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