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