|
|
1.1 ! root 1: /* YACC parser for C syntax and for Objective C. -*-c-*- ! 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: /* 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: Sed commands in Makefile.in are used to convert this file into ! 24: c-parse.y and into objc-parse.y. */ ! 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: ifc ! 30: %expect 8 ! 31: ! 32: /* These are the 8 conflicts you should get in parse.output; ! 33: the state numbers may vary if minor changes in the grammar are made. ! 34: ! 35: State 41 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 36: State 92 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 37: State 99 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 38: State 103 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 39: State 119 contains 1 shift/reduce conflict. (See comment at component_decl.) ! 40: State 183 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 41: State 193 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 42: State 199 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 43: */ ! 44: end ifc ! 45: ! 46: %{ ! 47: #include <stdio.h> ! 48: #include <errno.h> ! 49: #include <setjmp.h> ! 50: ! 51: #include "config.h" ! 52: #include "tree.h" ! 53: #include "input.h" ! 54: #include "c-lex.h" ! 55: #include "c-tree.h" ! 56: #include "flags.h" ! 57: ! 58: #ifdef MULTIBYTE_CHARS ! 59: #include <stdlib.h> ! 60: #include <locale.h> ! 61: #endif ! 62: ! 63: ifobjc ! 64: #include "objc-act.h" ! 65: end ifobjc ! 66: ! 67: /* Since parsers are distinct for each language, put the language string ! 68: definition here. */ ! 69: ifobjc ! 70: char *language_string = "GNU Objective-C"; ! 71: end ifobjc ! 72: ifc ! 73: char *language_string = "GNU C"; ! 74: end ifc ! 75: ! 76: #ifndef errno ! 77: extern int errno; ! 78: #endif ! 79: ! 80: void yyerror (); ! 81: ! 82: /* Like YYERROR but do call yyerror. */ ! 83: #define YYERROR1 { yyerror ("syntax error"); YYERROR; } ! 84: ! 85: /* Cause the `yydebug' variable to be defined. */ ! 86: #define YYDEBUG 1 ! 87: %} ! 88: ! 89: %start program ! 90: ! 91: %union {long itype; tree ttype; enum tree_code code; ! 92: char *filename; int lineno; } ! 93: ! 94: /* All identifiers that are not reserved words ! 95: and are not declared typedefs in the current block */ ! 96: %token IDENTIFIER ! 97: ! 98: /* All identifiers that are declared typedefs in the current block. ! 99: In some contexts, they are treated just like IDENTIFIER, ! 100: but they can also serve as typespecs in declarations. */ ! 101: %token TYPENAME ! 102: ! 103: /* Reserved words that specify storage class. ! 104: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 105: %token SCSPEC ! 106: ! 107: /* Reserved words that specify type. ! 108: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 109: %token TYPESPEC ! 110: ! 111: /* Reserved words that qualify type: "const" or "volatile". ! 112: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 113: %token TYPE_QUAL ! 114: ! 115: /* Character or numeric constants. ! 116: yylval is the node for the constant. */ ! 117: %token CONSTANT ! 118: ! 119: /* String constants in raw form. ! 120: yylval is a STRING_CST node. */ ! 121: %token STRING ! 122: ! 123: /* "...", used for functions with variable arglists. */ ! 124: %token ELLIPSIS ! 125: ! 126: /* the reserved words */ ! 127: /* SCO include files test "ASM", so use something else. */ ! 128: %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT ! 129: %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF ALIGN ! 130: %token ATTRIBUTE EXTENSION LABEL ! 131: %token REALPART IMAGPART ! 132: ! 133: /* Add precedence rules to solve dangling else s/r conflict */ ! 134: %nonassoc IF ! 135: %nonassoc ELSE ! 136: ! 137: /* Define the operator tokens and their precedences. ! 138: The value is an integer because, if used, it is the tree code ! 139: to use in the expression made from the operator. */ ! 140: ! 141: %right <code> ASSIGN '=' ! 142: %right <code> '?' ':' ! 143: %left <code> OROR ! 144: %left <code> ANDAND ! 145: %left <code> '|' ! 146: %left <code> '^' ! 147: %left <code> '&' ! 148: %left <code> EQCOMPARE ! 149: %left <code> ARITHCOMPARE ! 150: %left <code> LSHIFT RSHIFT ! 151: %left <code> '+' '-' ! 152: %left <code> '*' '/' '%' ! 153: %right <code> UNARY PLUSPLUS MINUSMINUS ! 154: %left HYPERUNARY ! 155: %left <code> POINTSAT '.' '(' '[' ! 156: ! 157: /* The Objective-C keywords. These are included in C and in ! 158: Objective C, so that the token codes are the same in both. */ ! 159: %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE ! 160: %token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS ! 161: ! 162: /* Objective-C string constants in raw form. ! 163: yylval is an OBJC_STRING_CST node. */ ! 164: %token OBJC_STRING ! 165: ! 166: ! 167: %type <code> unop ! 168: ! 169: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist ! 170: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING ! 171: %type <ttype> typed_declspecs reserved_declspecs ! 172: %type <ttype> typed_typespecs reserved_typespecquals ! 173: %type <ttype> declmods typespec typespecqual_reserved ! 174: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual ! 175: %type <ttype> initdecls notype_initdecls initdcl notype_initdcl ! 176: %type <ttype> init maybeasm ! 177: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers ! 178: %type <ttype> maybe_attribute attribute_list attrib ! 179: ! 180: %type <ttype> compstmt ! 181: ! 182: %type <ttype> declarator ! 183: %type <ttype> notype_declarator after_type_declarator ! 184: %type <ttype> parm_declarator ! 185: ! 186: %type <ttype> structsp component_decl_list component_decl_list2 ! 187: %type <ttype> component_decl components component_declarator ! 188: %type <ttype> enumlist enumerator ! 189: %type <ttype> typename absdcl absdcl1 type_quals ! 190: %type <ttype> xexpr parms parm identifiers ! 191: ! 192: %type <ttype> parmlist parmlist_1 parmlist_2 ! 193: %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1 ! 194: %type <ttype> identifiers_or_typenames ! 195: ! 196: %type <itype> setspecs ! 197: ! 198: %type <filename> save_filename ! 199: %type <lineno> save_lineno ! 200: ! 201: ifobjc ! 202: /* the Objective-C nonterminals */ ! 203: ! 204: %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator ! 205: %type <ttype> methoddecl unaryselector keywordselector selector ! 206: %type <ttype> keyworddecl receiver objcmessageexpr messageargs ! 207: %type <ttype> keywordexpr keywordarglist keywordarg ! 208: %type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr ! 209: %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr ! 210: %type <ttype> objc_string protocolrefs identifier_list objcprotocolexpr ! 211: %type <ttype> CLASSNAME OBJC_STRING OBJECTNAME ! 212: %type <ttype> objc_openbracket.expr_no_commas ! 213: end ifobjc ! 214: ! 215: %{ ! 216: /* Number of statements (loosely speaking) seen so far. */ ! 217: static int stmt_count; ! 218: ! 219: /* Input file and line number of the end of the body of last simple_if; ! 220: used by the stmt-rule immediately after simple_if returns. */ ! 221: static char *if_stmt_file; ! 222: static int if_stmt_line; ! 223: ! 224: /* List of types and structure classes of the current declaration. */ ! 225: static tree current_declspecs; ! 226: ! 227: /* Stack of saved values of current_declspecs. */ ! 228: static tree declspec_stack; ! 229: ! 230: /* 1 if we explained undeclared var errors. */ ! 231: static int undeclared_variable_notice; ! 232: ! 233: ifobjc ! 234: /* Objective-C specific information */ ! 235: ! 236: tree objc_interface_context; ! 237: tree objc_implementation_context; ! 238: tree objc_method_context; ! 239: tree objc_ivar_chain; ! 240: tree objc_ivar_context; ! 241: enum tree_code objc_inherit_code; ! 242: int objc_receiver_context; ! 243: int objc_public_flag; ! 244: ! 245: end ifobjc ! 246: ! 247: /* Tell yyparse how to print a token's value, if yydebug is set. */ ! 248: ! 249: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) ! 250: extern void yyprint (); ! 251: %} ! 252: ! 253: %% ! 254: program: /* empty */ ! 255: { if (pedantic) ! 256: pedwarn ("ANSI C forbids an empty source file"); ! 257: ifobjc ! 258: objc_finish (); ! 259: end ifobjc ! 260: } ! 261: | extdefs ! 262: { ! 263: /* In case there were missing closebraces, ! 264: get us back to the global binding level. */ ! 265: while (! global_bindings_p ()) ! 266: poplevel (0, 0, 0); ! 267: ifobjc ! 268: objc_finish (); ! 269: end ifobjc ! 270: } ! 271: ; ! 272: ! 273: /* the reason for the strange actions in this rule ! 274: is so that notype_initdecls when reached via datadef ! 275: can find a valid list of type and sc specs in $0. */ ! 276: ! 277: extdefs: ! 278: {$<ttype>$ = NULL_TREE; } extdef ! 279: | extdefs {$<ttype>$ = NULL_TREE; } extdef ! 280: ; ! 281: ! 282: extdef: ! 283: fndef ! 284: | datadef ! 285: ifobjc ! 286: | objcdef ! 287: end ifobjc ! 288: | ASM_KEYWORD '(' expr ')' ';' ! 289: { STRIP_NOPS ($3); ! 290: if ((TREE_CODE ($3) == ADDR_EXPR ! 291: && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST) ! 292: || TREE_CODE ($3) == STRING_CST) ! 293: assemble_asm ($3); ! 294: else ! 295: error ("argument of `asm' is not a constant string"); } ! 296: ; ! 297: ! 298: datadef: ! 299: setspecs notype_initdecls ';' ! 300: { if (pedantic) ! 301: error ("ANSI C forbids data definition with no type or storage class"); ! 302: else if (!flag_traditional) ! 303: warning ("data definition has no type or storage class"); } ! 304: | declmods setspecs notype_initdecls ';' ! 305: {} ! 306: | typed_declspecs setspecs initdecls ';' ! 307: {} ! 308: | declmods ';' ! 309: { pedwarn ("empty declaration"); } ! 310: | typed_declspecs ';' ! 311: { shadow_tag ($1); } ! 312: | error ';' ! 313: | error '}' ! 314: | ';' ! 315: { if (pedantic) ! 316: pedwarn ("ANSI C does not allow extra `;' outside of a function"); } ! 317: ; ! 318: ! 319: fndef: ! 320: typed_declspecs setspecs declarator ! 321: { if (! start_function ($1, $3, 0)) ! 322: YYERROR1; ! 323: reinit_parse_for_function (); } ! 324: xdecls ! 325: { store_parm_decls (); } ! 326: compstmt_or_error ! 327: { finish_function (0); } ! 328: | typed_declspecs setspecs declarator error ! 329: { } ! 330: | declmods setspecs notype_declarator ! 331: { if (! start_function ($1, $3, 0)) ! 332: YYERROR1; ! 333: reinit_parse_for_function (); } ! 334: xdecls ! 335: { store_parm_decls (); } ! 336: compstmt_or_error ! 337: { finish_function (0); } ! 338: | declmods setspecs notype_declarator error ! 339: { } ! 340: | setspecs notype_declarator ! 341: { if (! start_function (NULL_TREE, $2, 0)) ! 342: YYERROR1; ! 343: reinit_parse_for_function (); } ! 344: xdecls ! 345: { store_parm_decls (); } ! 346: compstmt_or_error ! 347: { finish_function (0); } ! 348: | setspecs notype_declarator error ! 349: { } ! 350: ; ! 351: ! 352: identifier: ! 353: IDENTIFIER ! 354: | TYPENAME ! 355: ifobjc ! 356: | OBJECTNAME ! 357: | CLASSNAME ! 358: end ifobjc ! 359: ; ! 360: ! 361: unop: '&' ! 362: { $$ = ADDR_EXPR; } ! 363: | '-' ! 364: { $$ = NEGATE_EXPR; } ! 365: | '+' ! 366: { $$ = CONVERT_EXPR; } ! 367: | PLUSPLUS ! 368: { $$ = PREINCREMENT_EXPR; } ! 369: | MINUSMINUS ! 370: { $$ = PREDECREMENT_EXPR; } ! 371: | '~' ! 372: { $$ = BIT_NOT_EXPR; } ! 373: | '!' ! 374: { $$ = TRUTH_NOT_EXPR; } ! 375: ; ! 376: ! 377: expr: nonnull_exprlist ! 378: { $$ = build_compound_expr ($1); } ! 379: ; ! 380: ! 381: exprlist: ! 382: /* empty */ ! 383: { $$ = NULL_TREE; } ! 384: | nonnull_exprlist ! 385: ; ! 386: ! 387: nonnull_exprlist: ! 388: expr_no_commas ! 389: { $$ = build_tree_list (NULL_TREE, $1); } ! 390: | nonnull_exprlist ',' expr_no_commas ! 391: { chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 392: ; ! 393: ! 394: unary_expr: ! 395: primary ! 396: | '*' cast_expr %prec UNARY ! 397: { $$ = build_indirect_ref ($2, "unary *"); } ! 398: /* __extension__ turns off -pedantic for following primary. */ ! 399: | EXTENSION ! 400: { $<itype>1 = pedantic; ! 401: pedantic = 0; } ! 402: cast_expr %prec UNARY ! 403: { $$ = $3; ! 404: pedantic = $<itype>1; } ! 405: | unop cast_expr %prec UNARY ! 406: { $$ = build_unary_op ($1, $2, 0); ! 407: overflow_warning ($$); } ! 408: /* Refer to the address of a label as a pointer. */ ! 409: | ANDAND identifier ! 410: { tree label = lookup_label ($2); ! 411: if (label == 0) ! 412: $$ = null_pointer_node; ! 413: else ! 414: { ! 415: TREE_USED (label) = 1; ! 416: $$ = build1 (ADDR_EXPR, ptr_type_node, label); ! 417: TREE_CONSTANT ($$) = 1; ! 418: } ! 419: } ! 420: /* This seems to be impossible on some machines, so let's turn it off. ! 421: You can use __builtin_next_arg to find the anonymous stack args. ! 422: | '&' ELLIPSIS ! 423: { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl)); ! 424: $$ = error_mark_node; ! 425: if (TREE_VALUE (tree_last (types)) == void_type_node) ! 426: error ("`&...' used in function with fixed number of arguments"); ! 427: else ! 428: { ! 429: if (pedantic) ! 430: pedwarn ("ANSI C forbids `&...'"); ! 431: $$ = tree_last (DECL_ARGUMENTS (current_function_decl)); ! 432: $$ = build_unary_op (ADDR_EXPR, $$, 0); ! 433: } } ! 434: */ ! 435: | SIZEOF unary_expr %prec UNARY ! 436: { if (TREE_CODE ($2) == COMPONENT_REF ! 437: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1))) ! 438: error ("`sizeof' applied to a bit-field"); ! 439: $$ = c_sizeof (TREE_TYPE ($2)); } ! 440: | SIZEOF '(' typename ')' %prec HYPERUNARY ! 441: { $$ = c_sizeof (groktypename ($3)); } ! 442: | ALIGNOF unary_expr %prec UNARY ! 443: { $$ = c_alignof_expr ($2); } ! 444: | ALIGNOF '(' typename ')' %prec HYPERUNARY ! 445: { $$ = c_alignof (groktypename ($3)); } ! 446: | REALPART cast_expr %prec UNARY ! 447: { $$ = build_unary_op (REALPART_EXPR, $2, 0); } ! 448: | IMAGPART cast_expr %prec UNARY ! 449: { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); } ! 450: ; ! 451: ! 452: cast_expr: ! 453: unary_expr ! 454: | '(' typename ')' cast_expr %prec UNARY ! 455: { tree type = groktypename ($2); ! 456: $$ = build_c_cast (type, $4); } ! 457: | '(' typename ')' '{' ! 458: { start_init (NULL_TREE, NULL, 0); ! 459: $2 = groktypename ($2); ! 460: really_start_incremental_init ($2); } ! 461: initlist_maybe_comma '}' %prec UNARY ! 462: { char *name; ! 463: tree result = pop_init_level (0); ! 464: tree type = $2; ! 465: finish_init (); ! 466: ! 467: if (pedantic) ! 468: pedwarn ("ANSI C forbids constructor expressions"); ! 469: if (TYPE_NAME (type) != 0) ! 470: { ! 471: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ! 472: name = IDENTIFIER_POINTER (TYPE_NAME (type)); ! 473: else ! 474: name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); ! 475: } ! 476: else ! 477: name = ""; ! 478: $$ = result; ! 479: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) ! 480: { ! 481: int failure = complete_array_type (type, $$, 1); ! 482: if (failure) ! 483: abort (); ! 484: } ! 485: } ! 486: ; ! 487: ! 488: expr_no_commas: ! 489: cast_expr ! 490: | expr_no_commas '+' expr_no_commas ! 491: { $$ = parser_build_binary_op ($2, $1, $3); } ! 492: | expr_no_commas '-' expr_no_commas ! 493: { $$ = parser_build_binary_op ($2, $1, $3); } ! 494: | expr_no_commas '*' expr_no_commas ! 495: { $$ = parser_build_binary_op ($2, $1, $3); } ! 496: | expr_no_commas '/' expr_no_commas ! 497: { $$ = parser_build_binary_op ($2, $1, $3); } ! 498: | expr_no_commas '%' expr_no_commas ! 499: { $$ = parser_build_binary_op ($2, $1, $3); } ! 500: | expr_no_commas LSHIFT expr_no_commas ! 501: { $$ = parser_build_binary_op ($2, $1, $3); } ! 502: | expr_no_commas RSHIFT expr_no_commas ! 503: { $$ = parser_build_binary_op ($2, $1, $3); } ! 504: | expr_no_commas ARITHCOMPARE expr_no_commas ! 505: { $$ = parser_build_binary_op ($2, $1, $3); } ! 506: | expr_no_commas EQCOMPARE expr_no_commas ! 507: { $$ = parser_build_binary_op ($2, $1, $3); } ! 508: | expr_no_commas '&' expr_no_commas ! 509: { $$ = parser_build_binary_op ($2, $1, $3); } ! 510: | expr_no_commas '|' expr_no_commas ! 511: { $$ = parser_build_binary_op ($2, $1, $3); } ! 512: | expr_no_commas '^' expr_no_commas ! 513: { $$ = parser_build_binary_op ($2, $1, $3); } ! 514: | expr_no_commas ANDAND expr_no_commas ! 515: { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); } ! 516: | expr_no_commas OROR expr_no_commas ! 517: { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); } ! 518: | expr_no_commas '?' xexpr ':' expr_no_commas ! 519: { $$ = build_conditional_expr ($1, $3, $5); } ! 520: | expr_no_commas '=' expr_no_commas ! 521: { $$ = build_modify_expr ($1, NOP_EXPR, $3); ! 522: C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } ! 523: | expr_no_commas ASSIGN expr_no_commas ! 524: { $$ = build_modify_expr ($1, $2, $3); ! 525: /* This inhibits warnings in truthvalue_conversion. */ ! 526: C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } ! 527: ; ! 528: ! 529: primary: ! 530: IDENTIFIER ! 531: { ! 532: tree context; ! 533: ! 534: $$ = lastiddecl; ! 535: if (!$$ || $$ == error_mark_node) ! 536: { ! 537: if (yychar == YYEMPTY) ! 538: yychar = YYLEX; ! 539: if (yychar == '(') ! 540: { ! 541: ifobjc ! 542: tree decl; ! 543: ! 544: if (objc_receiver_context ! 545: && ! (objc_receiver_context ! 546: && strcmp (IDENTIFIER_POINTER ($1), "super"))) ! 547: /* we have a message to super */ ! 548: $$ = get_super_receiver (); ! 549: else if (objc_method_context ! 550: && (decl = is_ivar (objc_ivar_chain, $1))) ! 551: { ! 552: if (is_private (decl)) ! 553: $$ = error_mark_node; ! 554: else ! 555: $$ = build_ivar_reference ($1); ! 556: } ! 557: else ! 558: end ifobjc ! 559: { ! 560: /* Ordinary implicit function declaration. */ ! 561: $$ = implicitly_declare ($1); ! 562: assemble_external ($$); ! 563: TREE_USED ($$) = 1; ! 564: } ! 565: } ! 566: else if (current_function_decl == 0) ! 567: { ! 568: error ("`%s' undeclared here (not in a function)", ! 569: IDENTIFIER_POINTER ($1)); ! 570: $$ = error_mark_node; ! 571: } ! 572: else ! 573: { ! 574: ifobjc ! 575: tree decl; ! 576: ! 577: if (objc_receiver_context ! 578: && ! strcmp (IDENTIFIER_POINTER ($1), "super")) ! 579: /* we have a message to super */ ! 580: $$ = get_super_receiver (); ! 581: else if (objc_method_context ! 582: && (decl = is_ivar (objc_ivar_chain, $1))) ! 583: { ! 584: if (is_private (decl)) ! 585: $$ = error_mark_node; ! 586: else ! 587: $$ = build_ivar_reference ($1); ! 588: } ! 589: else ! 590: end ifobjc ! 591: { ! 592: if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node ! 593: || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl) ! 594: { ! 595: error ("`%s' undeclared (first use this function)", ! 596: IDENTIFIER_POINTER ($1)); ! 597: ! 598: if (! undeclared_variable_notice) ! 599: { ! 600: error ("(Each undeclared identifier is reported only once"); ! 601: error ("for each function it appears in.)"); ! 602: undeclared_variable_notice = 1; ! 603: } ! 604: } ! 605: $$ = error_mark_node; ! 606: /* Prevent repeated error messages. */ ! 607: IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node; ! 608: IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl; ! 609: } ! 610: } ! 611: } ! 612: else if (TREE_TYPE ($$) == error_mark_node) ! 613: $$ = error_mark_node; ! 614: else if (C_DECL_ANTICIPATED ($$)) ! 615: { ! 616: /* The first time we see a build-in function used, ! 617: if it has not been declared. */ ! 618: C_DECL_ANTICIPATED ($$) = 0; ! 619: if (yychar == YYEMPTY) ! 620: yychar = YYLEX; ! 621: if (yychar == '(') ! 622: { ! 623: /* Omit the implicit declaration we ! 624: would ordinarily do, so we don't lose ! 625: the actual built in type. ! 626: But print a diagnostic for the mismatch. */ ! 627: ifobjc ! 628: if (objc_method_context ! 629: && is_ivar (objc_ivar_chain, $1)) ! 630: error ("Instance variable `%s' implicitly declared as function", ! 631: IDENTIFIER_POINTER (DECL_NAME ($$))); ! 632: else ! 633: end ifobjc ! 634: if (TREE_CODE ($$) != FUNCTION_DECL) ! 635: error ("`%s' implicitly declared as function", ! 636: IDENTIFIER_POINTER (DECL_NAME ($$))); ! 637: else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$))) ! 638: != TYPE_MODE (integer_type_node)) ! 639: && (TREE_TYPE (TREE_TYPE ($$)) ! 640: != void_type_node)) ! 641: pedwarn ("type mismatch in implicit declaration for built-in function `%s'", ! 642: IDENTIFIER_POINTER (DECL_NAME ($$))); ! 643: /* If it really returns void, change that to int. */ ! 644: if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node) ! 645: TREE_TYPE ($$) ! 646: = build_function_type (integer_type_node, ! 647: TYPE_ARG_TYPES (TREE_TYPE ($$))); ! 648: } ! 649: else ! 650: pedwarn ("built-in function `%s' used without declaration", ! 651: IDENTIFIER_POINTER (DECL_NAME ($$))); ! 652: ! 653: /* Do what we would ordinarily do when a fn is used. */ ! 654: assemble_external ($$); ! 655: TREE_USED ($$) = 1; ! 656: } ! 657: else ! 658: { ! 659: assemble_external ($$); ! 660: TREE_USED ($$) = 1; ! 661: ifobjc ! 662: /* we have a definition - still check if iVariable */ ! 663: ! 664: if (!objc_receiver_context ! 665: || (objc_receiver_context ! 666: && strcmp (IDENTIFIER_POINTER ($1), "super"))) ! 667: { ! 668: tree decl; ! 669: ! 670: if (objc_method_context ! 671: && (decl = is_ivar (objc_ivar_chain, $1))) ! 672: { ! 673: if (IDENTIFIER_LOCAL_VALUE ($1)) ! 674: warning ("local declaration of `%s' hides instance variable", ! 675: IDENTIFIER_POINTER ($1)); ! 676: else ! 677: { ! 678: if (is_private (decl)) ! 679: $$ = error_mark_node; ! 680: else ! 681: $$ = build_ivar_reference ($1); ! 682: } ! 683: } ! 684: } ! 685: else /* we have a message to super */ ! 686: $$ = get_super_receiver (); ! 687: end ifobjc ! 688: } ! 689: ! 690: if (TREE_CODE ($$) == CONST_DECL) ! 691: { ! 692: $$ = DECL_INITIAL ($$); ! 693: /* This is to prevent an enum whose value is 0 ! 694: from being considered a null pointer constant. */ ! 695: $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$); ! 696: TREE_CONSTANT ($$) = 1; ! 697: } ! 698: } ! 699: | CONSTANT ! 700: | string ! 701: { $$ = combine_strings ($1); } ! 702: | '(' expr ')' ! 703: { char class = TREE_CODE_CLASS (TREE_CODE ($2)); ! 704: if (class == 'e' || class == '1' ! 705: || class == '2' || class == '<') ! 706: C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK); ! 707: $$ = $2; } ! 708: | '(' error ')' ! 709: { $$ = error_mark_node; } ! 710: | '(' ! 711: { if (current_function_decl == 0) ! 712: { ! 713: error ("braced-group within expression allowed only inside a function"); ! 714: YYERROR; ! 715: } ! 716: /* We must force a BLOCK for this level ! 717: so that, if it is not expanded later, ! 718: there is a way to turn off the entire subtree of blocks ! 719: that are contained in it. */ ! 720: keep_next_level (); ! 721: push_iterator_stack (); ! 722: push_label_level (); ! 723: $<ttype>$ = expand_start_stmt_expr (); } ! 724: compstmt ')' ! 725: { tree rtl_exp; ! 726: if (pedantic) ! 727: pedwarn ("ANSI C forbids braced-groups within expressions"); ! 728: pop_iterator_stack (); ! 729: pop_label_level (); ! 730: rtl_exp = expand_end_stmt_expr ($<ttype>2); ! 731: /* The statements have side effects, so the group does. */ ! 732: TREE_SIDE_EFFECTS (rtl_exp) = 1; ! 733: ! 734: if (TREE_CODE ($3) == BLOCK) ! 735: { ! 736: /* Make a BIND_EXPR for the BLOCK already made. */ ! 737: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), ! 738: NULL_TREE, rtl_exp, $3); ! 739: /* Remove the block from the tree at this point. ! 740: It gets put back at the proper place ! 741: when the BIND_EXPR is expanded. */ ! 742: delete_block ($3); ! 743: } ! 744: else ! 745: $$ = $3; ! 746: } ! 747: | primary '(' exprlist ')' %prec '.' ! 748: { $$ = build_function_call ($1, $3); } ! 749: | primary '[' expr ']' %prec '.' ! 750: { $$ = build_array_ref ($1, $3); } ! 751: | primary '.' identifier ! 752: { ! 753: ifobjc ! 754: if (doing_objc_thang) ! 755: { ! 756: if (is_public ($1, $3)) ! 757: $$ = build_component_ref ($1, $3); ! 758: else ! 759: $$ = error_mark_node; ! 760: } ! 761: else ! 762: end ifobjc ! 763: $$ = build_component_ref ($1, $3); ! 764: } ! 765: | primary POINTSAT identifier ! 766: { ! 767: tree expr = build_indirect_ref ($1, "->"); ! 768: ! 769: ifobjc ! 770: if (doing_objc_thang) ! 771: { ! 772: if (is_public (expr, $3)) ! 773: $$ = build_component_ref (expr, $3); ! 774: else ! 775: $$ = error_mark_node; ! 776: } ! 777: else ! 778: end ifobjc ! 779: $$ = build_component_ref (expr, $3); ! 780: } ! 781: | primary PLUSPLUS ! 782: { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); } ! 783: | primary MINUSMINUS ! 784: { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); } ! 785: ifobjc ! 786: | objcmessageexpr ! 787: { $$ = build_message_expr ($1); } ! 788: | objcselectorexpr ! 789: { $$ = build_selector_expr ($1); } ! 790: | objcprotocolexpr ! 791: { $$ = build_protocol_expr ($1); } ! 792: | objcencodeexpr ! 793: { $$ = build_encode_expr ($1); } ! 794: | objc_string ! 795: { $$ = build_objc_string_object ($1); } ! 796: end ifobjc ! 797: ; ! 798: ! 799: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ ! 800: string: ! 801: STRING ! 802: | string STRING ! 803: { $$ = chainon ($1, $2); } ! 804: ; ! 805: ! 806: ifobjc ! 807: /* Produces an OBJC_STRING_CST with prehaps more OBJC_STRING_CSTs chained ! 808: onto it. */ ! 809: objc_string: ! 810: OBJC_STRING ! 811: | objc_string OBJC_STRING ! 812: { $$ = chainon ($1, $2); } ! 813: ; ! 814: end ifobjc ! 815: ! 816: xdecls: ! 817: /* empty */ ! 818: | datadecls ! 819: | datadecls ELLIPSIS ! 820: /* ... is used here to indicate a varargs function. */ ! 821: { c_mark_varargs (); ! 822: if (pedantic) ! 823: pedwarn ("ANSI C does not permit use of `varargs.h'"); } ! 824: ; ! 825: ! 826: /* The following are analogous to lineno_decl, decls and decl ! 827: except that they do not allow nested functions. ! 828: They are used for old-style parm decls. */ ! 829: lineno_datadecl: ! 830: save_filename save_lineno datadecl ! 831: { } ! 832: ; ! 833: ! 834: datadecls: ! 835: lineno_datadecl ! 836: | errstmt ! 837: | datadecls lineno_datadecl ! 838: | lineno_datadecl errstmt ! 839: ; ! 840: ! 841: datadecl: ! 842: typed_declspecs setspecs initdecls ';' ! 843: { current_declspecs = TREE_VALUE (declspec_stack); ! 844: declspec_stack = TREE_CHAIN (declspec_stack); ! 845: resume_momentary ($2); } ! 846: | declmods setspecs notype_initdecls ';' ! 847: { current_declspecs = TREE_VALUE (declspec_stack); ! 848: declspec_stack = TREE_CHAIN (declspec_stack); ! 849: resume_momentary ($2); } ! 850: | typed_declspecs ';' ! 851: { shadow_tag_warned ($1, 1); ! 852: pedwarn ("empty declaration"); } ! 853: | declmods ';' ! 854: { pedwarn ("empty declaration"); } ! 855: ; ! 856: ! 857: /* This combination which saves a lineno before a decl ! 858: is the normal thing to use, rather than decl itself. ! 859: This is to avoid shift/reduce conflicts in contexts ! 860: where statement labels are allowed. */ ! 861: lineno_decl: ! 862: save_filename save_lineno decl ! 863: { } ! 864: ; ! 865: ! 866: decls: ! 867: lineno_decl ! 868: | errstmt ! 869: | decls lineno_decl ! 870: | lineno_decl errstmt ! 871: ; ! 872: ! 873: /* records the type and storage class specs to use for processing ! 874: the declarators that follow. ! 875: Maintains a stack of outer-level values of current_declspecs, ! 876: for the sake of parm declarations nested in function declarators. */ ! 877: setspecs: /* empty */ ! 878: { $$ = suspend_momentary (); ! 879: pending_xref_error (); ! 880: declspec_stack = tree_cons (NULL_TREE, current_declspecs, ! 881: declspec_stack); ! 882: current_declspecs = $<ttype>0; } ! 883: ; ! 884: ! 885: decl: ! 886: typed_declspecs setspecs initdecls ';' ! 887: { current_declspecs = TREE_VALUE (declspec_stack); ! 888: declspec_stack = TREE_CHAIN (declspec_stack); ! 889: resume_momentary ($2); } ! 890: | declmods setspecs notype_initdecls ';' ! 891: { current_declspecs = TREE_VALUE (declspec_stack); ! 892: declspec_stack = TREE_CHAIN (declspec_stack); ! 893: resume_momentary ($2); } ! 894: | typed_declspecs setspecs nested_function ! 895: { current_declspecs = TREE_VALUE (declspec_stack); ! 896: declspec_stack = TREE_CHAIN (declspec_stack); ! 897: resume_momentary ($2); } ! 898: | declmods setspecs notype_nested_function ! 899: { current_declspecs = TREE_VALUE (declspec_stack); ! 900: declspec_stack = TREE_CHAIN (declspec_stack); ! 901: resume_momentary ($2); } ! 902: | typed_declspecs ';' ! 903: { shadow_tag ($1); } ! 904: | declmods ';' ! 905: { pedwarn ("empty declaration"); } ! 906: ; ! 907: ! 908: /* Declspecs which contain at least one type specifier or typedef name. ! 909: (Just `const' or `volatile' is not enough.) ! 910: A typedef'd name following these is taken as a name to be declared. */ ! 911: ! 912: typed_declspecs: ! 913: typespec reserved_declspecs ! 914: { $$ = tree_cons (NULL_TREE, $1, $2); } ! 915: | declmods typespec reserved_declspecs ! 916: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ! 917: ; ! 918: ! 919: reserved_declspecs: /* empty */ ! 920: { $$ = NULL_TREE; } ! 921: | reserved_declspecs typespecqual_reserved ! 922: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 923: | reserved_declspecs SCSPEC ! 924: { if (extra_warnings) ! 925: warning ("`%s' is not at beginning of declaration", ! 926: IDENTIFIER_POINTER ($2)); ! 927: $$ = tree_cons (NULL_TREE, $2, $1); } ! 928: ; ! 929: ! 930: /* List of just storage classes and type modifiers. ! 931: A declaration can start with just this, but then it cannot be used ! 932: to redeclare a typedef-name. */ ! 933: ! 934: declmods: ! 935: TYPE_QUAL ! 936: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); ! 937: TREE_STATIC ($$) = 1; } ! 938: | SCSPEC ! 939: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 940: | declmods TYPE_QUAL ! 941: { $$ = tree_cons (NULL_TREE, $2, $1); ! 942: TREE_STATIC ($$) = 1; } ! 943: | declmods SCSPEC ! 944: { if (extra_warnings && TREE_STATIC ($1)) ! 945: warning ("`%s' is not at beginning of declaration", ! 946: IDENTIFIER_POINTER ($2)); ! 947: $$ = tree_cons (NULL_TREE, $2, $1); ! 948: TREE_STATIC ($$) = TREE_STATIC ($1); } ! 949: ; ! 950: ! 951: ! 952: /* Used instead of declspecs where storage classes are not allowed ! 953: (that is, for typenames and structure components). ! 954: Don't accept a typedef-name if anything but a modifier precedes it. */ ! 955: ! 956: typed_typespecs: ! 957: typespec reserved_typespecquals ! 958: { $$ = tree_cons (NULL_TREE, $1, $2); } ! 959: | nonempty_type_quals typespec reserved_typespecquals ! 960: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ! 961: ; ! 962: ! 963: reserved_typespecquals: /* empty */ ! 964: { $$ = NULL_TREE; } ! 965: | reserved_typespecquals typespecqual_reserved ! 966: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 967: ; ! 968: ! 969: /* A typespec (but not a type qualifier). ! 970: Once we have seen one of these in a declaration, ! 971: if a typedef name appears then it is being redeclared. */ ! 972: ! 973: typespec: TYPESPEC ! 974: | structsp ! 975: | TYPENAME ! 976: { /* For a typedef name, record the meaning, not the name. ! 977: In case of `foo foo, bar;'. */ ! 978: $$ = lookup_name ($1); } ! 979: ifobjc ! 980: | CLASSNAME protocolrefs ! 981: { $$ = get_static_reference ($1, $2); } ! 982: | OBJECTNAME protocolrefs ! 983: { $$ = get_object_reference ($2); } ! 984: end ifobjc ! 985: | TYPEOF '(' expr ')' ! 986: { $$ = TREE_TYPE ($3); } ! 987: | TYPEOF '(' typename ')' ! 988: { $$ = groktypename ($3); } ! 989: ; ! 990: ! 991: /* A typespec that is a reserved word, or a type qualifier. */ ! 992: ! 993: typespecqual_reserved: TYPESPEC ! 994: | TYPE_QUAL ! 995: | structsp ! 996: ; ! 997: ! 998: initdecls: ! 999: initdcl ! 1000: | initdecls ',' initdcl ! 1001: ; ! 1002: ! 1003: notype_initdecls: ! 1004: notype_initdcl ! 1005: | notype_initdecls ',' initdcl ! 1006: ; ! 1007: ! 1008: maybeasm: ! 1009: /* empty */ ! 1010: { $$ = NULL_TREE; } ! 1011: | ASM_KEYWORD '(' string ')' ! 1012: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 1013: $$ = $3; ! 1014: } ! 1015: ; ! 1016: ! 1017: initdcl: ! 1018: declarator maybeasm maybe_attribute '=' ! 1019: { $<ttype>$ = start_decl ($1, current_declspecs, 1); ! 1020: decl_attributes ($<ttype>$, $3); ! 1021: start_init ($<ttype>$, $2, global_bindings_p ()); } ! 1022: init ! 1023: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1024: { finish_init (); ! 1025: decl_attributes ($<ttype>5, $3); ! 1026: finish_decl ($<ttype>5, $6, $2); } ! 1027: | declarator maybeasm maybe_attribute ! 1028: { tree d = start_decl ($1, current_declspecs, 0); ! 1029: decl_attributes (d, $3); ! 1030: finish_decl (d, NULL_TREE, $2); } ! 1031: ; ! 1032: ! 1033: notype_initdcl: ! 1034: notype_declarator maybeasm maybe_attribute '=' ! 1035: { $<ttype>$ = start_decl ($1, current_declspecs, 1); ! 1036: decl_attributes ($<ttype>$, $3); ! 1037: start_init ($<ttype>$, $2, global_bindings_p ()); } ! 1038: init ! 1039: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1040: { finish_init (); ! 1041: decl_attributes ($<ttype>5, $3); ! 1042: finish_decl ($<ttype>5, $6, $2); } ! 1043: | notype_declarator maybeasm maybe_attribute ! 1044: { tree d = start_decl ($1, current_declspecs, 0); ! 1045: decl_attributes (d, $3); ! 1046: finish_decl (d, NULL_TREE, $2); } ! 1047: ; ! 1048: /* the * rules are dummies to accept the Apollo extended syntax ! 1049: so that the header files compile. */ ! 1050: maybe_attribute: ! 1051: /* empty */ ! 1052: { $$ = NULL_TREE; } ! 1053: | ATTRIBUTE '(' '(' attribute_list ')' ')' ! 1054: { $$ = $4; } ! 1055: ; ! 1056: ! 1057: attribute_list ! 1058: : attrib ! 1059: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 1060: | attribute_list ',' attrib ! 1061: { $$ = tree_cons (NULL_TREE, $3, $1); } ! 1062: ; ! 1063: ! 1064: attrib ! 1065: : IDENTIFIER ! 1066: { if (strcmp (IDENTIFIER_POINTER ($1), "packed") ! 1067: && strcmp (IDENTIFIER_POINTER ($1), "noreturn") ! 1068: && strcmp (IDENTIFIER_POINTER ($1), "offset")) ! 1069: warning ("`%s' attribute directive ignored", ! 1070: IDENTIFIER_POINTER ($1)); ! 1071: $$ = $1; } ! 1072: | TYPE_QUAL ! 1073: | IDENTIFIER '(' IDENTIFIER ')' ! 1074: { /* If not "mode (m)", then issue warning. */ ! 1075: if (strcmp (IDENTIFIER_POINTER ($1), "mode") != 0) ! 1076: { ! 1077: warning ("`%s' attribute directive ignored", ! 1078: IDENTIFIER_POINTER ($1)); ! 1079: $$ = $1; ! 1080: } ! 1081: else ! 1082: $$ = tree_cons ($1, $3, NULL_TREE); } ! 1083: | IDENTIFIER '(' CONSTANT ')' ! 1084: { /* if not "aligned(n)", then issue warning */ ! 1085: if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0 ! 1086: || TREE_CODE ($3) != INTEGER_CST) ! 1087: { ! 1088: warning ("`%s' attribute directive ignored", ! 1089: IDENTIFIER_POINTER ($1)); ! 1090: $$ = $1; ! 1091: } ! 1092: else ! 1093: $$ = tree_cons ($1, $3, NULL_TREE); } ! 1094: | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')' ! 1095: { /* if not "format(...)", then issue warning */ ! 1096: if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0 ! 1097: || TREE_CODE ($5) != INTEGER_CST ! 1098: || TREE_CODE ($7) != INTEGER_CST) ! 1099: { ! 1100: warning ("`%s' attribute directive ignored", ! 1101: IDENTIFIER_POINTER ($1)); ! 1102: $$ = $1; ! 1103: } ! 1104: else ! 1105: $$ = tree_cons ($1, ! 1106: tree_cons ($3, ! 1107: tree_cons ($5, $7, NULL_TREE), ! 1108: NULL_TREE), ! 1109: NULL_TREE); } ! 1110: ; ! 1111: ! 1112: /* Initializers. `init' is the entry point. */ ! 1113: ! 1114: init: ! 1115: expr_no_commas ! 1116: | '{' ! 1117: { really_start_incremental_init (NULL_TREE); ! 1118: /* Note that the call to clear_momentary ! 1119: is in process_init_element. */ ! 1120: push_momentary_for_initlist (); } ! 1121: initlist_maybe_comma '}' ! 1122: { $$ = pop_init_level (0); ! 1123: if ($$ == error_mark_node) ! 1124: pop_momentary (); ! 1125: else ! 1126: pop_momentary_nofree (); } ! 1127: ! 1128: | error ! 1129: { $$ = error_mark_node; } ! 1130: ; ! 1131: ! 1132: /* `initlist_maybe_comma' is the guts of an initializer in braces. */ ! 1133: initlist_maybe_comma: ! 1134: /* empty */ ! 1135: { if (pedantic) ! 1136: pedwarn ("ANSI C forbids empty initializer braces"); } ! 1137: | initlist1 maybecomma ! 1138: ; ! 1139: ! 1140: initlist1: ! 1141: initelt ! 1142: | initlist1 ',' initelt ! 1143: ; ! 1144: ! 1145: /* `initelt' is a single element of an initializer. ! 1146: It may use braces. */ ! 1147: initelt: ! 1148: expr_no_commas ! 1149: { process_init_element ($1); } ! 1150: | '{' ! 1151: { push_init_level (0); } ! 1152: initlist_maybe_comma '}' ! 1153: { process_init_element (pop_init_level (0)); } ! 1154: | error ! 1155: /* These are for labeled elements. The syntax for an array element ! 1156: initializer conflicts with the syntax for an Objective-C message, ! 1157: so don't include these productions in the Objective-C grammer. */ ! 1158: ifc ! 1159: | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '=' ! 1160: { set_init_index ($2, $4); } ! 1161: initelt ! 1162: | '[' expr_no_commas ']' '=' ! 1163: { set_init_index ($2, NULL_TREE); } ! 1164: initelt ! 1165: end ifc ! 1166: ifobjc ! 1167: | objc_openbracket.expr_no_commas ELLIPSIS expr_no_commas ']' '=' ! 1168: { set_init_index ($1, $3); } ! 1169: initelt ! 1170: | objc_openbracket.expr_no_commas ']' '=' ! 1171: { set_init_index ($1, NULL_TREE); } ! 1172: initelt ! 1173: end ifobjc ! 1174: | identifier ':' ! 1175: { set_init_label ($1); } ! 1176: initelt ! 1177: | '.' identifier '=' ! 1178: { set_init_label ($2); } ! 1179: initelt ! 1180: ; ! 1181: ! 1182: nested_function: ! 1183: declarator ! 1184: { push_c_function_context (); ! 1185: if (! start_function (current_declspecs, $1, 1)) ! 1186: { ! 1187: pop_c_function_context (); ! 1188: YYERROR1; ! 1189: } ! 1190: reinit_parse_for_function (); ! 1191: store_parm_decls (); } ! 1192: /* This used to use compstmt_or_error. ! 1193: That caused a bug with input `f(g) int g {}', ! 1194: where the use of YYERROR1 above caused an error ! 1195: which then was handled by compstmt_or_error. ! 1196: There followed a repeated execution of that same rule, ! 1197: which called YYERROR1 again, and so on. */ ! 1198: compstmt ! 1199: { finish_function (1); ! 1200: pop_c_function_context (); } ! 1201: ; ! 1202: ! 1203: notype_nested_function: ! 1204: notype_declarator ! 1205: { push_c_function_context (); ! 1206: if (! start_function (current_declspecs, $1, 1)) ! 1207: { ! 1208: pop_c_function_context (); ! 1209: YYERROR1; ! 1210: } ! 1211: reinit_parse_for_function (); ! 1212: store_parm_decls (); } ! 1213: /* This used to use compstmt_or_error. ! 1214: That caused a bug with input `f(g) int g {}', ! 1215: where the use of YYERROR1 above caused an error ! 1216: which then was handled by compstmt_or_error. ! 1217: There followed a repeated execution of that same rule, ! 1218: which called YYERROR1 again, and so on. */ ! 1219: compstmt ! 1220: { finish_function (1); ! 1221: pop_c_function_context (); } ! 1222: ; ! 1223: ! 1224: /* Any kind of declarator (thus, all declarators allowed ! 1225: after an explicit typespec). */ ! 1226: ! 1227: declarator: ! 1228: after_type_declarator ! 1229: | notype_declarator ! 1230: ; ! 1231: ! 1232: /* A declarator that is allowed only after an explicit typespec. */ ! 1233: ! 1234: after_type_declarator: ! 1235: '(' after_type_declarator ')' ! 1236: { $$ = $2; } ! 1237: | after_type_declarator '(' parmlist_or_identifiers %prec '.' ! 1238: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 1239: /* | after_type_declarator '(' error ')' %prec '.' ! 1240: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 1241: poplevel (0, 0, 0); } */ ! 1242: | after_type_declarator '[' expr ']' %prec '.' ! 1243: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 1244: | after_type_declarator '[' ']' %prec '.' ! 1245: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 1246: | '*' type_quals after_type_declarator %prec UNARY ! 1247: { $$ = make_pointer_declarator ($2, $3); } ! 1248: | TYPENAME ! 1249: ifobjc ! 1250: | OBJECTNAME ! 1251: end ifobjc ! 1252: ; ! 1253: ! 1254: /* Kinds of declarator that can appear in a parameter list ! 1255: in addition to notype_declarator. This is like after_type_declarator ! 1256: but does not allow a typedef name in parentheses as an identifier ! 1257: (because it would conflict with a function with that typedef as arg). */ ! 1258: ! 1259: parm_declarator: ! 1260: parm_declarator '(' parmlist_or_identifiers %prec '.' ! 1261: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 1262: /* | parm_declarator '(' error ')' %prec '.' ! 1263: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 1264: poplevel (0, 0, 0); } */ ! 1265: | parm_declarator '[' expr ']' %prec '.' ! 1266: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 1267: | parm_declarator '[' ']' %prec '.' ! 1268: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 1269: | '*' type_quals parm_declarator %prec UNARY ! 1270: { $$ = make_pointer_declarator ($2, $3); } ! 1271: | TYPENAME ! 1272: ifobjc ! 1273: | OBJECTNAME ! 1274: end ifobjc ! 1275: ; ! 1276: ! 1277: /* A declarator allowed whether or not there has been ! 1278: an explicit typespec. These cannot redeclare a typedef-name. */ ! 1279: ! 1280: notype_declarator: ! 1281: notype_declarator '(' parmlist_or_identifiers %prec '.' ! 1282: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 1283: /* | notype_declarator '(' error ')' %prec '.' ! 1284: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 1285: poplevel (0, 0, 0); } */ ! 1286: | '(' notype_declarator ')' ! 1287: { $$ = $2; } ! 1288: | '*' type_quals notype_declarator %prec UNARY ! 1289: { $$ = make_pointer_declarator ($2, $3); } ! 1290: | notype_declarator '[' expr ']' %prec '.' ! 1291: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 1292: | notype_declarator '[' ']' %prec '.' ! 1293: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 1294: | IDENTIFIER ! 1295: ; ! 1296: ! 1297: structsp: ! 1298: STRUCT identifier '{' ! 1299: { $$ = start_struct (RECORD_TYPE, $2); ! 1300: /* Start scope of tag before parsing components. */ ! 1301: } ! 1302: component_decl_list '}' ! 1303: { $$ = finish_struct ($<ttype>4, $5); ! 1304: /* Really define the structure. */ ! 1305: } ! 1306: | STRUCT '{' component_decl_list '}' ! 1307: { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), ! 1308: $3); } ! 1309: | STRUCT identifier ! 1310: { $$ = xref_tag (RECORD_TYPE, $2); } ! 1311: | UNION identifier '{' ! 1312: { $$ = start_struct (UNION_TYPE, $2); } ! 1313: component_decl_list '}' ! 1314: { $$ = finish_struct ($<ttype>4, $5); } ! 1315: | UNION '{' component_decl_list '}' ! 1316: { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE), ! 1317: $3); } ! 1318: | UNION identifier ! 1319: { $$ = xref_tag (UNION_TYPE, $2); } ! 1320: | ENUM identifier '{' ! 1321: { $<itype>3 = suspend_momentary (); ! 1322: $$ = start_enum ($2); } ! 1323: enumlist maybecomma_warn '}' ! 1324: { $$ = finish_enum ($<ttype>4, nreverse ($5)); ! 1325: resume_momentary ($<itype>3); } ! 1326: | ENUM '{' ! 1327: { $<itype>2 = suspend_momentary (); ! 1328: $$ = start_enum (NULL_TREE); } ! 1329: enumlist maybecomma_warn '}' ! 1330: { $$ = finish_enum ($<ttype>3, nreverse ($4)); ! 1331: resume_momentary ($<itype>2); } ! 1332: | ENUM identifier ! 1333: { $$ = xref_tag (ENUMERAL_TYPE, $2); } ! 1334: ; ! 1335: ! 1336: maybecomma: ! 1337: /* empty */ ! 1338: | ',' ! 1339: ; ! 1340: ! 1341: maybecomma_warn: ! 1342: /* empty */ ! 1343: | ',' ! 1344: { if (pedantic) pedwarn ("comma at end of enumerator list"); } ! 1345: ; ! 1346: ! 1347: component_decl_list: ! 1348: component_decl_list2 ! 1349: { $$ = $1; } ! 1350: | component_decl_list2 component_decl ! 1351: { $$ = chainon ($1, $2); ! 1352: pedwarn ("no semicolon at end of struct or union"); } ! 1353: ; ! 1354: ! 1355: component_decl_list2: /* empty */ ! 1356: { $$ = NULL_TREE; } ! 1357: | component_decl_list2 component_decl ';' ! 1358: { $$ = chainon ($1, $2); } ! 1359: | component_decl_list2 ';' ! 1360: { if (pedantic) ! 1361: pedwarn ("extra semicolon in struct or union specified"); } ! 1362: ifobjc ! 1363: /* foo(sizeof(struct{ @defs(ClassName)})); */ ! 1364: | DEFS '(' CLASSNAME ')' ! 1365: { ! 1366: tree interface = lookup_interface ($3); ! 1367: ! 1368: if (interface) ! 1369: $$ = get_class_ivars (interface); ! 1370: else ! 1371: { ! 1372: error ("Cannot find interface declaration for `%s'", ! 1373: IDENTIFIER_POINTER ($3)); ! 1374: $$ = NULL_TREE; ! 1375: } ! 1376: } ! 1377: end ifobjc ! 1378: ; ! 1379: ! 1380: /* There is a shift-reduce conflict here, because `components' may ! 1381: start with a `typename'. It happens that shifting (the default resolution) ! 1382: does the right thing, because it treats the `typename' as part of ! 1383: a `typed_typespecs'. ! 1384: ! 1385: It is possible that this same technique would allow the distinction ! 1386: between `notype_initdecls' and `initdecls' to be eliminated. ! 1387: But I am being cautious and not trying it. */ ! 1388: ! 1389: component_decl: ! 1390: typed_typespecs setspecs components ! 1391: { $$ = $3; ! 1392: current_declspecs = TREE_VALUE (declspec_stack); ! 1393: declspec_stack = TREE_CHAIN (declspec_stack); ! 1394: resume_momentary ($2); } ! 1395: | typed_typespecs ! 1396: { if (pedantic) ! 1397: pedwarn ("ANSI C forbids member declarations with no members"); ! 1398: shadow_tag($1); ! 1399: $$ = NULL_TREE; } ! 1400: | nonempty_type_quals setspecs components ! 1401: { $$ = $3; ! 1402: current_declspecs = TREE_VALUE (declspec_stack); ! 1403: declspec_stack = TREE_CHAIN (declspec_stack); ! 1404: resume_momentary ($2); } ! 1405: | nonempty_type_quals ! 1406: { if (pedantic) ! 1407: pedwarn ("ANSI C forbids member declarations with no members"); ! 1408: shadow_tag($1); ! 1409: $$ = NULL_TREE; } ! 1410: | error ! 1411: { $$ = NULL_TREE; } ! 1412: ; ! 1413: ! 1414: components: ! 1415: component_declarator ! 1416: | components ',' component_declarator ! 1417: { $$ = chainon ($1, $3); } ! 1418: ; ! 1419: ! 1420: component_declarator: ! 1421: save_filename save_lineno declarator maybe_attribute ! 1422: { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE); ! 1423: decl_attributes ($$, $4); } ! 1424: | save_filename save_lineno ! 1425: declarator ':' expr_no_commas maybe_attribute ! 1426: { $$ = grokfield ($1, $2, $3, current_declspecs, $5); ! 1427: decl_attributes ($$, $6); } ! 1428: | save_filename save_lineno ':' expr_no_commas maybe_attribute ! 1429: { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); ! 1430: decl_attributes ($$, $5); } ! 1431: ; ! 1432: ! 1433: /* We chain the enumerators in reverse order. ! 1434: They are put in forward order where enumlist is used. ! 1435: (The order used to be significant, but no longer is so. ! 1436: However, we still maintain the order, just to be clean.) */ ! 1437: ! 1438: enumlist: ! 1439: enumerator ! 1440: | enumlist ',' enumerator ! 1441: { $$ = chainon ($3, $1); } ! 1442: ; ! 1443: ! 1444: ! 1445: enumerator: ! 1446: identifier ! 1447: { $$ = build_enumerator ($1, NULL_TREE); } ! 1448: | identifier '=' expr_no_commas ! 1449: { $$ = build_enumerator ($1, $3); } ! 1450: ; ! 1451: ! 1452: typename: ! 1453: typed_typespecs absdcl ! 1454: { $$ = build_tree_list ($1, $2); } ! 1455: | nonempty_type_quals absdcl ! 1456: { $$ = build_tree_list ($1, $2); } ! 1457: ; ! 1458: ! 1459: absdcl: /* an absolute declarator */ ! 1460: /* empty */ ! 1461: { $$ = NULL_TREE; } ! 1462: | absdcl1 ! 1463: ; ! 1464: ! 1465: nonempty_type_quals: ! 1466: TYPE_QUAL ! 1467: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 1468: | nonempty_type_quals TYPE_QUAL ! 1469: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 1470: ; ! 1471: ! 1472: type_quals: ! 1473: /* empty */ ! 1474: { $$ = NULL_TREE; } ! 1475: | type_quals TYPE_QUAL ! 1476: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 1477: ; ! 1478: ! 1479: absdcl1: /* a nonempty absolute declarator */ ! 1480: '(' absdcl1 ')' ! 1481: { $$ = $2; } ! 1482: /* `(typedef)1' is `int'. */ ! 1483: | '*' type_quals absdcl1 %prec UNARY ! 1484: { $$ = make_pointer_declarator ($2, $3); } ! 1485: | '*' type_quals %prec UNARY ! 1486: { $$ = make_pointer_declarator ($2, NULL_TREE); } ! 1487: | absdcl1 '(' parmlist %prec '.' ! 1488: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 1489: | absdcl1 '[' expr ']' %prec '.' ! 1490: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 1491: | absdcl1 '[' ']' %prec '.' ! 1492: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 1493: | '(' parmlist %prec '.' ! 1494: { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); } ! 1495: | '[' expr ']' %prec '.' ! 1496: { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); } ! 1497: | '[' ']' %prec '.' ! 1498: { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); } ! 1499: ; ! 1500: ! 1501: /* at least one statement, the first of which parses without error. */ ! 1502: /* stmts is used only after decls, so an invalid first statement ! 1503: is actually regarded as an invalid decl and part of the decls. */ ! 1504: ! 1505: stmts: ! 1506: lineno_stmt_or_label ! 1507: | stmts lineno_stmt_or_label ! 1508: | stmts errstmt ! 1509: ; ! 1510: ! 1511: xstmts: ! 1512: /* empty */ ! 1513: | stmts ! 1514: ; ! 1515: ! 1516: errstmt: error ';' ! 1517: ; ! 1518: ! 1519: pushlevel: /* empty */ ! 1520: { emit_line_note (input_filename, lineno); ! 1521: pushlevel (0); ! 1522: clear_last_expr (); ! 1523: push_momentary (); ! 1524: expand_start_bindings (0); ! 1525: ifobjc ! 1526: if (objc_method_context) ! 1527: add_objc_decls (); ! 1528: end ifobjc ! 1529: } ! 1530: ; ! 1531: ! 1532: /* Read zero or more forward-declarations for labels ! 1533: that nested functions can jump to. */ ! 1534: maybe_label_decls: ! 1535: /* empty */ ! 1536: | label_decls ! 1537: { if (pedantic) ! 1538: pedwarn ("ANSI C forbids label declarations"); } ! 1539: ; ! 1540: ! 1541: label_decls: ! 1542: label_decl ! 1543: | label_decls label_decl ! 1544: ; ! 1545: ! 1546: label_decl: ! 1547: LABEL identifiers_or_typenames ';' ! 1548: { tree link; ! 1549: for (link = $2; link; link = TREE_CHAIN (link)) ! 1550: { ! 1551: tree label = shadow_label (TREE_VALUE (link)); ! 1552: C_DECLARED_LABEL_FLAG (label) = 1; ! 1553: declare_nonlocal_label (label); ! 1554: } ! 1555: } ! 1556: ; ! 1557: ! 1558: /* This is the body of a function definition. ! 1559: It causes syntax errors to ignore to the next openbrace. */ ! 1560: compstmt_or_error: ! 1561: compstmt ! 1562: {} ! 1563: | error compstmt ! 1564: ; ! 1565: ! 1566: compstmt: '{' '}' ! 1567: { $$ = convert (void_type_node, integer_zero_node); } ! 1568: | '{' pushlevel maybe_label_decls decls xstmts '}' ! 1569: { emit_line_note (input_filename, lineno); ! 1570: expand_end_bindings (getdecls (), 1, 0); ! 1571: $$ = poplevel (1, 1, 0); ! 1572: pop_momentary (); } ! 1573: | '{' pushlevel maybe_label_decls error '}' ! 1574: { emit_line_note (input_filename, lineno); ! 1575: expand_end_bindings (getdecls (), kept_level_p (), 0); ! 1576: $$ = poplevel (kept_level_p (), 0, 0); ! 1577: pop_momentary (); } ! 1578: | '{' pushlevel maybe_label_decls stmts '}' ! 1579: { emit_line_note (input_filename, lineno); ! 1580: expand_end_bindings (getdecls (), kept_level_p (), 0); ! 1581: $$ = poplevel (kept_level_p (), 0, 0); ! 1582: pop_momentary (); } ! 1583: ; ! 1584: ! 1585: /* Value is number of statements counted as of the closeparen. */ ! 1586: simple_if: ! 1587: if_prefix lineno_labeled_stmt ! 1588: /* Make sure expand_end_cond is run once ! 1589: for each call to expand_start_cond. ! 1590: Otherwise a crash is likely. */ ! 1591: | if_prefix error ! 1592: ; ! 1593: ! 1594: if_prefix: ! 1595: IF '(' expr ')' ! 1596: { emit_line_note ($<filename>-1, $<lineno>0); ! 1597: expand_start_cond (truthvalue_conversion ($3), 0); ! 1598: $<itype>$ = stmt_count; ! 1599: if_stmt_file = $<filename>-1; ! 1600: if_stmt_line = $<lineno>0; ! 1601: position_after_white_space (); } ! 1602: ; ! 1603: ! 1604: /* This is a subroutine of stmt. ! 1605: It is used twice, once for valid DO statements ! 1606: and once for catching errors in parsing the end test. */ ! 1607: do_stmt_start: ! 1608: DO ! 1609: { stmt_count++; ! 1610: emit_line_note ($<filename>-1, $<lineno>0); ! 1611: /* See comment in `while' alternative, above. */ ! 1612: emit_nop (); ! 1613: expand_start_loop_continue_elsewhere (1); ! 1614: position_after_white_space (); } ! 1615: lineno_labeled_stmt WHILE ! 1616: { expand_loop_continue_here (); } ! 1617: ; ! 1618: ! 1619: save_filename: ! 1620: { $$ = input_filename; } ! 1621: ; ! 1622: ! 1623: save_lineno: ! 1624: { $$ = lineno; } ! 1625: ; ! 1626: ! 1627: lineno_labeled_stmt: ! 1628: save_filename save_lineno stmt ! 1629: { } ! 1630: /* | save_filename save_lineno error ! 1631: { } ! 1632: */ ! 1633: | save_filename save_lineno label lineno_labeled_stmt ! 1634: { } ! 1635: ; ! 1636: ! 1637: lineno_stmt_or_label: ! 1638: save_filename save_lineno stmt_or_label ! 1639: { } ! 1640: ; ! 1641: ! 1642: stmt_or_label: ! 1643: stmt ! 1644: | label ! 1645: { int next; ! 1646: position_after_white_space (); ! 1647: next = getc (finput); ! 1648: ungetc (next, finput); ! 1649: if (pedantic && next == '}') ! 1650: pedwarn ("ANSI C forbids label at end of compound statement"); ! 1651: } ! 1652: ; ! 1653: ! 1654: /* Parse a single real statement, not including any labels. */ ! 1655: stmt: ! 1656: compstmt ! 1657: { stmt_count++; } ! 1658: | all_iter_stmt ! 1659: | expr ';' ! 1660: { stmt_count++; ! 1661: emit_line_note ($<filename>-1, $<lineno>0); ! 1662: /* It appears that this should not be done--that a non-lvalue array ! 1663: shouldn't get an error if the value isn't used. ! 1664: Section 3.2.2.1 says that an array lvalue gets converted to a pointer ! 1665: if it appears as a top-level expression, ! 1666: but says nothing about non-lvalue arrays. */ ! 1667: #if 0 ! 1668: /* Call default_conversion to get an error ! 1669: on referring to a register array if pedantic. */ ! 1670: if (TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE ! 1671: || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE) ! 1672: $1 = default_conversion ($1); ! 1673: #endif ! 1674: iterator_expand ($1); ! 1675: clear_momentary (); } ! 1676: | simple_if ELSE ! 1677: { expand_start_else (); ! 1678: $<itype>1 = stmt_count; ! 1679: position_after_white_space (); } ! 1680: lineno_labeled_stmt ! 1681: { expand_end_cond (); ! 1682: if (extra_warnings && stmt_count == $<itype>1) ! 1683: warning ("empty body in an else-statement"); } ! 1684: | simple_if %prec IF ! 1685: { expand_end_cond (); ! 1686: /* This warning is here instead of in simple_if, because we ! 1687: do not want a warning if an empty if is followed by an ! 1688: else statement. */ ! 1689: if (extra_warnings && stmt_count == $<itype>1) ! 1690: warning_with_file_and_line (if_stmt_file, if_stmt_line, ! 1691: "empty body in an if-statement"); } ! 1692: /* Make sure expand_end_cond is run once ! 1693: for each call to expand_start_cond. ! 1694: Otherwise a crash is likely. */ ! 1695: | simple_if ELSE error ! 1696: { expand_end_cond (); } ! 1697: | WHILE ! 1698: { stmt_count++; ! 1699: emit_line_note ($<filename>-1, $<lineno>0); ! 1700: /* The emit_nop used to come before emit_line_note, ! 1701: but that made the nop seem like part of the preceding line. ! 1702: And that was confusing when the preceding line was ! 1703: inside of an if statement and was not really executed. ! 1704: I think it ought to work to put the nop after the line number. ! 1705: We will see. --rms, July 15, 1991. */ ! 1706: emit_nop (); } ! 1707: '(' expr ')' ! 1708: { /* Don't start the loop till we have succeeded ! 1709: in parsing the end test. This is to make sure ! 1710: that we end every loop we start. */ ! 1711: expand_start_loop (1); ! 1712: emit_line_note (input_filename, lineno); ! 1713: expand_exit_loop_if_false (NULL_PTR, ! 1714: truthvalue_conversion ($4)); ! 1715: position_after_white_space (); } ! 1716: lineno_labeled_stmt ! 1717: { expand_end_loop (); } ! 1718: | do_stmt_start ! 1719: '(' expr ')' ';' ! 1720: { emit_line_note (input_filename, lineno); ! 1721: expand_exit_loop_if_false (NULL_PTR, ! 1722: truthvalue_conversion ($3)); ! 1723: expand_end_loop (); ! 1724: clear_momentary (); } ! 1725: /* This rule is needed to make sure we end every loop we start. */ ! 1726: | do_stmt_start error ! 1727: { expand_end_loop (); ! 1728: clear_momentary (); } ! 1729: | FOR ! 1730: '(' xexpr ';' ! 1731: { stmt_count++; ! 1732: emit_line_note ($<filename>-1, $<lineno>0); ! 1733: /* See comment in `while' alternative, above. */ ! 1734: emit_nop (); ! 1735: if ($3) c_expand_expr_stmt ($3); ! 1736: /* Next step is to call expand_start_loop_continue_elsewhere, ! 1737: but wait till after we parse the entire for (...). ! 1738: Otherwise, invalid input might cause us to call that ! 1739: fn without calling expand_end_loop. */ ! 1740: } ! 1741: xexpr ';' ! 1742: /* Can't emit now; wait till after expand_start_loop... */ ! 1743: { $<lineno>7 = lineno; ! 1744: $<filename>$ = input_filename; } ! 1745: xexpr ')' ! 1746: { ! 1747: /* Start the loop. Doing this after parsing ! 1748: all the expressions ensures we will end the loop. */ ! 1749: expand_start_loop_continue_elsewhere (1); ! 1750: /* Emit the end-test, with a line number. */ ! 1751: emit_line_note ($<filename>8, $<lineno>7); ! 1752: if ($6) ! 1753: expand_exit_loop_if_false (NULL_PTR, ! 1754: truthvalue_conversion ($6)); ! 1755: /* Don't let the tree nodes for $9 be discarded by ! 1756: clear_momentary during the parsing of the next stmt. */ ! 1757: push_momentary (); ! 1758: $<lineno>7 = lineno; ! 1759: $<filename>8 = input_filename; ! 1760: position_after_white_space (); } ! 1761: lineno_labeled_stmt ! 1762: { /* Emit the increment expression, with a line number. */ ! 1763: emit_line_note ($<filename>8, $<lineno>7); ! 1764: expand_loop_continue_here (); ! 1765: if ($9) ! 1766: c_expand_expr_stmt ($9); ! 1767: pop_momentary (); ! 1768: expand_end_loop (); } ! 1769: | SWITCH '(' expr ')' ! 1770: { stmt_count++; ! 1771: emit_line_note ($<filename>-1, $<lineno>0); ! 1772: c_expand_start_case ($3); ! 1773: /* Don't let the tree nodes for $3 be discarded by ! 1774: clear_momentary during the parsing of the next stmt. */ ! 1775: push_momentary (); ! 1776: position_after_white_space (); } ! 1777: lineno_labeled_stmt ! 1778: { expand_end_case ($3); ! 1779: pop_momentary (); } ! 1780: | BREAK ';' ! 1781: { stmt_count++; ! 1782: emit_line_note ($<filename>-1, $<lineno>0); ! 1783: if ( ! expand_exit_something ()) ! 1784: error ("break statement not within loop or switch"); } ! 1785: | CONTINUE ';' ! 1786: { stmt_count++; ! 1787: emit_line_note ($<filename>-1, $<lineno>0); ! 1788: if (! expand_continue_loop (NULL_PTR)) ! 1789: error ("continue statement not within a loop"); } ! 1790: | RETURN ';' ! 1791: { stmt_count++; ! 1792: emit_line_note ($<filename>-1, $<lineno>0); ! 1793: c_expand_return (NULL_TREE); } ! 1794: | RETURN expr ';' ! 1795: { stmt_count++; ! 1796: emit_line_note ($<filename>-1, $<lineno>0); ! 1797: c_expand_return ($2); } ! 1798: | ASM_KEYWORD maybe_type_qual '(' expr ')' ';' ! 1799: { stmt_count++; ! 1800: emit_line_note ($<filename>-1, $<lineno>0); ! 1801: STRIP_NOPS ($4); ! 1802: if ((TREE_CODE ($4) == ADDR_EXPR ! 1803: && TREE_CODE (TREE_OPERAND ($4, 0)) == STRING_CST) ! 1804: || TREE_CODE ($4) == STRING_CST) ! 1805: expand_asm ($4); ! 1806: else ! 1807: error ("argument of `asm' is not a constant string"); } ! 1808: /* This is the case with just output operands. */ ! 1809: | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';' ! 1810: { stmt_count++; ! 1811: emit_line_note ($<filename>-1, $<lineno>0); ! 1812: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE, ! 1813: $2 == ridpointers[(int)RID_VOLATILE], ! 1814: input_filename, lineno); } ! 1815: /* This is the case with input operands as well. */ ! 1816: | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' asm_operands ')' ';' ! 1817: { stmt_count++; ! 1818: emit_line_note ($<filename>-1, $<lineno>0); ! 1819: c_expand_asm_operands ($4, $6, $8, NULL_TREE, ! 1820: $2 == ridpointers[(int)RID_VOLATILE], ! 1821: input_filename, lineno); } ! 1822: /* This is the case with clobbered registers as well. */ ! 1823: | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' ! 1824: asm_operands ':' asm_clobbers ')' ';' ! 1825: { stmt_count++; ! 1826: emit_line_note ($<filename>-1, $<lineno>0); ! 1827: c_expand_asm_operands ($4, $6, $8, $10, ! 1828: $2 == ridpointers[(int)RID_VOLATILE], ! 1829: input_filename, lineno); } ! 1830: | GOTO identifier ';' ! 1831: { tree decl; ! 1832: stmt_count++; ! 1833: emit_line_note ($<filename>-1, $<lineno>0); ! 1834: decl = lookup_label ($2); ! 1835: if (decl != 0) ! 1836: { ! 1837: TREE_USED (decl) = 1; ! 1838: expand_goto (decl); ! 1839: } ! 1840: } ! 1841: | GOTO '*' expr ';' ! 1842: { stmt_count++; ! 1843: emit_line_note ($<filename>-1, $<lineno>0); ! 1844: expand_computed_goto (convert (ptr_type_node, $3)); } ! 1845: | ';' ! 1846: ; ! 1847: ! 1848: all_iter_stmt: ! 1849: all_iter_stmt_simple ! 1850: /* | all_iter_stmt_with_decl */ ! 1851: ; ! 1852: ! 1853: all_iter_stmt_simple: ! 1854: FOR '(' primary ')' ! 1855: { ! 1856: /* The value returned by this action is */ ! 1857: /* 1 if everything is OK */ ! 1858: /* 0 in case of error or already bound iterator */ ! 1859: ! 1860: $<itype>$ = 0; ! 1861: if (TREE_CODE ($3) != VAR_DECL) ! 1862: error ("invalid `for (ITERATOR)' syntax"); ! 1863: else if (! ITERATOR_P ($3)) ! 1864: error ("`%s' is not an iterator", ! 1865: IDENTIFIER_POINTER (DECL_NAME ($3))); ! 1866: else if (ITERATOR_BOUND_P ($3)) ! 1867: error ("`for (%s)' inside expansion of same iterator", ! 1868: IDENTIFIER_POINTER (DECL_NAME ($3))); ! 1869: else ! 1870: { ! 1871: $<itype>$ = 1; ! 1872: iterator_for_loop_start ($3); ! 1873: } ! 1874: } ! 1875: lineno_labeled_stmt ! 1876: { ! 1877: if ($<itype>5) ! 1878: iterator_for_loop_end ($3); ! 1879: } ! 1880: ! 1881: /* This really should allow any kind of declaration, ! 1882: for generality. Fix it before turning it back on. ! 1883: ! 1884: all_iter_stmt_with_decl: ! 1885: FOR '(' ITERATOR pushlevel setspecs iterator_spec ')' ! 1886: { ! 1887: */ /* The value returned by this action is */ ! 1888: /* 1 if everything is OK */ ! 1889: /* 0 in case of error or already bound iterator */ ! 1890: /* ! 1891: iterator_for_loop_start ($6); ! 1892: } ! 1893: lineno_labeled_stmt ! 1894: { ! 1895: iterator_for_loop_end ($6); ! 1896: emit_line_note (input_filename, lineno); ! 1897: expand_end_bindings (getdecls (), 1, 0); ! 1898: $<ttype>$ = poplevel (1, 1, 0); ! 1899: pop_momentary (); ! 1900: } ! 1901: */ ! 1902: ! 1903: /* Any kind of label, including jump labels and case labels. ! 1904: ANSI C accepts labels only before statements, but we allow them ! 1905: also at the end of a compound statement. */ ! 1906: ! 1907: label: CASE expr_no_commas ':' ! 1908: { register tree value = check_case_value ($2); ! 1909: register tree label ! 1910: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 1911: ! 1912: stmt_count++; ! 1913: ! 1914: if (value != error_mark_node) ! 1915: { ! 1916: tree duplicate; ! 1917: int success = pushcase (value, convert_and_check, ! 1918: label, &duplicate); ! 1919: if (success == 1) ! 1920: error ("case label not within a switch statement"); ! 1921: else if (success == 2) ! 1922: { ! 1923: error ("duplicate case value"); ! 1924: error_with_decl (duplicate, "this is the first entry for that value"); ! 1925: } ! 1926: else if (success == 3) ! 1927: warning ("case value out of range"); ! 1928: else if (success == 5) ! 1929: error ("case label within scope of cleanup or variable array"); ! 1930: } ! 1931: position_after_white_space (); } ! 1932: | CASE expr_no_commas ELLIPSIS expr_no_commas ':' ! 1933: { register tree value1 = check_case_value ($2); ! 1934: register tree value2 = check_case_value ($4); ! 1935: register tree label ! 1936: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 1937: ! 1938: stmt_count++; ! 1939: ! 1940: if (value1 != error_mark_node && value2 != error_mark_node) ! 1941: { ! 1942: tree duplicate; ! 1943: int success = pushcase_range (value1, value2, ! 1944: convert_and_check, label, ! 1945: &duplicate); ! 1946: if (success == 1) ! 1947: error ("case label not within a switch statement"); ! 1948: else if (success == 2) ! 1949: { ! 1950: error ("duplicate case value"); ! 1951: error_with_decl (duplicate, "this is the first entry for that value"); ! 1952: } ! 1953: else if (success == 3) ! 1954: warning ("case value out of range"); ! 1955: else if (success == 4) ! 1956: warning ("empty case range"); ! 1957: else if (success == 5) ! 1958: error ("case label within scope of cleanup or variable array"); ! 1959: } ! 1960: position_after_white_space (); } ! 1961: | DEFAULT ':' ! 1962: { ! 1963: tree duplicate; ! 1964: register tree label ! 1965: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 1966: int success = pushcase (NULL_TREE, 0, label, &duplicate); ! 1967: stmt_count++; ! 1968: if (success == 1) ! 1969: error ("default label not within a switch statement"); ! 1970: else if (success == 2) ! 1971: { ! 1972: error ("multiple default labels in one switch"); ! 1973: error_with_decl (duplicate, "this is the first default label"); ! 1974: } ! 1975: position_after_white_space (); } ! 1976: | identifier ':' ! 1977: { tree label = define_label (input_filename, lineno, $1); ! 1978: stmt_count++; ! 1979: emit_nop (); ! 1980: if (label) ! 1981: expand_label (label); ! 1982: position_after_white_space (); } ! 1983: ; ! 1984: ! 1985: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ ! 1986: ! 1987: maybe_type_qual: ! 1988: /* empty */ ! 1989: { emit_line_note (input_filename, lineno); ! 1990: $$ = NULL_TREE; } ! 1991: | TYPE_QUAL ! 1992: { emit_line_note (input_filename, lineno); } ! 1993: ; ! 1994: ! 1995: xexpr: ! 1996: /* empty */ ! 1997: { $$ = NULL_TREE; } ! 1998: | expr ! 1999: ; ! 2000: ! 2001: /* These are the operands other than the first string and colon ! 2002: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ ! 2003: asm_operands: /* empty */ ! 2004: { $$ = NULL_TREE; } ! 2005: | nonnull_asm_operands ! 2006: ; ! 2007: ! 2008: nonnull_asm_operands: ! 2009: asm_operand ! 2010: | nonnull_asm_operands ',' asm_operand ! 2011: { $$ = chainon ($1, $3); } ! 2012: ; ! 2013: ! 2014: asm_operand: ! 2015: STRING '(' expr ')' ! 2016: { $$ = build_tree_list ($1, $3); } ! 2017: ; ! 2018: ! 2019: asm_clobbers: ! 2020: string ! 2021: { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); } ! 2022: | asm_clobbers ',' string ! 2023: { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); } ! 2024: ; ! 2025: ! 2026: /* This is what appears inside the parens in a function declarator. ! 2027: Its value is a list of ..._TYPE nodes. */ ! 2028: parmlist: ! 2029: { pushlevel (0); ! 2030: clear_parm_order (); ! 2031: declare_parm_level (0); } ! 2032: parmlist_1 ! 2033: { $$ = $2; ! 2034: parmlist_tags_warning (); ! 2035: poplevel (0, 0, 0); } ! 2036: ; ! 2037: ! 2038: parmlist_1: ! 2039: parmlist_2 ')' ! 2040: | parms ';' ! 2041: { tree parm; ! 2042: if (pedantic) ! 2043: pedwarn ("ANSI C forbids forward parameter declarations"); ! 2044: /* Mark the forward decls as such. */ ! 2045: for (parm = getdecls (); parm; parm = TREE_CHAIN (parm)) ! 2046: TREE_ASM_WRITTEN (parm) = 1; ! 2047: clear_parm_order (); } ! 2048: parmlist_1 ! 2049: { $$ = $4; } ! 2050: | error ')' ! 2051: { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); } ! 2052: ; ! 2053: ! 2054: /* This is what appears inside the parens in a function declarator. ! 2055: Is value is represented in the format that grokdeclarator expects. */ ! 2056: parmlist_2: /* empty */ ! 2057: { $$ = get_parm_info (0); } ! 2058: | ELLIPSIS ! 2059: { $$ = get_parm_info (0); ! 2060: if (pedantic) ! 2061: pedwarn ("ANSI C requires a named argument before `...'"); ! 2062: } ! 2063: | parms ! 2064: { $$ = get_parm_info (1); } ! 2065: | parms ',' ELLIPSIS ! 2066: { $$ = get_parm_info (0); } ! 2067: ; ! 2068: ! 2069: parms: ! 2070: parm ! 2071: { push_parm_decl ($1); } ! 2072: | parms ',' parm ! 2073: { push_parm_decl ($3); } ! 2074: ; ! 2075: ! 2076: /* A single parameter declaration or parameter type name, ! 2077: as found in a parmlist. */ ! 2078: parm: ! 2079: typed_declspecs parm_declarator ! 2080: { $$ = build_tree_list ($1, $2) ; } ! 2081: | typed_declspecs notype_declarator ! 2082: { $$ = build_tree_list ($1, $2) ; } ! 2083: | typed_declspecs absdcl ! 2084: { $$ = build_tree_list ($1, $2); } ! 2085: | declmods notype_declarator ! 2086: { $$ = build_tree_list ($1, $2) ; } ! 2087: | declmods absdcl ! 2088: { $$ = build_tree_list ($1, $2); } ! 2089: ; ! 2090: ! 2091: /* This is used in a function definition ! 2092: where either a parmlist or an identifier list is ok. ! 2093: Its value is a list of ..._TYPE nodes or a list of identifiers. */ ! 2094: parmlist_or_identifiers: ! 2095: { pushlevel (0); ! 2096: clear_parm_order (); ! 2097: declare_parm_level (1); } ! 2098: parmlist_or_identifiers_1 ! 2099: { $$ = $2; ! 2100: parmlist_tags_warning (); ! 2101: poplevel (0, 0, 0); } ! 2102: ; ! 2103: ! 2104: parmlist_or_identifiers_1: ! 2105: parmlist_1 ! 2106: | identifiers ')' ! 2107: { tree t; ! 2108: for (t = $1; t; t = TREE_CHAIN (t)) ! 2109: if (TREE_VALUE (t) == NULL_TREE) ! 2110: error ("`...' in old-style identifier list"); ! 2111: $$ = tree_cons (NULL_TREE, NULL_TREE, $1); } ! 2112: ; ! 2113: ! 2114: /* A nonempty list of identifiers. */ ! 2115: identifiers: ! 2116: IDENTIFIER ! 2117: { $$ = build_tree_list (NULL_TREE, $1); } ! 2118: | identifiers ',' IDENTIFIER ! 2119: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 2120: ; ! 2121: ! 2122: /* A nonempty list of identifiers, including typenames. */ ! 2123: identifiers_or_typenames: ! 2124: identifier ! 2125: { $$ = build_tree_list (NULL_TREE, $1); } ! 2126: | identifiers_or_typenames ',' identifier ! 2127: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 2128: ; ! 2129: ! 2130: ifobjc ! 2131: /* Objective-C productions. */ ! 2132: ! 2133: objcdef: ! 2134: classdef ! 2135: | classdecl ! 2136: | aliasdecl ! 2137: | protocoldef ! 2138: | methoddef ! 2139: | END ! 2140: { ! 2141: if (objc_implementation_context) ! 2142: { ! 2143: finish_class (objc_implementation_context); ! 2144: objc_ivar_chain = NULL_TREE; ! 2145: objc_implementation_context = NULL_TREE; ! 2146: } ! 2147: else ! 2148: warning ("`@end' must appear in an implementation context"); ! 2149: } ! 2150: ; ! 2151: ! 2152: /* A nonempty list of identifiers. */ ! 2153: identifier_list: ! 2154: identifier ! 2155: { $$ = build_tree_list (NULL_TREE, $1); } ! 2156: | identifier_list ',' identifier ! 2157: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 2158: ; ! 2159: ! 2160: classdecl: ! 2161: CLASS identifier_list ';' ! 2162: { ! 2163: objc_declare_class ($2); ! 2164: } ! 2165: ! 2166: aliasdecl: ! 2167: ALIAS identifier identifier ';' ! 2168: { ! 2169: objc_declare_alias ($2, $3); ! 2170: } ! 2171: ! 2172: classdef: ! 2173: INTERFACE identifier protocolrefs '{' ! 2174: { ! 2175: if (objc_interface_context) ! 2176: error ("@interface constructs cannot be nested"); ! 2177: objc_interface_context = objc_ivar_context ! 2178: = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3); ! 2179: objc_public_flag = 0; ! 2180: } ! 2181: ivar_decl_list '}' ! 2182: { ! 2183: continue_class (objc_interface_context); ! 2184: } ! 2185: methodprotolist ! 2186: END ! 2187: { ! 2188: finish_class (objc_interface_context); ! 2189: objc_interface_context = NULL_TREE; ! 2190: } ! 2191: ! 2192: | INTERFACE identifier protocolrefs ! 2193: { ! 2194: if (objc_interface_context) ! 2195: error ("@interface constructs cannot be nested"); ! 2196: objc_interface_context ! 2197: = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3); ! 2198: continue_class (objc_interface_context); ! 2199: } ! 2200: methodprotolist ! 2201: END ! 2202: { ! 2203: finish_class (objc_interface_context); ! 2204: objc_interface_context = NULL_TREE; ! 2205: } ! 2206: ! 2207: | INTERFACE identifier ':' identifier protocolrefs '{' ! 2208: { ! 2209: if (objc_interface_context) ! 2210: error ("@interface constructs cannot be nested"); ! 2211: objc_interface_context = objc_ivar_context ! 2212: = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5); ! 2213: objc_public_flag = 0; ! 2214: } ! 2215: ivar_decl_list '}' ! 2216: { ! 2217: continue_class (objc_interface_context); ! 2218: } ! 2219: methodprotolist ! 2220: END ! 2221: { ! 2222: finish_class (objc_interface_context); ! 2223: objc_interface_context = NULL_TREE; ! 2224: } ! 2225: ! 2226: | INTERFACE identifier ':' identifier protocolrefs ! 2227: { ! 2228: if (objc_interface_context) ! 2229: error ("@interface constructs cannot be nested"); ! 2230: objc_interface_context ! 2231: = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5); ! 2232: continue_class (objc_interface_context); ! 2233: } ! 2234: methodprotolist ! 2235: END ! 2236: { ! 2237: finish_class (objc_interface_context); ! 2238: objc_interface_context = NULL_TREE; ! 2239: } ! 2240: ! 2241: | IMPLEMENTATION identifier '{' ! 2242: { ! 2243: objc_implementation_context = objc_ivar_context ! 2244: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE); ! 2245: objc_public_flag = 0; ! 2246: } ! 2247: ivar_decl_list '}' ! 2248: { ! 2249: objc_ivar_chain ! 2250: = continue_class (objc_implementation_context); ! 2251: } ! 2252: ! 2253: | IMPLEMENTATION identifier ! 2254: { ! 2255: objc_implementation_context ! 2256: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE); ! 2257: objc_ivar_chain ! 2258: = continue_class (objc_implementation_context); ! 2259: } ! 2260: ! 2261: | IMPLEMENTATION identifier ':' identifier '{' ! 2262: { ! 2263: objc_implementation_context = objc_ivar_context ! 2264: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); ! 2265: objc_public_flag = 0; ! 2266: } ! 2267: ivar_decl_list '}' ! 2268: { ! 2269: objc_ivar_chain ! 2270: = continue_class (objc_implementation_context); ! 2271: } ! 2272: ! 2273: | IMPLEMENTATION identifier ':' identifier ! 2274: { ! 2275: objc_implementation_context ! 2276: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); ! 2277: objc_ivar_chain ! 2278: = continue_class (objc_implementation_context); ! 2279: } ! 2280: ! 2281: | INTERFACE identifier '(' identifier ')' protocolrefs ! 2282: { ! 2283: objc_interface_context ! 2284: = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6); ! 2285: continue_class (objc_interface_context); ! 2286: } ! 2287: methodprotolist ! 2288: END ! 2289: { ! 2290: finish_class (objc_interface_context); ! 2291: objc_interface_context = NULL_TREE; ! 2292: } ! 2293: ! 2294: | IMPLEMENTATION identifier '(' identifier ')' ! 2295: { ! 2296: objc_implementation_context ! 2297: = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); ! 2298: objc_ivar_chain ! 2299: = continue_class (objc_implementation_context); ! 2300: } ! 2301: ; ! 2302: ! 2303: protocoldef: ! 2304: PROTOCOL identifier protocolrefs ! 2305: { ! 2306: remember_protocol_qualifiers (); ! 2307: objc_interface_context ! 2308: = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3); ! 2309: } ! 2310: methodprotolist END ! 2311: { ! 2312: forget_protocol_qualifiers(); ! 2313: finish_protocol(objc_interface_context); ! 2314: objc_interface_context = NULL_TREE; ! 2315: } ! 2316: | PROTOCOL identifier_list ';' ! 2317: { ! 2318: objc_declare_protocols ($2); ! 2319: } ! 2320: ; ! 2321: ! 2322: protocolrefs: ! 2323: /* empty */ ! 2324: { ! 2325: $$ = NULL_TREE; ! 2326: } ! 2327: | ARITHCOMPARE identifier_list ARITHCOMPARE ! 2328: { ! 2329: if ($1 == LT_EXPR && $3 == GT_EXPR) ! 2330: $$ = $2; ! 2331: else ! 2332: YYERROR1; ! 2333: } ! 2334: ; ! 2335: ! 2336: ivar_decl_list: ! 2337: ivar_decl_list visibility_spec ivar_decls ! 2338: | ivar_decls ! 2339: ; ! 2340: ! 2341: visibility_spec: ! 2342: PRIVATE { objc_public_flag = 2; } ! 2343: | PROTECTED { objc_public_flag = 0; } ! 2344: | PUBLIC { objc_public_flag = 1; } ! 2345: ; ! 2346: ! 2347: ivar_decls: ! 2348: /* empty */ ! 2349: { ! 2350: $$ = NULL_TREE; ! 2351: } ! 2352: | ivar_decls ivar_decl ';' ! 2353: | ivar_decls ';' ! 2354: { ! 2355: if (pedantic) ! 2356: pedwarn ("extra semicolon in struct or union specified"); ! 2357: } ! 2358: ; ! 2359: ! 2360: ! 2361: /* There is a shift-reduce conflict here, because `components' may ! 2362: start with a `typename'. It happens that shifting (the default resolution) ! 2363: does the right thing, because it treats the `typename' as part of ! 2364: a `typed_typespecs'. ! 2365: ! 2366: It is possible that this same technique would allow the distinction ! 2367: between `notype_initdecls' and `initdecls' to be eliminated. ! 2368: But I am being cautious and not trying it. */ ! 2369: ! 2370: ivar_decl: ! 2371: typed_typespecs setspecs ivars ! 2372: { ! 2373: $$ = $3; ! 2374: resume_momentary ($2); ! 2375: } ! 2376: | nonempty_type_quals setspecs ivars ! 2377: { ! 2378: $$ = $3; ! 2379: resume_momentary ($2); ! 2380: } ! 2381: | error ! 2382: { $$ = NULL_TREE; } ! 2383: ; ! 2384: ! 2385: ivars: ! 2386: /* empty */ ! 2387: { $$ = NULL_TREE; } ! 2388: | ivar_declarator ! 2389: | ivars ',' ivar_declarator ! 2390: ; ! 2391: ! 2392: ivar_declarator: ! 2393: declarator ! 2394: { ! 2395: $$ = add_instance_variable (objc_ivar_context, ! 2396: objc_public_flag, ! 2397: $1, current_declspecs, ! 2398: NULL_TREE); ! 2399: } ! 2400: | declarator ':' expr_no_commas ! 2401: { ! 2402: $$ = add_instance_variable (objc_ivar_context, ! 2403: objc_public_flag, ! 2404: $1, current_declspecs, $3); ! 2405: } ! 2406: | ':' expr_no_commas ! 2407: { ! 2408: $$ = add_instance_variable (objc_ivar_context, ! 2409: objc_public_flag, ! 2410: NULL_TREE, ! 2411: current_declspecs, $2); ! 2412: } ! 2413: ; ! 2414: ! 2415: methoddef: ! 2416: '+' ! 2417: { ! 2418: remember_protocol_qualifiers (); ! 2419: if (objc_implementation_context) ! 2420: objc_inherit_code = CLASS_METHOD_DECL; ! 2421: else ! 2422: fatal ("method definition not in class context"); ! 2423: } ! 2424: methoddecl ! 2425: { ! 2426: forget_protocol_qualifiers (); ! 2427: add_class_method (objc_implementation_context, $3); ! 2428: start_method_def ($3); ! 2429: objc_method_context = $3; ! 2430: } ! 2431: optarglist ! 2432: { ! 2433: continue_method_def (); ! 2434: } ! 2435: compstmt_or_error ! 2436: { ! 2437: finish_method_def (); ! 2438: objc_method_context = NULL_TREE; ! 2439: } ! 2440: ! 2441: | '-' ! 2442: { ! 2443: remember_protocol_qualifiers (); ! 2444: if (objc_implementation_context) ! 2445: objc_inherit_code = INSTANCE_METHOD_DECL; ! 2446: else ! 2447: fatal ("method definition not in class context"); ! 2448: } ! 2449: methoddecl ! 2450: { ! 2451: forget_protocol_qualifiers (); ! 2452: add_instance_method (objc_implementation_context, $3); ! 2453: start_method_def ($3); ! 2454: objc_method_context = $3; ! 2455: } ! 2456: optarglist ! 2457: { ! 2458: continue_method_def (); ! 2459: } ! 2460: compstmt_or_error ! 2461: { ! 2462: finish_method_def (); ! 2463: objc_method_context = NULL_TREE; ! 2464: } ! 2465: ; ! 2466: ! 2467: /* the reason for the strange actions in this rule ! 2468: is so that notype_initdecls when reached via datadef ! 2469: can find a valid list of type and sc specs in $0. */ ! 2470: ! 2471: methodprotolist: ! 2472: /* empty */ ! 2473: | {$<ttype>$ = NULL_TREE; } methodprotolist2 ! 2474: ; ! 2475: ! 2476: methodprotolist2: /* eliminates a shift/reduce conflict */ ! 2477: methodproto ! 2478: | datadef ! 2479: | methodprotolist2 methodproto ! 2480: | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef ! 2481: ; ! 2482: ! 2483: semi_or_error: ! 2484: ';' ! 2485: | error ! 2486: ; ! 2487: ! 2488: methodproto: ! 2489: '+' ! 2490: { ! 2491: objc_inherit_code = CLASS_METHOD_DECL; ! 2492: } ! 2493: methoddecl ! 2494: { ! 2495: add_class_method (objc_interface_context, $3); ! 2496: } ! 2497: semi_or_error ! 2498: ! 2499: | '-' ! 2500: { ! 2501: objc_inherit_code = INSTANCE_METHOD_DECL; ! 2502: } ! 2503: methoddecl ! 2504: { ! 2505: add_instance_method (objc_interface_context, $3); ! 2506: } ! 2507: semi_or_error ! 2508: ; ! 2509: ! 2510: methoddecl: ! 2511: '(' typename ')' unaryselector ! 2512: { ! 2513: $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE); ! 2514: } ! 2515: ! 2516: | unaryselector ! 2517: { ! 2518: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE); ! 2519: } ! 2520: ! 2521: | '(' typename ')' keywordselector optparmlist ! 2522: { ! 2523: $$ = build_method_decl (objc_inherit_code, $2, $4, $5); ! 2524: } ! 2525: ! 2526: | keywordselector optparmlist ! 2527: { ! 2528: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2); ! 2529: } ! 2530: ; ! 2531: ! 2532: /* "optarglist" assumes that start_method_def has already been called... ! 2533: if it is not, the "xdecls" will not be placed in the proper scope */ ! 2534: ! 2535: optarglist: ! 2536: /* empty */ ! 2537: | ';' myxdecls ! 2538: ; ! 2539: ! 2540: /* to get around the following situation: "int foo (int a) int b; {}" that ! 2541: is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */ ! 2542: ! 2543: myxdecls: ! 2544: /* empty */ ! 2545: | mydecls ! 2546: ; ! 2547: ! 2548: mydecls: ! 2549: mydecl ! 2550: | errstmt ! 2551: | mydecls mydecl ! 2552: | mydecl errstmt ! 2553: ; ! 2554: ! 2555: mydecl: ! 2556: typed_declspecs setspecs myparms ';' ! 2557: { resume_momentary ($2); } ! 2558: | typed_declspecs ';' ! 2559: { shadow_tag ($1); } ! 2560: | declmods ';' ! 2561: { pedwarn ("empty declaration"); } ! 2562: ; ! 2563: ! 2564: myparms: ! 2565: myparm ! 2566: { push_parm_decl ($1); } ! 2567: | myparms ',' myparm ! 2568: { push_parm_decl ($3); } ! 2569: ; ! 2570: ! 2571: /* A single parameter declaration or parameter type name, ! 2572: as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */ ! 2573: ! 2574: myparm: ! 2575: parm_declarator ! 2576: { $$ = build_tree_list (current_declspecs, $1) ; } ! 2577: | notype_declarator ! 2578: { $$ = build_tree_list (current_declspecs, $1) ; } ! 2579: | absdcl ! 2580: { $$ = build_tree_list (current_declspecs, $1) ; } ! 2581: ; ! 2582: ! 2583: optparmlist: ! 2584: /* empty */ ! 2585: { ! 2586: $$ = NULL_TREE; ! 2587: } ! 2588: | ',' ELLIPSIS ! 2589: { ! 2590: /* oh what a kludge! */ ! 2591: $$ = (tree)1; ! 2592: } ! 2593: | ',' ! 2594: { ! 2595: pushlevel (0); ! 2596: } ! 2597: parmlist_2 ! 2598: { ! 2599: /* returns a tree list node generated by get_parm_info */ ! 2600: $$ = $3; ! 2601: poplevel (0, 0, 0); ! 2602: } ! 2603: ; ! 2604: ! 2605: unaryselector: ! 2606: selector ! 2607: ; ! 2608: ! 2609: keywordselector: ! 2610: keyworddecl ! 2611: ! 2612: | keywordselector keyworddecl ! 2613: { ! 2614: $$ = chainon ($1, $2); ! 2615: } ! 2616: ; ! 2617: ! 2618: selector: ! 2619: IDENTIFIER ! 2620: | TYPENAME ! 2621: | OBJECTNAME ! 2622: | reservedwords ! 2623: ; ! 2624: ! 2625: reservedwords: ! 2626: ENUM { $$ = get_identifier (token_buffer); } ! 2627: | STRUCT { $$ = get_identifier (token_buffer); } ! 2628: | UNION { $$ = get_identifier (token_buffer); } ! 2629: | IF { $$ = get_identifier (token_buffer); } ! 2630: | ELSE { $$ = get_identifier (token_buffer); } ! 2631: | WHILE { $$ = get_identifier (token_buffer); } ! 2632: | DO { $$ = get_identifier (token_buffer); } ! 2633: | FOR { $$ = get_identifier (token_buffer); } ! 2634: | SWITCH { $$ = get_identifier (token_buffer); } ! 2635: | CASE { $$ = get_identifier (token_buffer); } ! 2636: | DEFAULT { $$ = get_identifier (token_buffer); } ! 2637: | BREAK { $$ = get_identifier (token_buffer); } ! 2638: | CONTINUE { $$ = get_identifier (token_buffer); } ! 2639: | RETURN { $$ = get_identifier (token_buffer); } ! 2640: | GOTO { $$ = get_identifier (token_buffer); } ! 2641: | ASM_KEYWORD { $$ = get_identifier (token_buffer); } ! 2642: | SIZEOF { $$ = get_identifier (token_buffer); } ! 2643: | TYPEOF { $$ = get_identifier (token_buffer); } ! 2644: | ALIGNOF { $$ = get_identifier (token_buffer); } ! 2645: | TYPESPEC ! 2646: | TYPE_QUAL ! 2647: ; ! 2648: ! 2649: keyworddecl: ! 2650: selector ':' '(' typename ')' identifier ! 2651: { ! 2652: $$ = build_keyword_decl ($1, $4, $6); ! 2653: } ! 2654: ! 2655: | selector ':' identifier ! 2656: { ! 2657: $$ = build_keyword_decl ($1, NULL_TREE, $3); ! 2658: } ! 2659: ! 2660: | ':' '(' typename ')' identifier ! 2661: { ! 2662: $$ = build_keyword_decl (NULL_TREE, $3, $5); ! 2663: } ! 2664: ! 2665: | ':' identifier ! 2666: { ! 2667: $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2); ! 2668: } ! 2669: ; ! 2670: ! 2671: messageargs: ! 2672: selector ! 2673: | keywordarglist ! 2674: ; ! 2675: ! 2676: keywordarglist: ! 2677: keywordarg ! 2678: | keywordarglist keywordarg ! 2679: { ! 2680: $$ = chainon ($1, $2); ! 2681: } ! 2682: ; ! 2683: ! 2684: ! 2685: keywordexpr: ! 2686: nonnull_exprlist ! 2687: { ! 2688: if (TREE_CHAIN ($1) == NULL_TREE) ! 2689: /* just return the expr., remove a level of indirection */ ! 2690: $$ = TREE_VALUE ($1); ! 2691: else ! 2692: /* we have a comma expr., we will collapse later */ ! 2693: $$ = $1; ! 2694: } ! 2695: ; ! 2696: ! 2697: keywordarg: ! 2698: selector ':' keywordexpr ! 2699: { ! 2700: $$ = build_tree_list ($1, $3); ! 2701: } ! 2702: | ':' keywordexpr ! 2703: { ! 2704: $$ = build_tree_list (NULL_TREE, $2); ! 2705: } ! 2706: ; ! 2707: ! 2708: receiver: ! 2709: expr_no_commas ! 2710: | CLASSNAME ! 2711: { ! 2712: $$ = get_class_reference ($1); ! 2713: } ! 2714: ; ! 2715: ! 2716: objc_openbracket.expr_no_commas: ! 2717: '[' ! 2718: { objc_receiver_context = 1; } ! 2719: receiver ! 2720: { ! 2721: objc_receiver_context = 0; ! 2722: $$ = $3; ! 2723: } ! 2724: ; ! 2725: ! 2726: objcmessageexpr: ! 2727: objc_openbracket.expr_no_commas ! 2728: messageargs ']' ! 2729: { ! 2730: /* build nonnull_exprlist */ ! 2731: $1 = build_tree_list (NULL_TREE, $1); ! 2732: /* build expr */ ! 2733: $1 = build_compound_expr ($1); ! 2734: $$ = build_tree_list ($1, $2); ! 2735: } ! 2736: | objc_openbracket.expr_no_commas ! 2737: ',' nonnull_exprlist ! 2738: { ! 2739: /* make $1 a nonnull_exprlist */ ! 2740: $1 = build_tree_list (NULL_TREE, $1); ! 2741: /* chain them together */ ! 2742: chainon ($1, $3); ! 2743: /* make a compound expr */ ! 2744: $1 = build_compound_expr ($1); ! 2745: } ! 2746: messageargs ']' ! 2747: { ! 2748: $$ = build_tree_list ($1, $5); ! 2749: } ! 2750: ; ! 2751: ! 2752: selectorarg: ! 2753: selector ! 2754: | keywordnamelist ! 2755: ; ! 2756: ! 2757: keywordnamelist: ! 2758: keywordname ! 2759: | keywordnamelist keywordname ! 2760: { ! 2761: $$ = chainon ($1, $2); ! 2762: } ! 2763: ; ! 2764: ! 2765: keywordname: ! 2766: selector ':' ! 2767: { ! 2768: $$ = build_tree_list ($1, NULL_TREE); ! 2769: } ! 2770: | ':' ! 2771: { ! 2772: $$ = build_tree_list (NULL_TREE, NULL_TREE); ! 2773: } ! 2774: ; ! 2775: ! 2776: objcselectorexpr: ! 2777: SELECTOR '(' selectorarg ')' ! 2778: { ! 2779: $$ = $3; ! 2780: } ! 2781: ; ! 2782: ! 2783: objcprotocolexpr: ! 2784: PROTOCOL '(' identifier ')' ! 2785: { ! 2786: $$ = $3; ! 2787: } ! 2788: ; ! 2789: ! 2790: /* extension to support C-structures in the archiver */ ! 2791: ! 2792: objcencodeexpr: ! 2793: ENCODE '(' typename ')' ! 2794: { ! 2795: $$ = groktypename ($3); ! 2796: } ! 2797: ; ! 2798: ! 2799: end ifobjc ! 2800: %%
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.