|
|
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.