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