|
|
1.1.1.4 root 1: /* YACC parser for C syntax and for Objective C. -*-c-*-
1.1 root 2: Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
1.1.1.4 root 20: /* This file defines the grammar of C and that of Objective C.
21: ifobjc ... end ifobjc conditionals contain code for Objective C only.
22: ifc ... end ifc conditionals contain code for C only.
1.1.1.5 ! root 23: Sed commands in Makefile.in are used to convert this file into
1.1.1.4 root 24: c-parse.y and into objc-parse.y. */
1.1 root 25:
26: /* To whomever it may concern: I have heard that such a thing was once
27: written by AT&T, but I have never seen it. */
28:
29: %expect 8
30:
31: /* These are the 8 conflicts you should get in parse.output;
32: the state numbers may vary if minor changes in the grammar are made.
33:
34: State 41 contains 1 shift/reduce conflict. (Two ways to recover from error.)
35: State 92 contains 1 shift/reduce conflict. (Two ways to recover from error.)
36: State 99 contains 1 shift/reduce conflict. (Two ways to recover from error.)
37: State 103 contains 1 shift/reduce conflict. (Two ways to recover from error.)
38: State 119 contains 1 shift/reduce conflict. (See comment at component_decl.)
39: State 183 contains 1 shift/reduce conflict. (Two ways to recover from error.)
40: State 193 contains 1 shift/reduce conflict. (Two ways to recover from error.)
41: State 199 contains 1 shift/reduce conflict. (Two ways to recover from error.)
42: */
43:
44: %{
45: #include <stdio.h>
46: #include <errno.h>
47: #include <setjmp.h>
48:
49: #include "config.h"
50: #include "tree.h"
51: #include "input.h"
52: #include "c-lex.h"
53: #include "c-tree.h"
54: #include "flags.h"
55:
56: #ifdef MULTIBYTE_CHARS
57: #include <stdlib.h>
58: #include <locale.h>
59: #endif
60:
1.1.1.4 root 61:
1.1.1.5 ! root 62: /* Since parsers are distinct for each language, put the language string
! 63: definition here. */
! 64: char *language_string = "GNU C";
! 65:
1.1 root 66: #ifndef errno
67: extern int errno;
68: #endif
69:
70: void yyerror ();
71:
72: /* Like YYERROR but do call yyerror. */
73: #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
74:
75: /* Cause the `yydebug' variable to be defined. */
76: #define YYDEBUG 1
77: %}
78:
79: %start program
80:
81: %union {long itype; tree ttype; enum tree_code code;
82: char *filename; int lineno; }
83:
84: /* All identifiers that are not reserved words
85: and are not declared typedefs in the current block */
86: %token IDENTIFIER
87:
88: /* All identifiers that are declared typedefs in the current block.
89: In some contexts, they are treated just like IDENTIFIER,
90: but they can also serve as typespecs in declarations. */
91: %token TYPENAME
92:
93: /* Reserved words that specify storage class.
94: yylval contains an IDENTIFIER_NODE which indicates which one. */
95: %token SCSPEC
96:
97: /* Reserved words that specify type.
98: yylval contains an IDENTIFIER_NODE which indicates which one. */
99: %token TYPESPEC
100:
101: /* Reserved words that qualify type: "const" or "volatile".
102: yylval contains an IDENTIFIER_NODE which indicates which one. */
103: %token TYPE_QUAL
104:
105: /* Character or numeric constants.
106: yylval is the node for the constant. */
107: %token CONSTANT
108:
109: /* String constants in raw form.
110: yylval is a STRING_CST node. */
111: %token STRING
112:
113: /* "...", used for functions with variable arglists. */
114: %token ELLIPSIS
115:
116: /* the reserved words */
1.1.1.2 root 117: /* SCO include files test "ASM", so use something else. */
1.1 root 118: %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
1.1.1.2 root 119: %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF ALIGN
1.1 root 120: %token ATTRIBUTE EXTENSION LABEL
1.1.1.5 ! root 121: %token REALPART IMAGPART
1.1 root 122:
123: /* Add precedence rules to solve dangling else s/r conflict */
124: %nonassoc IF
125: %nonassoc ELSE
126:
127: /* Define the operator tokens and their precedences.
128: The value is an integer because, if used, it is the tree code
129: to use in the expression made from the operator. */
130:
131: %right <code> ASSIGN '='
132: %right <code> '?' ':'
133: %left <code> OROR
134: %left <code> ANDAND
135: %left <code> '|'
136: %left <code> '^'
137: %left <code> '&'
138: %left <code> EQCOMPARE
139: %left <code> ARITHCOMPARE
140: %left <code> LSHIFT RSHIFT
141: %left <code> '+' '-'
142: %left <code> '*' '/' '%'
143: %right <code> UNARY PLUSPLUS MINUSMINUS
144: %left HYPERUNARY
145: %left <code> POINTSAT '.' '(' '['
146:
1.1.1.4 root 147: /* The Objective-C keywords. These are included in C and in
148: Objective C, so that the token codes are the same in both. */
1.1 root 149: %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
1.1.1.5 ! root 150: %token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
! 151:
! 152: /* Objective-C string constants in raw form.
! 153: yylval is an OBJC_STRING_CST node. */
! 154: %token OBJC_STRING
1.1 root 155:
156:
157: %type <code> unop
158:
159: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
160: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
161: %type <ttype> typed_declspecs reserved_declspecs
162: %type <ttype> typed_typespecs reserved_typespecquals
163: %type <ttype> declmods typespec typespecqual_reserved
164: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
165: %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
166: %type <ttype> init initlist maybeasm
167: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
168: %type <ttype> maybe_attribute attribute_list attrib
169:
170: %type <ttype> compstmt
171:
172: %type <ttype> declarator
173: %type <ttype> notype_declarator after_type_declarator
174: %type <ttype> parm_declarator
175:
176: %type <ttype> structsp component_decl_list component_decl_list2
177: %type <ttype> component_decl components component_declarator
178: %type <ttype> enumlist enumerator
179: %type <ttype> typename absdcl absdcl1 type_quals
180: %type <ttype> xexpr parms parm identifiers
181:
182: %type <ttype> parmlist parmlist_1 parmlist_2
183: %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
184: %type <ttype> identifiers_or_typenames
185:
186: %type <itype> setspecs
187:
188: %type <filename> save_filename
189: %type <lineno> save_lineno
190:
1.1.1.4 root 191:
1.1 root 192: %{
193: /* Number of statements (loosely speaking) seen so far. */
194: static int stmt_count;
195:
196: /* Input file and line number of the end of the body of last simple_if;
197: used by the stmt-rule immediately after simple_if returns. */
198: static char *if_stmt_file;
199: static int if_stmt_line;
200:
201: /* List of types and structure classes of the current declaration. */
202: static tree current_declspecs;
203:
204: /* Stack of saved values of current_declspecs. */
205: static tree declspec_stack;
206:
207: /* 1 if we explained undeclared var errors. */
208: static int undeclared_variable_notice;
209:
1.1.1.4 root 210:
1.1 root 211: /* Tell yyparse how to print a token's value, if yydebug is set. */
212:
213: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
214: extern void yyprint ();
215: %}
216:
217: %%
218: program: /* empty */
219: { if (pedantic)
1.1.1.4 root 220: pedwarn ("ANSI C forbids an empty source file");
221: }
1.1 root 222: | extdefs
1.1.1.4 root 223: {
1.1.1.5 ! root 224: /* In case there were missing closebraces,
! 225: get us back to the global binding level. */
! 226: while (! global_bindings_p ())
! 227: poplevel (0, 0, 0);
1.1.1.4 root 228: }
1.1 root 229: ;
230:
231: /* the reason for the strange actions in this rule
232: is so that notype_initdecls when reached via datadef
233: can find a valid list of type and sc specs in $0. */
234:
235: extdefs:
236: {$<ttype>$ = NULL_TREE; } extdef
237: | extdefs {$<ttype>$ = NULL_TREE; } extdef
238: ;
239:
240: extdef:
241: fndef
242: | datadef
1.1.1.2 root 243: | ASM_KEYWORD '(' expr ')' ';'
1.1 root 244: { STRIP_NOPS ($3);
245: if ((TREE_CODE ($3) == ADDR_EXPR
246: && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST)
247: || TREE_CODE ($3) == STRING_CST)
248: assemble_asm ($3);
249: else
250: error ("argument of `asm' is not a constant string"); }
251: ;
252:
253: datadef:
254: setspecs notype_initdecls ';'
255: { if (pedantic)
256: error ("ANSI C forbids data definition with no type or storage class");
257: else if (!flag_traditional)
258: warning ("data definition has no type or storage class"); }
259: | declmods setspecs notype_initdecls ';'
260: {}
261: | typed_declspecs setspecs initdecls ';'
262: {}
263: | declmods ';'
1.1.1.4 root 264: { pedwarn ("empty declaration"); }
1.1 root 265: | typed_declspecs ';'
266: { shadow_tag ($1); }
267: | error ';'
268: | error '}'
269: | ';'
270: { if (pedantic)
271: pedwarn ("ANSI C does not allow extra `;' outside of a function"); }
272: ;
273:
274: fndef:
275: typed_declspecs setspecs declarator
276: { if (! start_function ($1, $3, 0))
277: YYERROR1;
278: reinit_parse_for_function (); }
279: xdecls
280: { store_parm_decls (); }
281: compstmt_or_error
282: { finish_function (0); }
283: | typed_declspecs setspecs declarator error
284: { }
285: | declmods setspecs notype_declarator
286: { if (! start_function ($1, $3, 0))
287: YYERROR1;
288: reinit_parse_for_function (); }
289: xdecls
290: { store_parm_decls (); }
291: compstmt_or_error
292: { finish_function (0); }
293: | declmods setspecs notype_declarator error
294: { }
295: | setspecs notype_declarator
1.1.1.4 root 296: { if (! start_function (NULL_TREE, $2, 0))
1.1 root 297: YYERROR1;
298: reinit_parse_for_function (); }
299: xdecls
300: { store_parm_decls (); }
301: compstmt_or_error
302: { finish_function (0); }
303: | setspecs notype_declarator error
304: { }
305: ;
306:
307: identifier:
308: IDENTIFIER
309: | TYPENAME
310: ;
311:
312: unop: '&'
313: { $$ = ADDR_EXPR; }
314: | '-'
315: { $$ = NEGATE_EXPR; }
316: | '+'
317: { $$ = CONVERT_EXPR; }
318: | PLUSPLUS
319: { $$ = PREINCREMENT_EXPR; }
320: | MINUSMINUS
321: { $$ = PREDECREMENT_EXPR; }
322: | '~'
323: { $$ = BIT_NOT_EXPR; }
324: | '!'
325: { $$ = TRUTH_NOT_EXPR; }
326: ;
327:
328: expr: nonnull_exprlist
329: { $$ = build_compound_expr ($1); }
330: ;
331:
332: exprlist:
333: /* empty */
334: { $$ = NULL_TREE; }
335: | nonnull_exprlist
336: ;
337:
338: nonnull_exprlist:
339: expr_no_commas
340: { $$ = build_tree_list (NULL_TREE, $1); }
341: | nonnull_exprlist ',' expr_no_commas
342: { chainon ($1, build_tree_list (NULL_TREE, $3)); }
343: ;
344:
345: unary_expr:
346: primary
347: | '*' cast_expr %prec UNARY
348: { $$ = build_indirect_ref ($2, "unary *"); }
349: /* __extension__ turns off -pedantic for following primary. */
350: | EXTENSION
351: { $<itype>1 = pedantic;
352: pedantic = 0; }
353: cast_expr %prec UNARY
354: { $$ = $3;
355: pedantic = $<itype>1; }
356: | unop cast_expr %prec UNARY
1.1.1.5 ! root 357: { $$ = build_unary_op ($1, $2, 0);
! 358: overflow_warning ($$); }
1.1 root 359: /* Refer to the address of a label as a pointer. */
360: | ANDAND identifier
361: { tree label = lookup_label ($2);
1.1.1.5 ! root 362: if (label == 0)
! 363: $$ = null_pointer_node;
! 364: else
! 365: {
! 366: TREE_USED (label) = 1;
! 367: $$ = build1 (ADDR_EXPR, ptr_type_node, label);
! 368: TREE_CONSTANT ($$) = 1;
! 369: }
! 370: }
1.1 root 371: /* This seems to be impossible on some machines, so let's turn it off.
1.1.1.3 root 372: You can use __builtin_next_arg to find the anonymous stack args.
1.1 root 373: | '&' ELLIPSIS
374: { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
375: $$ = error_mark_node;
376: if (TREE_VALUE (tree_last (types)) == void_type_node)
377: error ("`&...' used in function with fixed number of arguments");
378: else
379: {
380: if (pedantic)
381: pedwarn ("ANSI C forbids `&...'");
382: $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
383: $$ = build_unary_op (ADDR_EXPR, $$, 0);
384: } }
385: */
386: | SIZEOF unary_expr %prec UNARY
387: { if (TREE_CODE ($2) == COMPONENT_REF
388: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
389: error ("`sizeof' applied to a bit-field");
390: $$ = c_sizeof (TREE_TYPE ($2)); }
391: | SIZEOF '(' typename ')' %prec HYPERUNARY
392: { $$ = c_sizeof (groktypename ($3)); }
393: | ALIGNOF unary_expr %prec UNARY
394: { $$ = c_alignof_expr ($2); }
395: | ALIGNOF '(' typename ')' %prec HYPERUNARY
396: { $$ = c_alignof (groktypename ($3)); }
1.1.1.5 ! root 397: | REALPART cast_expr %prec UNARY
! 398: { $$ = build_unary_op (REALPART_EXPR, $2, 0); }
! 399: | IMAGPART cast_expr %prec UNARY
! 400: { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); }
1.1 root 401: ;
402:
403: cast_expr:
404: unary_expr
405: | '(' typename ')' cast_expr %prec UNARY
406: { tree type = groktypename ($2);
407: $$ = build_c_cast (type, $4); }
408: | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY
409: { tree type = groktypename ($2);
410: char *name;
411: if (pedantic)
412: pedwarn ("ANSI C forbids constructor expressions");
413: if (TYPE_NAME (type) != 0)
414: {
415: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
416: name = IDENTIFIER_POINTER (TYPE_NAME (type));
417: else
418: name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
419: }
420: else
421: name = "";
422: $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)),
1.1.1.4 root 423: NULL_PTR, 0, 0, name);
1.1 root 424: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
425: {
426: int failure = complete_array_type (type, $$, 1);
427: if (failure)
428: abort ();
429: }
430: }
431: ;
432:
433: expr_no_commas:
434: cast_expr
435: | expr_no_commas '+' expr_no_commas
436: { $$ = parser_build_binary_op ($2, $1, $3); }
437: | expr_no_commas '-' expr_no_commas
438: { $$ = parser_build_binary_op ($2, $1, $3); }
439: | expr_no_commas '*' expr_no_commas
440: { $$ = parser_build_binary_op ($2, $1, $3); }
441: | expr_no_commas '/' expr_no_commas
442: { $$ = parser_build_binary_op ($2, $1, $3); }
443: | expr_no_commas '%' expr_no_commas
444: { $$ = parser_build_binary_op ($2, $1, $3); }
445: | expr_no_commas LSHIFT expr_no_commas
446: { $$ = parser_build_binary_op ($2, $1, $3); }
447: | expr_no_commas RSHIFT expr_no_commas
448: { $$ = parser_build_binary_op ($2, $1, $3); }
449: | expr_no_commas ARITHCOMPARE expr_no_commas
450: { $$ = parser_build_binary_op ($2, $1, $3); }
451: | expr_no_commas EQCOMPARE expr_no_commas
452: { $$ = parser_build_binary_op ($2, $1, $3); }
453: | expr_no_commas '&' expr_no_commas
454: { $$ = parser_build_binary_op ($2, $1, $3); }
455: | expr_no_commas '|' expr_no_commas
456: { $$ = parser_build_binary_op ($2, $1, $3); }
457: | expr_no_commas '^' expr_no_commas
458: { $$ = parser_build_binary_op ($2, $1, $3); }
459: | expr_no_commas ANDAND expr_no_commas
460: { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
461: | expr_no_commas OROR expr_no_commas
462: { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
463: | expr_no_commas '?' xexpr ':' expr_no_commas
464: { $$ = build_conditional_expr ($1, $3, $5); }
465: | expr_no_commas '=' expr_no_commas
1.1.1.4 root 466: { $$ = build_modify_expr ($1, NOP_EXPR, $3);
467: C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); }
1.1 root 468: | expr_no_commas ASSIGN expr_no_commas
1.1.1.4 root 469: { $$ = build_modify_expr ($1, $2, $3);
1.1.1.5 ! root 470: /* This inhibits warnings in truthvalue_conversion. */
! 471: C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
1.1 root 472: ;
473:
474: primary:
475: IDENTIFIER
476: {
477: tree context;
478:
479: $$ = lastiddecl;
480: if (!$$ || $$ == error_mark_node)
481: {
482: if (yychar == YYEMPTY)
483: yychar = YYLEX;
484: if (yychar == '(')
485: {
1.1.1.4 root 486: {
487: /* Ordinary implicit function declaration. */
488: $$ = implicitly_declare ($1);
489: assemble_external ($$);
490: TREE_USED ($$) = 1;
491: }
1.1 root 492: }
493: else if (current_function_decl == 0)
494: {
1.1.1.5 ! root 495: error ("`%s' undeclared here (not in a function)",
1.1 root 496: IDENTIFIER_POINTER ($1));
497: $$ = error_mark_node;
498: }
499: else
500: {
501: {
1.1.1.4 root 502: if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
503: || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
1.1 root 504: {
1.1.1.4 root 505: error ("`%s' undeclared (first use this function)",
506: IDENTIFIER_POINTER ($1));
507:
508: if (! undeclared_variable_notice)
509: {
510: error ("(Each undeclared identifier is reported only once");
511: error ("for each function it appears in.)");
512: undeclared_variable_notice = 1;
513: }
1.1 root 514: }
1.1.1.4 root 515: $$ = error_mark_node;
516: /* Prevent repeated error messages. */
517: IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
518: IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
1.1 root 519: }
520: }
521: }
522: else if (TREE_TYPE ($$) == error_mark_node)
523: $$ = error_mark_node;
1.1.1.4 root 524: else if (C_DECL_ANTICIPATED ($$))
525: {
526: /* The first time we see a build-in function used,
527: if it has not been declared. */
528: C_DECL_ANTICIPATED ($$) = 0;
529: if (yychar == YYEMPTY)
530: yychar = YYLEX;
531: if (yychar == '(')
532: {
533: /* Omit the implicit declaration we
534: would ordinarily do, so we don't lose
535: the actual built in type.
536: But print a diagnostic for the mismatch. */
537: if (TREE_CODE ($$) != FUNCTION_DECL)
538: error ("`%s' implicitly declared as function",
539: IDENTIFIER_POINTER (DECL_NAME ($$)));
540: else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$)))
541: != TYPE_MODE (integer_type_node))
542: && (TREE_TYPE (TREE_TYPE ($$))
543: != void_type_node))
544: pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
545: IDENTIFIER_POINTER (DECL_NAME ($$)));
546: /* If it really returns void, change that to int. */
547: if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node)
548: TREE_TYPE ($$)
549: = build_function_type (integer_type_node,
550: TYPE_ARG_TYPES (TREE_TYPE ($$)));
551: }
552: else
553: pedwarn ("built-in function `%s' used without declaration",
554: IDENTIFIER_POINTER (DECL_NAME ($$)));
555:
556: /* Do what we would ordinarily do when a fn is used. */
557: assemble_external ($$);
558: TREE_USED ($$) = 1;
559: }
1.1.1.2 root 560: else
1.1 root 561: {
1.1.1.2 root 562: assemble_external ($$);
1.1 root 563: TREE_USED ($$) = 1;
564: }
1.1.1.4 root 565:
1.1 root 566: if (TREE_CODE ($$) == CONST_DECL)
1.1.1.4 root 567: {
568: $$ = DECL_INITIAL ($$);
569: /* This is to prevent an enum whose value is 0
570: from being considered a null pointer constant. */
571: $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
572: TREE_CONSTANT ($$) = 1;
573: }
1.1 root 574: }
575: | CONSTANT
576: | string
577: { $$ = combine_strings ($1); }
578: | '(' expr ')'
579: { char class = TREE_CODE_CLASS (TREE_CODE ($2));
580: if (class == 'e' || class == '1'
581: || class == '2' || class == '<')
582: C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
583: $$ = $2; }
584: | '(' error ')'
585: { $$ = error_mark_node; }
586: | '('
587: { if (current_function_decl == 0)
588: {
589: error ("braced-group within expression allowed only inside a function");
590: YYERROR;
591: }
592: /* We must force a BLOCK for this level
593: so that, if it is not expanded later,
594: there is a way to turn off the entire subtree of blocks
595: that are contained in it. */
596: keep_next_level ();
1.1.1.5 ! root 597: push_iterator_stack ();
1.1 root 598: push_label_level ();
599: $<ttype>$ = expand_start_stmt_expr (); }
600: compstmt ')'
601: { tree rtl_exp;
602: if (pedantic)
603: pedwarn ("ANSI C forbids braced-groups within expressions");
1.1.1.5 ! root 604: pop_iterator_stack ();
1.1 root 605: pop_label_level ();
606: rtl_exp = expand_end_stmt_expr ($<ttype>2);
607: /* The statements have side effects, so the group does. */
608: TREE_SIDE_EFFECTS (rtl_exp) = 1;
609:
610: /* Make a BIND_EXPR for the BLOCK already made. */
611: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
612: NULL_TREE, rtl_exp, $3);
1.1.1.4 root 613: /* Remove the block from the tree at this point.
614: It gets put back at the proper place
615: when the BIND_EXPR is expanded. */
616: delete_block ($3);
1.1 root 617: }
618: | primary '(' exprlist ')' %prec '.'
619: { $$ = build_function_call ($1, $3); }
620: | primary '[' expr ']' %prec '.'
621: { $$ = build_array_ref ($1, $3); }
622: | primary '.' identifier
1.1.1.4 root 623: {
624: $$ = build_component_ref ($1, $3);
625: }
1.1 root 626: | primary POINTSAT identifier
1.1.1.4 root 627: {
628: tree expr = build_indirect_ref ($1, "->");
629:
630: $$ = build_component_ref (expr, $3);
631: }
1.1 root 632: | primary PLUSPLUS
633: { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
634: | primary MINUSMINUS
635: { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
636: ;
637:
638: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
639: string:
640: STRING
641: | string STRING
642: { $$ = chainon ($1, $2); }
643: ;
644:
1.1.1.5 ! root 645:
1.1 root 646: xdecls:
647: /* empty */
648: | datadecls
649: | datadecls ELLIPSIS
650: /* ... is used here to indicate a varargs function. */
651: { c_mark_varargs ();
652: if (pedantic)
653: pedwarn ("ANSI C does not permit use of `varargs.h'"); }
654: ;
655:
656: /* The following are analogous to lineno_decl, decls and decl
657: except that they do not allow nested functions.
658: They are used for old-style parm decls. */
659: lineno_datadecl:
660: save_filename save_lineno datadecl
661: { }
662: ;
663:
664: datadecls:
665: lineno_datadecl
666: | errstmt
667: | datadecls lineno_datadecl
668: | lineno_datadecl errstmt
669: ;
670:
671: datadecl:
672: typed_declspecs setspecs initdecls ';'
673: { current_declspecs = TREE_VALUE (declspec_stack);
674: declspec_stack = TREE_CHAIN (declspec_stack);
675: resume_momentary ($2); }
676: | declmods setspecs notype_initdecls ';'
677: { current_declspecs = TREE_VALUE (declspec_stack);
678: declspec_stack = TREE_CHAIN (declspec_stack);
679: resume_momentary ($2); }
680: | typed_declspecs ';'
1.1.1.4 root 681: { shadow_tag_warned ($1, 1);
682: pedwarn ("empty declaration"); }
1.1 root 683: | declmods ';'
684: { pedwarn ("empty declaration"); }
685: ;
686:
687: /* This combination which saves a lineno before a decl
688: is the normal thing to use, rather than decl itself.
689: This is to avoid shift/reduce conflicts in contexts
690: where statement labels are allowed. */
691: lineno_decl:
692: save_filename save_lineno decl
693: { }
694: ;
695:
696: decls:
697: lineno_decl
698: | errstmt
699: | decls lineno_decl
700: | lineno_decl errstmt
701: ;
702:
703: /* records the type and storage class specs to use for processing
704: the declarators that follow.
705: Maintains a stack of outer-level values of current_declspecs,
706: for the sake of parm declarations nested in function declarators. */
707: setspecs: /* empty */
708: { $$ = suspend_momentary ();
709: pending_xref_error ();
1.1.1.4 root 710: declspec_stack = tree_cons (NULL_TREE, current_declspecs,
1.1 root 711: declspec_stack);
712: current_declspecs = $<ttype>0; }
713: ;
714:
715: decl:
716: typed_declspecs setspecs initdecls ';'
717: { current_declspecs = TREE_VALUE (declspec_stack);
718: declspec_stack = TREE_CHAIN (declspec_stack);
719: resume_momentary ($2); }
720: | declmods setspecs notype_initdecls ';'
721: { current_declspecs = TREE_VALUE (declspec_stack);
722: declspec_stack = TREE_CHAIN (declspec_stack);
723: resume_momentary ($2); }
724: | typed_declspecs setspecs nested_function
725: { current_declspecs = TREE_VALUE (declspec_stack);
726: declspec_stack = TREE_CHAIN (declspec_stack);
727: resume_momentary ($2); }
728: | declmods setspecs notype_nested_function
729: { current_declspecs = TREE_VALUE (declspec_stack);
730: declspec_stack = TREE_CHAIN (declspec_stack);
731: resume_momentary ($2); }
732: | typed_declspecs ';'
733: { shadow_tag ($1); }
734: | declmods ';'
735: { pedwarn ("empty declaration"); }
736: ;
737:
738: /* Declspecs which contain at least one type specifier or typedef name.
739: (Just `const' or `volatile' is not enough.)
740: A typedef'd name following these is taken as a name to be declared. */
741:
742: typed_declspecs:
743: typespec reserved_declspecs
744: { $$ = tree_cons (NULL_TREE, $1, $2); }
745: | declmods typespec reserved_declspecs
746: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
747: ;
748:
749: reserved_declspecs: /* empty */
750: { $$ = NULL_TREE; }
751: | reserved_declspecs typespecqual_reserved
752: { $$ = tree_cons (NULL_TREE, $2, $1); }
753: | reserved_declspecs SCSPEC
1.1.1.4 root 754: { if (extra_warnings)
755: warning ("`%s' is not at beginning of declaration",
756: IDENTIFIER_POINTER ($2));
757: $$ = tree_cons (NULL_TREE, $2, $1); }
1.1 root 758: ;
759:
760: /* List of just storage classes and type modifiers.
761: A declaration can start with just this, but then it cannot be used
762: to redeclare a typedef-name. */
763:
764: declmods:
765: TYPE_QUAL
1.1.1.4 root 766: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
767: TREE_STATIC ($$) = 1; }
1.1 root 768: | SCSPEC
769: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
770: | declmods TYPE_QUAL
1.1.1.4 root 771: { $$ = tree_cons (NULL_TREE, $2, $1);
772: TREE_STATIC ($$) = 1; }
1.1 root 773: | declmods SCSPEC
1.1.1.4 root 774: { if (extra_warnings && TREE_STATIC ($1))
775: warning ("`%s' is not at beginning of declaration",
776: IDENTIFIER_POINTER ($2));
777: $$ = tree_cons (NULL_TREE, $2, $1);
778: TREE_STATIC ($$) = TREE_STATIC ($1); }
1.1 root 779: ;
780:
781:
782: /* Used instead of declspecs where storage classes are not allowed
783: (that is, for typenames and structure components).
784: Don't accept a typedef-name if anything but a modifier precedes it. */
785:
786: typed_typespecs:
787: typespec reserved_typespecquals
788: { $$ = tree_cons (NULL_TREE, $1, $2); }
789: | nonempty_type_quals typespec reserved_typespecquals
790: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
791: ;
792:
793: reserved_typespecquals: /* empty */
794: { $$ = NULL_TREE; }
795: | reserved_typespecquals typespecqual_reserved
796: { $$ = tree_cons (NULL_TREE, $2, $1); }
797: ;
798:
799: /* A typespec (but not a type qualifier).
800: Once we have seen one of these in a declaration,
801: if a typedef name appears then it is being redeclared. */
802:
803: typespec: TYPESPEC
804: | structsp
805: | TYPENAME
806: { /* For a typedef name, record the meaning, not the name.
807: In case of `foo foo, bar;'. */
808: $$ = lookup_name ($1); }
809: | TYPEOF '(' expr ')'
1.1.1.4 root 810: { $$ = TREE_TYPE ($3); }
1.1 root 811: | TYPEOF '(' typename ')'
1.1.1.4 root 812: { $$ = groktypename ($3); }
1.1 root 813: ;
814:
815: /* A typespec that is a reserved word, or a type qualifier. */
816:
817: typespecqual_reserved: TYPESPEC
818: | TYPE_QUAL
819: | structsp
820: ;
821:
822: initdecls:
823: initdcl
824: | initdecls ',' initdcl
825: ;
826:
827: notype_initdecls:
828: notype_initdcl
829: | notype_initdecls ',' initdcl
830: ;
831:
832: maybeasm:
833: /* empty */
834: { $$ = NULL_TREE; }
1.1.1.2 root 835: | ASM_KEYWORD '(' string ')'
1.1 root 836: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
837: $$ = $3;
838: }
839: ;
840:
841: initdcl:
842: declarator maybeasm maybe_attribute '='
843: { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
844: init
845: /* Note how the declaration of the variable is in effect while its init is parsed! */
846: { decl_attributes ($<ttype>5, $3);
847: finish_decl ($<ttype>5, $6, $2); }
848: | declarator maybeasm maybe_attribute
849: { tree d = start_decl ($1, current_declspecs, 0);
850: decl_attributes (d, $3);
851: finish_decl (d, NULL_TREE, $2); }
852: ;
853:
854: notype_initdcl:
855: notype_declarator maybeasm maybe_attribute '='
856: { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
857: init
858: /* Note how the declaration of the variable is in effect while its init is parsed! */
859: { decl_attributes ($<ttype>5, $3);
860: finish_decl ($<ttype>5, $6, $2); }
861: | notype_declarator maybeasm maybe_attribute
862: { tree d = start_decl ($1, current_declspecs, 0);
863: decl_attributes (d, $3);
864: finish_decl (d, NULL_TREE, $2); }
865: ;
866: /* the * rules are dummies to accept the Apollo extended syntax
867: so that the header files compile. */
868: maybe_attribute:
869: /* empty */
870: { $$ = NULL_TREE; }
871: | ATTRIBUTE '(' '(' attribute_list ')' ')'
872: { $$ = $4; }
873: ;
874:
875: attribute_list
876: : attrib
877: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
878: | attribute_list ',' attrib
879: { $$ = tree_cons (NULL_TREE, $3, $1); }
880: ;
881:
882: attrib
883: : IDENTIFIER
884: { if (strcmp (IDENTIFIER_POINTER ($1), "packed"))
885: warning ("`%s' attribute directive ignored",
886: IDENTIFIER_POINTER ($1));
887: $$ = $1; }
1.1.1.3 root 888: | IDENTIFIER '(' IDENTIFIER ')'
889: { /* If not "mode (m)", then issue warning. */
890: if (strcmp (IDENTIFIER_POINTER ($1), "mode") != 0)
891: {
892: warning ("`%s' attribute directive ignored",
893: IDENTIFIER_POINTER ($1));
894: $$ = $1;
895: }
896: else
1.1.1.4 root 897: $$ = tree_cons ($1, $3, NULL_TREE); }
1.1 root 898: | IDENTIFIER '(' CONSTANT ')'
899: { /* if not "aligned(n)", then issue warning */
900: if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
901: || TREE_CODE ($3) != INTEGER_CST)
902: {
903: warning ("`%s' attribute directive ignored",
904: IDENTIFIER_POINTER ($1));
905: $$ = $1;
906: }
907: else
1.1.1.4 root 908: $$ = tree_cons ($1, $3, NULL_TREE); }
1.1 root 909: | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'
910: { /* if not "format(...)", then issue warning */
911: if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0
912: || TREE_CODE ($5) != INTEGER_CST
913: || TREE_CODE ($7) != INTEGER_CST)
914: {
915: warning ("`%s' attribute directive ignored",
916: IDENTIFIER_POINTER ($1));
917: $$ = $1;
918: }
919: else
1.1.1.4 root 920: $$ = tree_cons ($1,
921: tree_cons ($3,
922: tree_cons ($5, $7, NULL_TREE),
923: NULL_TREE),
924: NULL_TREE); }
1.1 root 925: ;
926:
927: init:
928: expr_no_commas
929: | '{' '}'
930: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
931: if (pedantic)
932: pedwarn ("ANSI C forbids empty initializer braces"); }
933: | '{' initlist '}'
934: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
935: | '{' initlist ',' '}'
936: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
937: | error
938: { $$ = NULL_TREE; }
939: ;
940:
941: /* This chain is built in reverse order,
942: and put in forward order where initlist is used. */
943: initlist:
944: init
945: { $$ = build_tree_list (NULL_TREE, $1); }
946: | initlist ',' init
947: { $$ = tree_cons (NULL_TREE, $3, $1); }
1.1.1.5 ! root 948: /* These are for labeled elements. The syntax for an array element
! 949: initializer conflicts with the syntax for an Objective-C message,
! 950: so don't include these productions in the Objective-C grammer. */
1.1.1.4 root 951: | '[' expr_no_commas ELLIPSIS expr_no_commas ']' init
952: { $$ = build_tree_list (tree_cons ($2, NULL_TREE,
953: build_tree_list ($4, NULL_TREE)),
954: $6); }
955: | initlist ',' '[' expr_no_commas ELLIPSIS expr_no_commas ']' init
956: { $$ = tree_cons (tree_cons ($4, NULL_TREE,
957: build_tree_list ($6, NULL_TREE)),
958: $8,
959: $1); }
1.1 root 960: | '[' expr_no_commas ']' init
961: { $$ = build_tree_list ($2, $4); }
962: | initlist ',' '[' expr_no_commas ']' init
963: { $$ = tree_cons ($4, $6, $1); }
964: | identifier ':' init
965: { $$ = build_tree_list ($1, $3); }
966: | initlist ',' identifier ':' init
967: { $$ = tree_cons ($3, $5, $1); }
968: ;
969:
970: nested_function:
971: declarator
972: { push_c_function_context ();
973: if (! start_function (current_declspecs, $1, 1))
974: {
975: pop_c_function_context ();
976: YYERROR1;
977: }
978: reinit_parse_for_function ();
979: store_parm_decls (); }
980: /* This used to use compstmt_or_error.
981: That caused a bug with input `f(g) int g {}',
982: where the use of YYERROR1 above caused an error
983: which then was handled by compstmt_or_error.
984: There followed a repeated execution of that same rule,
985: which called YYERROR1 again, and so on. */
986: compstmt
987: { finish_function (1);
988: pop_c_function_context (); }
989: ;
990:
991: notype_nested_function:
992: notype_declarator
993: { push_c_function_context ();
994: if (! start_function (current_declspecs, $1, 1))
995: {
996: pop_c_function_context ();
997: YYERROR1;
998: }
999: reinit_parse_for_function ();
1000: store_parm_decls (); }
1001: /* This used to use compstmt_or_error.
1002: That caused a bug with input `f(g) int g {}',
1003: where the use of YYERROR1 above caused an error
1004: which then was handled by compstmt_or_error.
1005: There followed a repeated execution of that same rule,
1006: which called YYERROR1 again, and so on. */
1007: compstmt
1008: { finish_function (1);
1009: pop_c_function_context (); }
1010: ;
1011:
1012: /* Any kind of declarator (thus, all declarators allowed
1013: after an explicit typespec). */
1014:
1015: declarator:
1016: after_type_declarator
1017: | notype_declarator
1018: ;
1019:
1020: /* A declarator that is allowed only after an explicit typespec. */
1021:
1022: after_type_declarator:
1023: '(' after_type_declarator ')'
1024: { $$ = $2; }
1025: | after_type_declarator '(' parmlist_or_identifiers %prec '.'
1026: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1027: /* | after_type_declarator '(' error ')' %prec '.'
1028: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
1029: poplevel (0, 0, 0); } */
1030: | after_type_declarator '[' expr ']' %prec '.'
1031: { $$ = build_nt (ARRAY_REF, $1, $3); }
1032: | after_type_declarator '[' ']' %prec '.'
1033: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1034: | '*' type_quals after_type_declarator %prec UNARY
1035: { $$ = make_pointer_declarator ($2, $3); }
1036: | TYPENAME
1037: ;
1038:
1039: /* Kinds of declarator that can appear in a parameter list
1040: in addition to notype_declarator. This is like after_type_declarator
1041: but does not allow a typedef name in parentheses as an identifier
1042: (because it would conflict with a function with that typedef as arg). */
1043:
1044: parm_declarator:
1045: parm_declarator '(' parmlist_or_identifiers %prec '.'
1046: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1047: /* | parm_declarator '(' error ')' %prec '.'
1048: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
1049: poplevel (0, 0, 0); } */
1050: | parm_declarator '[' expr ']' %prec '.'
1051: { $$ = build_nt (ARRAY_REF, $1, $3); }
1052: | parm_declarator '[' ']' %prec '.'
1053: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1054: | '*' type_quals parm_declarator %prec UNARY
1055: { $$ = make_pointer_declarator ($2, $3); }
1056: | TYPENAME
1057: ;
1058:
1059: /* A declarator allowed whether or not there has been
1060: an explicit typespec. These cannot redeclare a typedef-name. */
1061:
1062: notype_declarator:
1063: notype_declarator '(' parmlist_or_identifiers %prec '.'
1064: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1065: /* | notype_declarator '(' error ')' %prec '.'
1066: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
1067: poplevel (0, 0, 0); } */
1068: | '(' notype_declarator ')'
1069: { $$ = $2; }
1070: | '*' type_quals notype_declarator %prec UNARY
1071: { $$ = make_pointer_declarator ($2, $3); }
1072: | notype_declarator '[' expr ']' %prec '.'
1073: { $$ = build_nt (ARRAY_REF, $1, $3); }
1074: | notype_declarator '[' ']' %prec '.'
1075: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1076: | IDENTIFIER
1077: ;
1078:
1079: structsp:
1080: STRUCT identifier '{'
1081: { $$ = start_struct (RECORD_TYPE, $2);
1082: /* Start scope of tag before parsing components. */
1083: }
1084: component_decl_list '}'
1085: { $$ = finish_struct ($<ttype>4, $5);
1086: /* Really define the structure. */
1087: }
1088: | STRUCT '{' component_decl_list '}'
1089: { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
1090: $3); }
1091: | STRUCT identifier
1092: { $$ = xref_tag (RECORD_TYPE, $2); }
1093: | UNION identifier '{'
1094: { $$ = start_struct (UNION_TYPE, $2); }
1095: component_decl_list '}'
1096: { $$ = finish_struct ($<ttype>4, $5); }
1097: | UNION '{' component_decl_list '}'
1098: { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
1099: $3); }
1100: | UNION identifier
1101: { $$ = xref_tag (UNION_TYPE, $2); }
1102: | ENUM identifier '{'
1103: { $<itype>3 = suspend_momentary ();
1104: $$ = start_enum ($2); }
1105: enumlist maybecomma_warn '}'
1106: { $$ = finish_enum ($<ttype>4, nreverse ($5));
1107: resume_momentary ($<itype>3); }
1108: | ENUM '{'
1109: { $<itype>2 = suspend_momentary ();
1110: $$ = start_enum (NULL_TREE); }
1111: enumlist maybecomma_warn '}'
1112: { $$ = finish_enum ($<ttype>3, nreverse ($4));
1113: resume_momentary ($<itype>2); }
1114: | ENUM identifier
1115: { $$ = xref_tag (ENUMERAL_TYPE, $2); }
1116: ;
1117:
1118: maybecomma:
1119: /* empty */
1120: | ','
1121: ;
1122:
1123: maybecomma_warn:
1124: /* empty */
1125: | ','
1126: { if (pedantic) pedwarn ("comma at end of enumerator list"); }
1127: ;
1128:
1129: component_decl_list:
1130: component_decl_list2
1131: { $$ = $1; }
1132: | component_decl_list2 component_decl
1133: { $$ = chainon ($1, $2);
1.1.1.4 root 1134: pedwarn ("no semicolon at end of struct or union"); }
1.1 root 1135: ;
1136:
1137: component_decl_list2: /* empty */
1138: { $$ = NULL_TREE; }
1139: | component_decl_list2 component_decl ';'
1140: { $$ = chainon ($1, $2); }
1141: | component_decl_list2 ';'
1142: { if (pedantic)
1143: pedwarn ("extra semicolon in struct or union specified"); }
1144: ;
1145:
1146: /* There is a shift-reduce conflict here, because `components' may
1147: start with a `typename'. It happens that shifting (the default resolution)
1148: does the right thing, because it treats the `typename' as part of
1149: a `typed_typespecs'.
1150:
1151: It is possible that this same technique would allow the distinction
1152: between `notype_initdecls' and `initdecls' to be eliminated.
1153: But I am being cautious and not trying it. */
1154:
1155: component_decl:
1156: typed_typespecs setspecs components
1157: { $$ = $3;
1158: current_declspecs = TREE_VALUE (declspec_stack);
1159: declspec_stack = TREE_CHAIN (declspec_stack);
1160: resume_momentary ($2); }
1161: | typed_typespecs
1162: { if (pedantic)
1163: pedwarn ("ANSI C forbids member declarations with no members");
1164: shadow_tag($1);
1165: $$ = NULL_TREE; }
1166: | nonempty_type_quals setspecs components
1167: { $$ = $3;
1168: current_declspecs = TREE_VALUE (declspec_stack);
1169: declspec_stack = TREE_CHAIN (declspec_stack);
1170: resume_momentary ($2); }
1171: | nonempty_type_quals
1172: { if (pedantic)
1173: pedwarn ("ANSI C forbids member declarations with no members");
1174: shadow_tag($1);
1175: $$ = NULL_TREE; }
1176: | error
1177: { $$ = NULL_TREE; }
1178: ;
1179:
1180: components:
1181: component_declarator
1182: | components ',' component_declarator
1183: { $$ = chainon ($1, $3); }
1184: ;
1185:
1186: component_declarator:
1187: save_filename save_lineno declarator maybe_attribute
1188: { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
1189: decl_attributes ($$, $4); }
1190: | save_filename save_lineno
1191: declarator ':' expr_no_commas maybe_attribute
1192: { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
1193: decl_attributes ($$, $6); }
1.1.1.5 ! root 1194: | save_filename save_lineno ':' expr_no_commas maybe_attribute
! 1195: { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
! 1196: decl_attributes ($$, $5); }
1.1 root 1197: ;
1198:
1199: /* We chain the enumerators in reverse order.
1200: They are put in forward order where enumlist is used.
1201: (The order used to be significant, but no longer is so.
1202: However, we still maintain the order, just to be clean.) */
1203:
1204: enumlist:
1205: enumerator
1206: | enumlist ',' enumerator
1207: { $$ = chainon ($3, $1); }
1208: ;
1209:
1210:
1211: enumerator:
1212: identifier
1213: { $$ = build_enumerator ($1, NULL_TREE); }
1214: | identifier '=' expr_no_commas
1215: { $$ = build_enumerator ($1, $3); }
1216: ;
1217:
1218: typename:
1219: typed_typespecs absdcl
1220: { $$ = build_tree_list ($1, $2); }
1221: | nonempty_type_quals absdcl
1222: { $$ = build_tree_list ($1, $2); }
1223: ;
1224:
1225: absdcl: /* an absolute declarator */
1226: /* empty */
1227: { $$ = NULL_TREE; }
1228: | absdcl1
1229: ;
1230:
1231: nonempty_type_quals:
1232: TYPE_QUAL
1233: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
1234: | nonempty_type_quals TYPE_QUAL
1235: { $$ = tree_cons (NULL_TREE, $2, $1); }
1236: ;
1237:
1238: type_quals:
1239: /* empty */
1240: { $$ = NULL_TREE; }
1241: | type_quals TYPE_QUAL
1242: { $$ = tree_cons (NULL_TREE, $2, $1); }
1243: ;
1244:
1245: absdcl1: /* a nonempty absolute declarator */
1246: '(' absdcl1 ')'
1247: { $$ = $2; }
1248: /* `(typedef)1' is `int'. */
1249: | '*' type_quals absdcl1 %prec UNARY
1250: { $$ = make_pointer_declarator ($2, $3); }
1251: | '*' type_quals %prec UNARY
1252: { $$ = make_pointer_declarator ($2, NULL_TREE); }
1253: | absdcl1 '(' parmlist %prec '.'
1254: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1255: | absdcl1 '[' expr ']' %prec '.'
1256: { $$ = build_nt (ARRAY_REF, $1, $3); }
1257: | absdcl1 '[' ']' %prec '.'
1258: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1259: | '(' parmlist %prec '.'
1260: { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
1261: | '[' expr ']' %prec '.'
1262: { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
1263: | '[' ']' %prec '.'
1264: { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
1265: ;
1266:
1267: /* at least one statement, the first of which parses without error. */
1268: /* stmts is used only after decls, so an invalid first statement
1269: is actually regarded as an invalid decl and part of the decls. */
1270:
1271: stmts:
1272: lineno_stmt_or_label
1273: | stmts lineno_stmt_or_label
1274: | stmts errstmt
1275: ;
1276:
1277: xstmts:
1278: /* empty */
1279: | stmts
1280: ;
1281:
1282: errstmt: error ';'
1283: ;
1284:
1285: pushlevel: /* empty */
1286: { emit_line_note (input_filename, lineno);
1287: pushlevel (0);
1288: clear_last_expr ();
1289: push_momentary ();
1.1.1.4 root 1290: expand_start_bindings (0);
1291: }
1.1 root 1292: ;
1293:
1294: /* Read zero or more forward-declarations for labels
1295: that nested functions can jump to. */
1296: maybe_label_decls:
1297: /* empty */
1298: | label_decls
1299: { if (pedantic)
1300: pedwarn ("ANSI C forbids label declarations"); }
1301: ;
1302:
1303: label_decls:
1304: label_decl
1305: | label_decls label_decl
1306: ;
1307:
1308: label_decl:
1309: LABEL identifiers_or_typenames ';'
1310: { tree link;
1311: for (link = $2; link; link = TREE_CHAIN (link))
1312: {
1313: tree label = shadow_label (TREE_VALUE (link));
1314: C_DECLARED_LABEL_FLAG (label) = 1;
1315: declare_nonlocal_label (label);
1316: }
1317: }
1318: ;
1319:
1320: /* This is the body of a function definition.
1321: It causes syntax errors to ignore to the next openbrace. */
1322: compstmt_or_error:
1323: compstmt
1324: {}
1325: | error compstmt
1326: ;
1327:
1328: compstmt: '{' '}'
1329: { $$ = convert (void_type_node, integer_zero_node); }
1330: | '{' pushlevel maybe_label_decls decls xstmts '}'
1331: { emit_line_note (input_filename, lineno);
1332: expand_end_bindings (getdecls (), 1, 0);
1333: $$ = poplevel (1, 1, 0);
1334: pop_momentary (); }
1335: | '{' pushlevel maybe_label_decls error '}'
1336: { emit_line_note (input_filename, lineno);
1337: expand_end_bindings (getdecls (), kept_level_p (), 0);
1338: $$ = poplevel (kept_level_p (), 0, 0);
1339: pop_momentary (); }
1340: | '{' pushlevel maybe_label_decls stmts '}'
1341: { emit_line_note (input_filename, lineno);
1342: expand_end_bindings (getdecls (), kept_level_p (), 0);
1343: $$ = poplevel (kept_level_p (), 0, 0);
1344: pop_momentary (); }
1345: ;
1346:
1347: /* Value is number of statements counted as of the closeparen. */
1348: simple_if:
1349: if_prefix lineno_labeled_stmt
1350: /* Make sure expand_end_cond is run once
1351: for each call to expand_start_cond.
1352: Otherwise a crash is likely. */
1353: | if_prefix error
1354: ;
1355:
1356: if_prefix:
1357: IF '(' expr ')'
1358: { emit_line_note ($<filename>-1, $<lineno>0);
1359: expand_start_cond (truthvalue_conversion ($3), 0);
1360: $<itype>1 = stmt_count;
1361: if_stmt_file = $<filename>-1;
1362: if_stmt_line = $<lineno>0;
1363: position_after_white_space (); }
1364: ;
1365:
1.1.1.3 root 1366: /* This is a subroutine of stmt.
1367: It is used twice, once for valid DO statements
1368: and once for catching errors in parsing the end test. */
1369: do_stmt_start:
1370: DO
1371: { stmt_count++;
1372: emit_line_note ($<filename>-1, $<lineno>0);
1373: /* See comment in `while' alternative, above. */
1374: emit_nop ();
1375: expand_start_loop_continue_elsewhere (1);
1376: position_after_white_space (); }
1377: lineno_labeled_stmt WHILE
1378: { expand_loop_continue_here (); }
1379: ;
1380:
1.1 root 1381: save_filename:
1382: { $$ = input_filename; }
1383: ;
1384:
1385: save_lineno:
1386: { $$ = lineno; }
1387: ;
1388:
1389: lineno_labeled_stmt:
1390: save_filename save_lineno stmt
1391: { }
1392: /* | save_filename save_lineno error
1393: { }
1394: */
1395: | save_filename save_lineno label lineno_labeled_stmt
1396: { }
1397: ;
1398:
1399: lineno_stmt_or_label:
1400: save_filename save_lineno stmt_or_label
1401: { }
1402: ;
1403:
1404: stmt_or_label:
1405: stmt
1406: | label
1407: { int next;
1408: position_after_white_space ();
1409: next = getc (finput);
1410: ungetc (next, finput);
1411: if (pedantic && next == '}')
1412: pedwarn ("ANSI C forbids label at end of compound statement");
1413: }
1414: ;
1415:
1416: /* Parse a single real statement, not including any labels. */
1417: stmt:
1418: compstmt
1419: { stmt_count++; }
1.1.1.5 ! root 1420: | all_iter_stmt
1.1 root 1421: | expr ';'
1422: { stmt_count++;
1423: emit_line_note ($<filename>-1, $<lineno>0);
1.1.1.5 ! root 1424: iterator_expand ($1);
1.1 root 1425: clear_momentary (); }
1426: | simple_if ELSE
1427: { expand_start_else ();
1428: $<itype>1 = stmt_count;
1429: position_after_white_space (); }
1430: lineno_labeled_stmt
1431: { expand_end_cond ();
1432: if (extra_warnings && stmt_count == $<itype>1)
1433: warning ("empty body in an else-statement"); }
1434: | simple_if %prec IF
1435: { expand_end_cond ();
1436: if (extra_warnings && stmt_count == $<itype>1)
1437: warning_with_file_and_line (if_stmt_file, if_stmt_line,
1438: "empty body in an if-statement"); }
1439: /* Make sure expand_end_cond is run once
1440: for each call to expand_start_cond.
1441: Otherwise a crash is likely. */
1442: | simple_if ELSE error
1443: { expand_end_cond (); }
1444: | WHILE
1445: { stmt_count++;
1446: emit_line_note ($<filename>-1, $<lineno>0);
1447: /* The emit_nop used to come before emit_line_note,
1448: but that made the nop seem like part of the preceding line.
1449: And that was confusing when the preceding line was
1450: inside of an if statement and was not really executed.
1451: I think it ought to work to put the nop after the line number.
1452: We will see. --rms, July 15, 1991. */
1.1.1.3 root 1453: emit_nop (); }
1.1 root 1454: '(' expr ')'
1.1.1.3 root 1455: { /* Don't start the loop till we have succeeded
1456: in parsing the end test. This is to make sure
1457: that we end every loop we start. */
1458: expand_start_loop (1);
1459: emit_line_note (input_filename, lineno);
1.1.1.4 root 1460: expand_exit_loop_if_false (NULL_PTR,
1461: truthvalue_conversion ($4));
1.1 root 1462: position_after_white_space (); }
1463: lineno_labeled_stmt
1464: { expand_end_loop (); }
1.1.1.3 root 1465: | do_stmt_start
1.1 root 1466: '(' expr ')' ';'
1467: { emit_line_note (input_filename, lineno);
1.1.1.4 root 1468: expand_exit_loop_if_false (NULL_PTR,
1469: truthvalue_conversion ($3));
1.1 root 1470: expand_end_loop ();
1471: clear_momentary (); }
1.1.1.3 root 1472: /* This rule is needed to make sure we end every loop we start. */
1473: | do_stmt_start error
1474: { expand_end_loop ();
1475: clear_momentary (); }
1.1 root 1476: | FOR
1477: '(' xexpr ';'
1478: { stmt_count++;
1479: emit_line_note ($<filename>-1, $<lineno>0);
1480: /* See comment in `while' alternative, above. */
1481: emit_nop ();
1482: if ($3) c_expand_expr_stmt ($3);
1.1.1.3 root 1483: /* Next step is to call expand_start_loop_continue_elsewhere,
1484: but wait till after we parse the entire for (...).
1485: Otherwise, invalid input might cause us to call that
1486: fn without calling expand_end_loop. */
1487: }
1.1 root 1488: xexpr ';'
1.1.1.3 root 1489: /* Can't emit now; wait till after expand_start_loop... */
1490: { $<lineno>7 = lineno;
1491: $<filename>$ = input_filename; }
1.1 root 1492: xexpr ')'
1.1.1.3 root 1493: {
1494: /* Start the loop. Doing this after parsing
1495: all the expressions ensures we will end the loop. */
1496: expand_start_loop_continue_elsewhere (1);
1497: /* Emit the end-test, with a line number. */
1498: emit_line_note ($<filename>8, $<lineno>7);
1499: if ($6)
1.1.1.4 root 1500: expand_exit_loop_if_false (NULL_PTR,
1501: truthvalue_conversion ($6));
1.1.1.3 root 1502: /* Don't let the tree nodes for $9 be discarded by
1503: clear_momentary during the parsing of the next stmt. */
1504: push_momentary ();
1.1.1.4 root 1505: $<lineno>7 = lineno;
1.1.1.5 ! root 1506: $<filename>8 = input_filename;
! 1507: position_after_white_space (); }
1.1 root 1508: lineno_labeled_stmt
1.1.1.4 root 1509: { /* Emit the increment expression, with a line number. */
1510: emit_line_note ($<filename>8, $<lineno>7);
1.1 root 1511: expand_loop_continue_here ();
1512: if ($9)
1513: c_expand_expr_stmt ($9);
1514: pop_momentary ();
1515: expand_end_loop (); }
1516: | SWITCH '(' expr ')'
1517: { stmt_count++;
1518: emit_line_note ($<filename>-1, $<lineno>0);
1519: c_expand_start_case ($3);
1520: /* Don't let the tree nodes for $3 be discarded by
1521: clear_momentary during the parsing of the next stmt. */
1522: push_momentary ();
1523: position_after_white_space (); }
1524: lineno_labeled_stmt
1525: { expand_end_case ($3);
1526: pop_momentary (); }
1527: | BREAK ';'
1528: { stmt_count++;
1529: emit_line_note ($<filename>-1, $<lineno>0);
1530: if ( ! expand_exit_something ())
1531: error ("break statement not within loop or switch"); }
1532: | CONTINUE ';'
1533: { stmt_count++;
1534: emit_line_note ($<filename>-1, $<lineno>0);
1.1.1.4 root 1535: if (! expand_continue_loop (NULL_PTR))
1.1 root 1536: error ("continue statement not within a loop"); }
1537: | RETURN ';'
1538: { stmt_count++;
1539: emit_line_note ($<filename>-1, $<lineno>0);
1540: c_expand_return (NULL_TREE); }
1541: | RETURN expr ';'
1542: { stmt_count++;
1543: emit_line_note ($<filename>-1, $<lineno>0);
1544: c_expand_return ($2); }
1.1.1.2 root 1545: | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
1.1 root 1546: { stmt_count++;
1547: emit_line_note ($<filename>-1, $<lineno>0);
1548: STRIP_NOPS ($4);
1549: if ((TREE_CODE ($4) == ADDR_EXPR
1550: && TREE_CODE (TREE_OPERAND ($4, 0)) == STRING_CST)
1551: || TREE_CODE ($4) == STRING_CST)
1552: expand_asm ($4);
1553: else
1554: error ("argument of `asm' is not a constant string"); }
1555: /* This is the case with just output operands. */
1.1.1.2 root 1556: | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
1.1 root 1557: { stmt_count++;
1558: emit_line_note ($<filename>-1, $<lineno>0);
1559: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
1560: $2 == ridpointers[(int)RID_VOLATILE],
1561: input_filename, lineno); }
1562: /* This is the case with input operands as well. */
1.1.1.2 root 1563: | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' asm_operands ')' ';'
1.1 root 1564: { stmt_count++;
1565: emit_line_note ($<filename>-1, $<lineno>0);
1566: c_expand_asm_operands ($4, $6, $8, NULL_TREE,
1567: $2 == ridpointers[(int)RID_VOLATILE],
1568: input_filename, lineno); }
1569: /* This is the case with clobbered registers as well. */
1.1.1.2 root 1570: | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
1.1 root 1571: asm_operands ':' asm_clobbers ')' ';'
1572: { stmt_count++;
1573: emit_line_note ($<filename>-1, $<lineno>0);
1574: c_expand_asm_operands ($4, $6, $8, $10,
1575: $2 == ridpointers[(int)RID_VOLATILE],
1576: input_filename, lineno); }
1577: | GOTO identifier ';'
1578: { tree decl;
1579: stmt_count++;
1580: emit_line_note ($<filename>-1, $<lineno>0);
1581: decl = lookup_label ($2);
1582: if (decl != 0)
1583: {
1584: TREE_USED (decl) = 1;
1585: expand_goto (decl);
1586: }
1587: }
1588: | GOTO '*' expr ';'
1589: { stmt_count++;
1590: emit_line_note ($<filename>-1, $<lineno>0);
1.1.1.4 root 1591: expand_computed_goto (convert (ptr_type_node, $3)); }
1.1 root 1592: | ';'
1593: ;
1594:
1.1.1.5 ! root 1595: all_iter_stmt:
! 1596: all_iter_stmt_simple
! 1597: /* | all_iter_stmt_with_decl */
! 1598: ;
! 1599:
! 1600: all_iter_stmt_simple:
! 1601: FOR '(' primary ')'
! 1602: {
! 1603: /* The value returned by this action is */
! 1604: /* 1 if everything is OK */
! 1605: /* 0 in case of error or already bound iterator */
! 1606:
! 1607: $<itype>$ = 0;
! 1608: if (TREE_CODE ($3) != VAR_DECL)
! 1609: error ("invalid `for (ITERATOR)' syntax");
! 1610: if (! ITERATOR_P ($3))
! 1611: error ("`%s' is not an iterator",
! 1612: IDENTIFIER_POINTER (DECL_NAME ($3)));
! 1613: else if (ITERATOR_BOUND_P ($3))
! 1614: error ("`for (%s)' inside expansion of same iterator",
! 1615: IDENTIFIER_POINTER (DECL_NAME ($3)));
! 1616: else
! 1617: {
! 1618: $<itype>$ = 1;
! 1619: iterator_for_loop_start ($3);
! 1620: }
! 1621: }
! 1622: lineno_labeled_stmt
! 1623: {
! 1624: if ($<itype>5)
! 1625: iterator_for_loop_end ($3);
! 1626: }
! 1627:
! 1628: /* This really should allow any kind of declaration,
! 1629: for generality. Fix it before turning it back on.
! 1630:
! 1631: all_iter_stmt_with_decl:
! 1632: FOR '(' ITERATOR pushlevel setspecs iterator_spec ')'
! 1633: {
! 1634: */ /* The value returned by this action is */
! 1635: /* 1 if everything is OK */
! 1636: /* 0 in case of error or already bound iterator */
! 1637: /*
! 1638: iterator_for_loop_start ($6);
! 1639: }
! 1640: lineno_labeled_stmt
! 1641: {
! 1642: iterator_for_loop_end ($6);
! 1643: emit_line_note (input_filename, lineno);
! 1644: expand_end_bindings (getdecls (), 1, 0);
! 1645: $<ttype>$ = poplevel (1, 1, 0);
! 1646: pop_momentary ();
! 1647: }
! 1648: */
! 1649:
1.1 root 1650: /* Any kind of label, including jump labels and case labels.
1651: ANSI C accepts labels only before statements, but we allow them
1652: also at the end of a compound statement. */
1653:
1.1.1.5 ! root 1654: label: CASE expr_no_commas ':'
1.1 root 1655: { register tree value = check_case_value ($2);
1656: register tree label
1657: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1658:
1659: stmt_count++;
1660:
1661: if (value != error_mark_node)
1662: {
1663: tree duplicate;
1664: int success = pushcase (value, label, &duplicate);
1665: if (success == 1)
1666: error ("case label not within a switch statement");
1667: else if (success == 2)
1668: {
1669: error ("duplicate case value");
1670: error_with_decl (duplicate, "this is the first entry for that value");
1671: }
1672: else if (success == 3)
1673: warning ("case value out of range");
1674: else if (success == 5)
1675: error ("case label within scope of cleanup or variable array");
1676: }
1677: position_after_white_space (); }
1.1.1.5 ! root 1678: | CASE expr_no_commas ELLIPSIS expr_no_commas ':'
1.1 root 1679: { register tree value1 = check_case_value ($2);
1680: register tree value2 = check_case_value ($4);
1681: register tree label
1682: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1683:
1684: stmt_count++;
1685:
1686: if (value1 != error_mark_node && value2 != error_mark_node)
1687: {
1688: tree duplicate;
1689: int success = pushcase_range (value1, value2, label,
1690: &duplicate);
1691: if (success == 1)
1692: error ("case label not within a switch statement");
1693: else if (success == 2)
1694: {
1695: error ("duplicate case value");
1696: error_with_decl (duplicate, "this is the first entry for that value");
1697: }
1698: else if (success == 3)
1699: warning ("case value out of range");
1700: else if (success == 4)
1701: warning ("empty case range");
1702: else if (success == 5)
1703: error ("case label within scope of cleanup or variable array");
1704: }
1705: position_after_white_space (); }
1706: | DEFAULT ':'
1707: {
1708: tree duplicate;
1709: register tree label
1710: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1711: int success = pushcase (NULL_TREE, label, &duplicate);
1712: stmt_count++;
1713: if (success == 1)
1714: error ("default label not within a switch statement");
1715: else if (success == 2)
1716: {
1717: error ("multiple default labels in one switch");
1718: error_with_decl (duplicate, "this is the first default label");
1719: }
1720: position_after_white_space (); }
1721: | identifier ':'
1722: { tree label = define_label (input_filename, lineno, $1);
1723: stmt_count++;
1724: emit_nop ();
1725: if (label)
1726: expand_label (label);
1727: position_after_white_space (); }
1728: ;
1729:
1730: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */
1731:
1732: maybe_type_qual:
1733: /* empty */
1734: { emit_line_note (input_filename, lineno); }
1735: | TYPE_QUAL
1736: { emit_line_note (input_filename, lineno); }
1737: ;
1738:
1739: xexpr:
1740: /* empty */
1741: { $$ = NULL_TREE; }
1742: | expr
1743: ;
1744:
1745: /* These are the operands other than the first string and colon
1746: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
1747: asm_operands: /* empty */
1748: { $$ = NULL_TREE; }
1749: | nonnull_asm_operands
1750: ;
1751:
1752: nonnull_asm_operands:
1753: asm_operand
1754: | nonnull_asm_operands ',' asm_operand
1755: { $$ = chainon ($1, $3); }
1756: ;
1757:
1758: asm_operand:
1759: STRING '(' expr ')'
1760: { $$ = build_tree_list ($1, $3); }
1761: ;
1762:
1763: asm_clobbers:
1764: string
1765: { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
1766: | asm_clobbers ',' string
1767: { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
1768: ;
1769:
1770: /* This is what appears inside the parens in a function declarator.
1771: Its value is a list of ..._TYPE nodes. */
1772: parmlist:
1773: { pushlevel (0);
1774: clear_parm_order ();
1775: declare_parm_level (0); }
1776: parmlist_1
1777: { $$ = $2;
1778: parmlist_tags_warning ();
1779: poplevel (0, 0, 0); }
1780: ;
1781:
1782: parmlist_1:
1783: parmlist_2 ')'
1784: | parms ';'
1785: { tree parm;
1.1.1.3 root 1786: if (pedantic)
1787: pedwarn ("ANSI C forbids forward parameter declarations");
1.1 root 1788: /* Mark the forward decls as such. */
1789: for (parm = getdecls (); parm; parm = TREE_CHAIN (parm))
1790: TREE_ASM_WRITTEN (parm) = 1;
1791: clear_parm_order (); }
1792: parmlist_1
1793: { $$ = $4; }
1794: | error ')'
1795: { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
1796: ;
1797:
1798: /* This is what appears inside the parens in a function declarator.
1799: Is value is represented in the format that grokdeclarator expects. */
1800: parmlist_2: /* empty */
1801: { $$ = get_parm_info (0); }
1802: | ELLIPSIS
1803: { $$ = get_parm_info (0);
1804: if (pedantic)
1805: pedwarn ("ANSI C requires a named argument before `...'");
1806: }
1807: | parms
1808: { $$ = get_parm_info (1); }
1809: | parms ',' ELLIPSIS
1810: { $$ = get_parm_info (0); }
1811: ;
1812:
1813: parms:
1814: parm
1815: { push_parm_decl ($1); }
1816: | parms ',' parm
1817: { push_parm_decl ($3); }
1818: ;
1819:
1820: /* A single parameter declaration or parameter type name,
1821: as found in a parmlist. */
1822: parm:
1823: typed_declspecs parm_declarator
1824: { $$ = build_tree_list ($1, $2) ; }
1825: | typed_declspecs notype_declarator
1826: { $$ = build_tree_list ($1, $2) ; }
1827: | typed_declspecs absdcl
1828: { $$ = build_tree_list ($1, $2); }
1829: | declmods notype_declarator
1830: { $$ = build_tree_list ($1, $2) ; }
1831: | declmods absdcl
1832: { $$ = build_tree_list ($1, $2); }
1833: ;
1834:
1835: /* This is used in a function definition
1836: where either a parmlist or an identifier list is ok.
1837: Its value is a list of ..._TYPE nodes or a list of identifiers. */
1838: parmlist_or_identifiers:
1839: { pushlevel (0);
1840: clear_parm_order ();
1841: declare_parm_level (1); }
1842: parmlist_or_identifiers_1
1843: { $$ = $2;
1844: parmlist_tags_warning ();
1845: poplevel (0, 0, 0); }
1846: ;
1847:
1848: parmlist_or_identifiers_1:
1.1.1.3 root 1849: parmlist_1
1.1 root 1850: | identifiers ')'
1851: { tree t;
1852: for (t = $1; t; t = TREE_CHAIN (t))
1853: if (TREE_VALUE (t) == NULL_TREE)
1854: error ("`...' in old-style identifier list");
1855: $$ = tree_cons (NULL_TREE, NULL_TREE, $1); }
1856: ;
1857:
1858: /* A nonempty list of identifiers. */
1859: identifiers:
1860: IDENTIFIER
1861: { $$ = build_tree_list (NULL_TREE, $1); }
1862: | identifiers ',' IDENTIFIER
1863: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
1864: ;
1865:
1866: /* A nonempty list of identifiers, including typenames. */
1867: identifiers_or_typenames:
1868: identifier
1869: { $$ = build_tree_list (NULL_TREE, $1); }
1870: | identifiers_or_typenames ',' identifier
1871: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
1872: ;
1.1.1.4 root 1873:
1.1 root 1874: %%
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.