|
|
1.1 ! root 1: /* YACC parser for C syntax. ! 2: Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc. ! 3: Objective-C extensions by s.naroff. ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: ! 22: /* To whomever it may concern: I have heard that such a thing was once ! 23: written by AT&T, but I have never seen it. */ ! 24: ! 25: %expect 36 ! 26: ! 27: /* These are the 8 conflicts you should get in parse.output; ! 28: the state numbers may vary if minor changes in the grammar are made. ! 29: ! 30: State 41 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 31: State 92 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 32: State 99 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 33: State 103 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 34: State 119 contains 1 shift/reduce conflict. (See comment at component_decl.) ! 35: State 183 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 36: State 193 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 37: State 199 contains 1 shift/reduce conflict. (Two ways to recover from error.) ! 38: */ ! 39: ! 40: %{ ! 41: #include <stdio.h> ! 42: #include <errno.h> ! 43: #include <setjmp.h> ! 44: ! 45: #include "config.h" ! 46: #include "tree.h" ! 47: #include "input.h" ! 48: #include "c-lex.h" ! 49: #include "c-tree.h" ! 50: #include "flags.h" ! 51: ! 52: #include "objc-actions.h" ! 53: ! 54: #ifndef errno ! 55: extern int errno; ! 56: #endif ! 57: ! 58: void yyerror (); ! 59: ! 60: /* Like YYERROR but do call yyerror. */ ! 61: #define YYERROR1 { yyerror ("syntax error"); YYERROR; } ! 62: ! 63: /* Cause the `yydebug' variable to be defined. */ ! 64: #define YYDEBUG 1 ! 65: %} ! 66: ! 67: %start program ! 68: ! 69: %union {long itype; tree ttype; enum tree_code code; ! 70: char *filename; int lineno; } ! 71: ! 72: /* All identifiers that are not reserved words ! 73: and are not declared typedefs in the current block */ ! 74: %token IDENTIFIER ! 75: ! 76: /* All identifiers that are declared typedefs in the current block. ! 77: In some contexts, they are treated just like IDENTIFIER, ! 78: but they can also serve as typespecs in declarations. */ ! 79: %token TYPENAME ! 80: ! 81: /* Reserved words that specify storage class. ! 82: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 83: %token SCSPEC ! 84: ! 85: /* Reserved words that specify type. ! 86: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 87: %token TYPESPEC ! 88: ! 89: /* Reserved words that qualify type: "const" or "volatile". ! 90: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 91: %token TYPE_QUAL ! 92: ! 93: /* Character or numeric constants. ! 94: yylval is the node for the constant. */ ! 95: %token CONSTANT ! 96: ! 97: /* String constants in raw form. ! 98: yylval is a STRING_CST node. */ ! 99: %token STRING ! 100: ! 101: /* "...", used for functions with variable arglists. */ ! 102: %token ELLIPSIS ! 103: ! 104: /* the reserved words */ ! 105: %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT ! 106: %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF ALIGN ! 107: %token ATTRIBUTE EXTENSION LABEL ! 108: ! 109: /* Add precedence rules to solve dangling else s/r conflict */ ! 110: %nonassoc IF ! 111: %nonassoc ELSE ! 112: ! 113: /* Define the operator tokens and their precedences. ! 114: The value is an integer because, if used, it is the tree code ! 115: to use in the expression made from the operator. */ ! 116: ! 117: %right <code> ASSIGN '=' ! 118: %right <code> '?' ':' ! 119: %left <code> OROR ! 120: %left <code> ANDAND ! 121: %left <code> '|' ! 122: %left <code> '^' ! 123: %left <code> '&' ! 124: %left <code> EQCOMPARE ! 125: %left <code> ARITHCOMPARE ! 126: %left <code> LSHIFT RSHIFT ! 127: %left <code> '+' '-' ! 128: %left <code> '*' '/' '%' ! 129: %right <code> UNARY PLUSPLUS MINUSMINUS ! 130: %left HYPERUNARY ! 131: %left <code> POINTSAT '.' '(' '[' ! 132: ! 133: /* the Objective-C keywords */ ! 134: %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE ! 135: %token CLASSNAME PUBLIC ! 136: ! 137: ! 138: %type <code> unop ! 139: ! 140: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist ! 141: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING ! 142: %type <ttype> typed_declspecs reserved_declspecs ! 143: %type <ttype> typed_typespecs reserved_typespecquals ! 144: %type <ttype> declmods typespec typespecqual_reserved ! 145: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual ! 146: %type <ttype> initdecls notype_initdecls initdcl notype_initdcl ! 147: %type <ttype> init initlist maybeasm ! 148: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers ! 149: %type <ttype> maybe_attribute attribute_list attrib ! 150: ! 151: %type <ttype> compstmt ! 152: ! 153: %type <ttype> declarator ! 154: %type <ttype> notype_declarator after_type_declarator ! 155: %type <ttype> parm_declarator ! 156: ! 157: %type <ttype> structsp component_decl_list component_decl_list2 ! 158: %type <ttype> component_decl components component_declarator ! 159: %type <ttype> enumlist enumerator ! 160: %type <ttype> typename absdcl absdcl1 type_quals ! 161: %type <ttype> xexpr parms parm identifiers ! 162: ! 163: %type <ttype> parmlist parmlist_1 parmlist_2 ! 164: %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1 ! 165: ! 166: %type <itype> setspecs ! 167: ! 168: %type <filename> save_filename ! 169: %type <lineno> save_lineno ! 170: ! 171: /* the Objective-C nonterminals */ ! 172: ! 173: %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator ! 174: %type <ttype> methoddecl unaryselector keywordselector selector ! 175: %type <ttype> keyworddecl receiver objcmessageexpr messageargs ! 176: %type <ttype> keywordexpr keywordarglist keywordarg ! 177: %type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr ! 178: %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr ! 179: %type <ttype> CLASSNAME ! 180: ! 181: %{ ! 182: /* Number of statements (loosely speaking) seen so far. */ ! 183: static int stmt_count; ! 184: ! 185: /* Input file and line number of the end of the body of last simple_if; ! 186: used by the stmt-rule immediately after simple_if returns. */ ! 187: static char *if_stmt_file; ! 188: static int if_stmt_line; ! 189: ! 190: /* List of types and structure classes of the current declaration. */ ! 191: static tree current_declspecs; ! 192: ! 193: /* Stack of saved values of current_declspecs. */ ! 194: static tree declspec_stack; ! 195: ! 196: /* 1 if we explained undeclared var errors. */ ! 197: static int undeclared_variable_notice; ! 198: ! 199: /* Objective-C specific information */ ! 200: ! 201: tree objc_interface_context; ! 202: tree objc_implementation_context; ! 203: tree objc_method_context; ! 204: tree objc_ivar_chain; ! 205: tree objc_ivar_context; ! 206: enum tree_code objc_inherit_code; ! 207: int objc_receiver_context; ! 208: int objc_public_flag; ! 209: ! 210: /* Tell yyparse how to print a token's value, if yydebug is set. */ ! 211: ! 212: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) ! 213: extern void yyprint (); ! 214: %} ! 215: ! 216: %% ! 217: program: /* empty */ ! 218: { if (pedantic) ! 219: pedwarn ("ANSI C forbids an empty source file"); ! 220: objc_finish (); } ! 221: | extdefs ! 222: { objc_finish (); } ! 223: ; ! 224: ! 225: /* the reason for the strange actions in this rule ! 226: is so that notype_initdecls when reached via datadef ! 227: can find a valid list of type and sc specs in $0. */ ! 228: ! 229: extdefs: ! 230: {$<ttype>$ = NULL_TREE; } extdef ! 231: | extdefs {$<ttype>$ = NULL_TREE; } extdef ! 232: ; ! 233: ! 234: extdef: ! 235: fndef ! 236: | datadef ! 237: | objcdef ! 238: | ASM '(' string ')' ';' ! 239: { if (pedantic) ! 240: pedwarn ("ANSI C forbids use of `asm' keyword"); ! 241: if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 242: assemble_asm ($3); } ! 243: ; ! 244: ! 245: datadef: ! 246: setspecs notype_initdecls ';' ! 247: { if (pedantic) ! 248: error ("ANSI C forbids data definition with no type or storage class"); ! 249: else if (!flag_traditional) ! 250: warning ("data definition has no type or storage class"); } ! 251: | declmods setspecs notype_initdecls ';' ! 252: {} ! 253: | typed_declspecs setspecs initdecls ';' ! 254: {} ! 255: | declmods ';' ! 256: { error ("empty declaration"); } ! 257: | typed_declspecs ';' ! 258: { shadow_tag ($1); } ! 259: | error ';' ! 260: | error '}' ! 261: | ';' ! 262: { if (pedantic) ! 263: pedwarn ("ANSI C does not allow extra `;' outside of a function"); } ! 264: ; ! 265: ! 266: fndef: ! 267: typed_declspecs setspecs declarator ! 268: { if (! start_function ($1, $3, 0)) ! 269: YYERROR1; ! 270: reinit_parse_for_function (); } ! 271: xdecls ! 272: { store_parm_decls (); } ! 273: compstmt_or_error ! 274: { finish_function (0); } ! 275: | typed_declspecs setspecs declarator error ! 276: { } ! 277: | declmods setspecs notype_declarator ! 278: { if (! start_function ($1, $3, 0)) ! 279: YYERROR1; ! 280: reinit_parse_for_function (); } ! 281: xdecls ! 282: { store_parm_decls (); } ! 283: compstmt_or_error ! 284: { finish_function (0); } ! 285: | declmods setspecs notype_declarator error ! 286: { } ! 287: | setspecs notype_declarator ! 288: { if (! start_function (0, $2, 0)) ! 289: YYERROR1; ! 290: reinit_parse_for_function (); } ! 291: xdecls ! 292: { store_parm_decls (); } ! 293: compstmt_or_error ! 294: { finish_function (0); } ! 295: | setspecs notype_declarator error ! 296: { } ! 297: ; ! 298: ! 299: identifier: ! 300: IDENTIFIER ! 301: | TYPENAME ! 302: | CLASSNAME ! 303: { $$ = CLASS_NAME ($1); } ! 304: ; ! 305: ! 306: unop: '&' ! 307: { $$ = ADDR_EXPR; } ! 308: | '-' ! 309: { $$ = NEGATE_EXPR; } ! 310: | '+' ! 311: { $$ = CONVERT_EXPR; } ! 312: | PLUSPLUS ! 313: { $$ = PREINCREMENT_EXPR; } ! 314: | MINUSMINUS ! 315: { $$ = PREDECREMENT_EXPR; } ! 316: | '~' ! 317: { $$ = BIT_NOT_EXPR; } ! 318: | '!' ! 319: { $$ = TRUTH_NOT_EXPR; } ! 320: ; ! 321: ! 322: expr: nonnull_exprlist ! 323: { $$ = build_compound_expr ($1); } ! 324: ; ! 325: ! 326: exprlist: ! 327: /* empty */ ! 328: { $$ = NULL_TREE; } ! 329: | nonnull_exprlist ! 330: ; ! 331: ! 332: nonnull_exprlist: ! 333: expr_no_commas ! 334: { $$ = build_tree_list (NULL_TREE, $1); } ! 335: | nonnull_exprlist ',' expr_no_commas ! 336: { chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 337: ; ! 338: ! 339: unary_expr: ! 340: primary ! 341: | '*' cast_expr %prec UNARY ! 342: { $$ = build_indirect_ref ($2, "unary *"); } ! 343: /* __extension__ turns off -pedantic for following primary. */ ! 344: | EXTENSION ! 345: { $<itype>1 = pedantic; ! 346: pedantic = 0; } ! 347: cast_expr %prec UNARY ! 348: { $$ = $3; ! 349: pedantic = $<itype>1; } ! 350: | unop cast_expr %prec UNARY ! 351: { $$ = build_unary_op ($1, $2, 0); } ! 352: /* Refer to the address of a label as a pointer. */ ! 353: | ANDAND identifier ! 354: { tree label = lookup_label ($2); ! 355: TREE_USED (label) = 1; ! 356: $$ = build1 (ADDR_EXPR, ptr_type_node, label); ! 357: TREE_CONSTANT ($$) = 1; } ! 358: /* This seems to be impossible on some machines, so let's turn it off. ! 359: | '&' ELLIPSIS ! 360: { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl)); ! 361: $$ = error_mark_node; ! 362: if (TREE_VALUE (tree_last (types)) == void_type_node) ! 363: error ("`&...' used in function with fixed number of arguments"); ! 364: else ! 365: { ! 366: if (pedantic) ! 367: pedwarn ("ANSI C forbids `&...'"); ! 368: $$ = tree_last (DECL_ARGUMENTS (current_function_decl)); ! 369: $$ = build_unary_op (ADDR_EXPR, $$, 0); ! 370: } } ! 371: */ ! 372: | SIZEOF unary_expr %prec UNARY ! 373: { if (TREE_CODE ($2) == COMPONENT_REF ! 374: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1))) ! 375: error ("`sizeof' applied to a bit-field"); ! 376: $$ = c_sizeof (TREE_TYPE ($2)); } ! 377: | SIZEOF '(' typename ')' %prec HYPERUNARY ! 378: { $$ = c_sizeof (groktypename ($3)); } ! 379: | ALIGNOF unary_expr %prec UNARY ! 380: { $$ = c_alignof_expr ($2); } ! 381: | ALIGNOF '(' typename ')' %prec HYPERUNARY ! 382: { $$ = c_alignof (groktypename ($3)); } ! 383: ; ! 384: ! 385: cast_expr: ! 386: unary_expr ! 387: | '(' typename ')' cast_expr %prec UNARY ! 388: { tree type = groktypename ($2); ! 389: $$ = build_c_cast (type, $4); } ! 390: | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY ! 391: { tree type = groktypename ($2); ! 392: if (pedantic) ! 393: pedwarn ("ANSI C forbids constructor expressions"); ! 394: $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), 0, 0, 0); ! 395: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) ! 396: { ! 397: int failure = complete_array_type (type, $$, 1); ! 398: if (failure) ! 399: abort (); ! 400: } ! 401: } ! 402: ; ! 403: ! 404: expr_no_commas: ! 405: cast_expr ! 406: | expr_no_commas '+' expr_no_commas ! 407: { $$ = parser_build_binary_op ($2, $1, $3); } ! 408: | expr_no_commas '-' expr_no_commas ! 409: { $$ = parser_build_binary_op ($2, $1, $3); } ! 410: | expr_no_commas '*' expr_no_commas ! 411: { $$ = parser_build_binary_op ($2, $1, $3); } ! 412: | expr_no_commas '/' expr_no_commas ! 413: { $$ = parser_build_binary_op ($2, $1, $3); } ! 414: | expr_no_commas '%' expr_no_commas ! 415: { $$ = parser_build_binary_op ($2, $1, $3); } ! 416: | expr_no_commas LSHIFT expr_no_commas ! 417: { $$ = parser_build_binary_op ($2, $1, $3); } ! 418: | expr_no_commas RSHIFT expr_no_commas ! 419: { $$ = parser_build_binary_op ($2, $1, $3); } ! 420: | expr_no_commas ARITHCOMPARE expr_no_commas ! 421: { $$ = parser_build_binary_op ($2, $1, $3); } ! 422: | expr_no_commas EQCOMPARE expr_no_commas ! 423: { $$ = parser_build_binary_op ($2, $1, $3); } ! 424: | expr_no_commas '&' expr_no_commas ! 425: { $$ = parser_build_binary_op ($2, $1, $3); } ! 426: | expr_no_commas '|' expr_no_commas ! 427: { $$ = parser_build_binary_op ($2, $1, $3); } ! 428: | expr_no_commas '^' expr_no_commas ! 429: { $$ = parser_build_binary_op ($2, $1, $3); } ! 430: | expr_no_commas ANDAND expr_no_commas ! 431: { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); } ! 432: | expr_no_commas OROR expr_no_commas ! 433: { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); } ! 434: | expr_no_commas '?' xexpr ':' expr_no_commas ! 435: { $$ = build_conditional_expr ($1, $3, $5); } ! 436: | expr_no_commas '=' expr_no_commas ! 437: { $$ = build_modify_expr ($1, NOP_EXPR, $3); } ! 438: | expr_no_commas ASSIGN expr_no_commas ! 439: { $$ = build_modify_expr ($1, $2, $3); } ! 440: ; ! 441: ! 442: primary: ! 443: IDENTIFIER ! 444: { ! 445: tree context; ! 446: ! 447: $$ = lastiddecl; ! 448: if (!$$ || $$ == error_mark_node) ! 449: { ! 450: if (yychar == YYEMPTY) ! 451: yychar = YYLEX; ! 452: if (yychar == '(') ! 453: { ! 454: if (objc_receiver_context ! 455: && ! (objc_receiver_context ! 456: && strcmp (IDENTIFIER_POINTER ($1), "super"))) ! 457: /* we have a message to super */ ! 458: $$ = get_super_receiver (); ! 459: else if (objc_method_context ! 460: && is_ivar (objc_ivar_chain, $1)) ! 461: $$ = build_ivar_reference ($1); ! 462: else ! 463: { ! 464: /* Ordinary implicit function declaration. */ ! 465: $$ = implicitly_declare ($1); ! 466: assemble_external ($$); ! 467: TREE_USED ($$) = 1; ! 468: } ! 469: } ! 470: else if (current_function_decl == 0) ! 471: { ! 472: error ("`%s' undeclared, outside of functions", ! 473: IDENTIFIER_POINTER ($1)); ! 474: $$ = error_mark_node; ! 475: } ! 476: else ! 477: { ! 478: if (objc_receiver_context ! 479: && ! (objc_receiver_context ! 480: && strcmp (IDENTIFIER_POINTER ($1), "super"))) ! 481: /* we have a message to super */ ! 482: $$ = get_super_receiver (); ! 483: else if (objc_method_context ! 484: && is_ivar (objc_ivar_chain, $1)) ! 485: $$ = build_ivar_reference ($1); ! 486: else ! 487: { ! 488: if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node ! 489: || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl) ! 490: { ! 491: error ("`%s' undeclared (first use this function)", ! 492: IDENTIFIER_POINTER ($1)); ! 493: ! 494: if (! undeclared_variable_notice) ! 495: { ! 496: error ("(Each undeclared identifier is reported only once"); ! 497: error ("for each function it appears in.)"); ! 498: undeclared_variable_notice = 1; ! 499: } ! 500: } ! 501: $$ = error_mark_node; ! 502: /* Prevent repeated error messages. */ ! 503: IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node; ! 504: IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl; ! 505: } ! 506: } ! 507: } ! 508: else ! 509: { ! 510: if (! TREE_USED ($$)) ! 511: { ! 512: if (TREE_EXTERNAL ($$)) ! 513: assemble_external ($$); ! 514: TREE_USED ($$) = 1; ! 515: } ! 516: /* we have a definition - still check if iVariable */ ! 517: ! 518: if (!objc_receiver_context ! 519: || (objc_receiver_context ! 520: && strcmp (IDENTIFIER_POINTER ($1), "super"))) ! 521: { ! 522: if (objc_method_context ! 523: && is_ivar (objc_ivar_chain, $1)) ! 524: { ! 525: if (IDENTIFIER_LOCAL_VALUE ($1)) ! 526: warning ("local declaration of `%s' hides instance variable", ! 527: IDENTIFIER_POINTER ($1)); ! 528: else ! 529: $$ = build_ivar_reference ($1); ! 530: } ! 531: } ! 532: else /* we have a message to super */ ! 533: $$ = get_super_receiver (); ! 534: } ! 535: ! 536: if (TREE_CODE ($$) == CONST_DECL) ! 537: $$ = DECL_INITIAL ($$); ! 538: } ! 539: | CONSTANT ! 540: | string ! 541: { $$ = combine_strings ($1); } ! 542: | '(' expr ')' ! 543: { char class = TREE_CODE_CLASS (TREE_CODE ($2)); ! 544: if (class == 'e' || class == '1' ! 545: || class == '2' || class == '<') ! 546: C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK); ! 547: $$ = $2; } ! 548: | '(' error ')' ! 549: { $$ = error_mark_node; } ! 550: | '(' ! 551: { if (current_function_decl == 0) ! 552: { ! 553: error ("braced-group within expression allowed only inside a function"); ! 554: YYERROR; ! 555: } ! 556: /* We must force a BLOCK for this level ! 557: so that, if it is not expanded later, ! 558: there is a way to turn off the entire subtree of blocks ! 559: that are contained in it. */ ! 560: keep_next_level (); ! 561: push_label_level (); ! 562: $<ttype>$ = expand_start_stmt_expr (); } ! 563: compstmt ')' ! 564: { tree rtl_exp; ! 565: if (pedantic) ! 566: pedwarn ("ANSI C forbids braced-groups within expressions"); ! 567: pop_label_level (); ! 568: rtl_exp = expand_end_stmt_expr ($<ttype>2); ! 569: /* The statements have side effects, so the group does. */ ! 570: TREE_SIDE_EFFECTS (rtl_exp) = 1; ! 571: ! 572: /* Make a BIND_EXPR for the BLOCK already made. */ ! 573: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), ! 574: NULL_TREE, rtl_exp, $3); ! 575: } ! 576: | primary '(' exprlist ')' %prec '.' ! 577: { $$ = build_function_call ($1, $3); } ! 578: | primary '[' expr ']' %prec '.' ! 579: { $$ = build_array_ref ($1, $3); } ! 580: | primary '.' identifier ! 581: { ! 582: if (doing_objc_thang) ! 583: { ! 584: if (is_public ($1, $3)) ! 585: $$ = build_component_ref ($1, $3); ! 586: else ! 587: $$ = error_mark_node; ! 588: } ! 589: else ! 590: $$ = build_component_ref ($1, $3); ! 591: } ! 592: | primary POINTSAT identifier ! 593: { ! 594: tree anExpr = build_indirect_ref ($1, "->"); ! 595: ! 596: if (doing_objc_thang) ! 597: { ! 598: if (is_public (anExpr, $3)) ! 599: $$ = build_component_ref (anExpr, $3); ! 600: else ! 601: $$ = error_mark_node; ! 602: } ! 603: else ! 604: $$ = build_component_ref (anExpr, $3); ! 605: } ! 606: | primary PLUSPLUS ! 607: { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); } ! 608: | primary MINUSMINUS ! 609: { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); } ! 610: | objcmessageexpr ! 611: { $$ = build_message_expr ($1); } ! 612: | objcselectorexpr ! 613: { $$ = build_selector_expr ($1); } ! 614: | objcencodeexpr ! 615: { $$ = build_encode_expr ($1); } ! 616: ; ! 617: ! 618: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ ! 619: string: ! 620: STRING ! 621: | string STRING ! 622: { $$ = chainon ($1, $2); } ! 623: ; ! 624: ! 625: xdecls: ! 626: /* empty */ ! 627: | decls ! 628: | decls ELLIPSIS ! 629: /* ... is used here to indicate a varargs function. */ ! 630: { c_mark_varargs (); ! 631: if (pedantic) ! 632: pedwarn ("ANSI C does not permit use of `varargs.h'"); } ! 633: ; ! 634: ! 635: /* This combination which saves a lineno before a decl ! 636: is the normal thing to use, rather than decl itself. ! 637: This is to avoid shift/reduce conflicts in contexts ! 638: where statement labels are allowed. */ ! 639: lineno_decl: ! 640: save_filename save_lineno decl ! 641: { } ! 642: ; ! 643: ! 644: decls: ! 645: lineno_decl ! 646: | errstmt ! 647: | decls lineno_decl ! 648: | lineno_decl errstmt ! 649: ; ! 650: ! 651: /* records the type and storage class specs to use for processing ! 652: the declarators that follow. ! 653: Maintains a stack of outer-level values of current_declspecs, ! 654: for the sake of parm declarations nested in function declarators. */ ! 655: setspecs: /* empty */ ! 656: { $$ = suspend_momentary (); ! 657: pending_xref_error (); ! 658: declspec_stack = tree_cons (0, current_declspecs, ! 659: declspec_stack); ! 660: current_declspecs = $<ttype>0; } ! 661: ; ! 662: ! 663: decl: ! 664: typed_declspecs setspecs initdecls ';' ! 665: { current_declspecs = TREE_VALUE (declspec_stack); ! 666: declspec_stack = TREE_CHAIN (declspec_stack); ! 667: resume_momentary ($2); } ! 668: | declmods setspecs notype_initdecls ';' ! 669: { current_declspecs = TREE_VALUE (declspec_stack); ! 670: declspec_stack = TREE_CHAIN (declspec_stack); ! 671: resume_momentary ($2); } ! 672: | typed_declspecs setspecs nested_function ! 673: { current_declspecs = TREE_VALUE (declspec_stack); ! 674: declspec_stack = TREE_CHAIN (declspec_stack); ! 675: resume_momentary ($2); } ! 676: | declmods setspecs notype_nested_function ! 677: { current_declspecs = TREE_VALUE (declspec_stack); ! 678: declspec_stack = TREE_CHAIN (declspec_stack); ! 679: resume_momentary ($2); } ! 680: | typed_declspecs ';' ! 681: { shadow_tag ($1); } ! 682: | declmods ';' ! 683: { pedwarn ("empty declaration"); } ! 684: ; ! 685: ! 686: /* Declspecs which contain at least one type specifier or typedef name. ! 687: (Just `const' or `volatile' is not enough.) ! 688: A typedef'd name following these is taken as a name to be declared. */ ! 689: ! 690: typed_declspecs: ! 691: typespec reserved_declspecs ! 692: { $$ = tree_cons (NULL_TREE, $1, $2); } ! 693: | declmods typespec reserved_declspecs ! 694: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ! 695: ; ! 696: ! 697: reserved_declspecs: /* empty */ ! 698: { $$ = NULL_TREE; } ! 699: | reserved_declspecs typespecqual_reserved ! 700: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 701: | reserved_declspecs SCSPEC ! 702: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 703: ; ! 704: ! 705: /* List of just storage classes and type modifiers. ! 706: A declaration can start with just this, but then it cannot be used ! 707: to redeclare a typedef-name. */ ! 708: ! 709: declmods: ! 710: TYPE_QUAL ! 711: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 712: | SCSPEC ! 713: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 714: | declmods TYPE_QUAL ! 715: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 716: | declmods SCSPEC ! 717: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 718: ; ! 719: ! 720: ! 721: /* Used instead of declspecs where storage classes are not allowed ! 722: (that is, for typenames and structure components). ! 723: Don't accept a typedef-name if anything but a modifier precedes it. */ ! 724: ! 725: typed_typespecs: ! 726: typespec reserved_typespecquals ! 727: { $$ = tree_cons (NULL_TREE, $1, $2); } ! 728: | nonempty_type_quals typespec reserved_typespecquals ! 729: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); } ! 730: ; ! 731: ! 732: reserved_typespecquals: /* empty */ ! 733: { $$ = NULL_TREE; } ! 734: | reserved_typespecquals typespecqual_reserved ! 735: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 736: ; ! 737: ! 738: /* A typespec (but not a type qualifier). ! 739: Once we have seen one of these in a declaration, ! 740: if a typedef name appears then it is being redeclared. */ ! 741: ! 742: typespec: TYPESPEC ! 743: | structsp ! 744: | TYPENAME ! 745: | CLASSNAME ! 746: { $$ = get_static_reference ($1); } ! 747: | TYPEOF '(' expr ')' ! 748: { $$ = TREE_TYPE ($3); ! 749: if (pedantic) ! 750: pedwarn ("ANSI C forbids `typeof'"); } ! 751: | TYPEOF '(' typename ')' ! 752: { $$ = groktypename ($3); ! 753: if (pedantic) ! 754: pedwarn ("ANSI C forbids `typeof'"); } ! 755: ; ! 756: ! 757: /* A typespec that is a reserved word, or a type qualifier. */ ! 758: ! 759: typespecqual_reserved: TYPESPEC ! 760: | TYPE_QUAL ! 761: | structsp ! 762: ; ! 763: ! 764: initdecls: ! 765: initdcl ! 766: | initdecls ',' initdcl ! 767: ; ! 768: ! 769: notype_initdecls: ! 770: notype_initdcl ! 771: | notype_initdecls ',' initdcl ! 772: ; ! 773: ! 774: maybeasm: ! 775: /* empty */ ! 776: { $$ = NULL_TREE; } ! 777: | ASM '(' string ')' ! 778: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 779: $$ = $3; ! 780: if (pedantic) ! 781: pedwarn ("ANSI C forbids use of `asm' keyword"); ! 782: } ! 783: ; ! 784: ! 785: initdcl: ! 786: declarator maybeasm maybe_attribute '=' ! 787: { $<ttype>$ = start_decl ($1, current_declspecs, 1); } ! 788: init ! 789: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 790: { decl_attributes ($<ttype>5, $3); ! 791: finish_decl ($<ttype>5, $6, $2); } ! 792: | declarator maybeasm maybe_attribute ! 793: { tree d = start_decl ($1, current_declspecs, 0); ! 794: decl_attributes (d, $3); ! 795: finish_decl (d, NULL_TREE, $2); } ! 796: ; ! 797: ! 798: notype_initdcl: ! 799: notype_declarator maybeasm maybe_attribute '=' ! 800: { $<ttype>$ = start_decl ($1, current_declspecs, 1); } ! 801: init ! 802: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 803: { decl_attributes ($<ttype>5, $3); ! 804: finish_decl ($<ttype>5, $6, $2); } ! 805: | notype_declarator maybeasm maybe_attribute ! 806: { tree d = start_decl ($1, current_declspecs, 0); ! 807: decl_attributes (d, $3); ! 808: finish_decl (d, NULL_TREE, $2); } ! 809: ; ! 810: /* the * rules are dummies to accept the Apollo extended syntax ! 811: so that the header files compile. */ ! 812: maybe_attribute: ! 813: /* empty */ ! 814: { $$ = NULL_TREE; } ! 815: | ATTRIBUTE '(' '(' attribute_list ')' ')' ! 816: { $$ = $4; } ! 817: ; ! 818: ! 819: attribute_list ! 820: : attrib ! 821: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 822: | attribute_list ',' attrib ! 823: { $$ = tree_cons (NULL_TREE, $3, $1); } ! 824: ; ! 825: ! 826: attrib ! 827: : IDENTIFIER ! 828: { warning ("`%s' attribute directive ignored", ! 829: IDENTIFIER_POINTER ($1)); ! 830: $$ = $1; } ! 831: | IDENTIFIER '(' CONSTANT ')' ! 832: { /* if not "aligned(n)", then issue warning */ ! 833: if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0 ! 834: || TREE_CODE ($3) != INTEGER_CST) ! 835: { ! 836: warning ("`%s' attribute directive ignored", ! 837: IDENTIFIER_POINTER ($1)); ! 838: $$ = $1; ! 839: } ! 840: else ! 841: $$ = tree_cons ($1, $3); } ! 842: | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')' ! 843: { /* if not "format(...)", then issue warning */ ! 844: if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0 ! 845: || TREE_CODE ($5) != INTEGER_CST ! 846: || TREE_CODE ($7) != INTEGER_CST) ! 847: { ! 848: warning ("`%s' attribute directive ignored", ! 849: IDENTIFIER_POINTER ($1)); ! 850: $$ = $1; ! 851: } ! 852: else ! 853: $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7))); } ! 854: ; ! 855: ! 856: init: ! 857: expr_no_commas ! 858: | '{' '}' ! 859: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); ! 860: if (pedantic) ! 861: pedwarn ("ANSI C forbids empty initializer braces"); } ! 862: | '{' initlist '}' ! 863: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); } ! 864: | '{' initlist ',' '}' ! 865: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); } ! 866: | error ! 867: { $$ = NULL_TREE; } ! 868: ; ! 869: ! 870: /* This chain is built in reverse order, ! 871: and put in forward order where initlist is used. */ ! 872: initlist: ! 873: init ! 874: { $$ = build_tree_list (NULL_TREE, $1); } ! 875: | initlist ',' init ! 876: { $$ = tree_cons (NULL_TREE, $3, $1); } ! 877: /* These are for labeled elements. */ ! 878: | '[' expr_no_commas ']' init ! 879: { $$ = build_tree_list ($2, $4); } ! 880: | initlist ',' CASE expr_no_commas ':' init ! 881: { $$ = tree_cons ($4, $6, $1); } ! 882: | identifier ':' init ! 883: { $$ = build_tree_list ($1, $3); } ! 884: | initlist ',' identifier ':' init ! 885: { $$ = tree_cons ($3, $5, $1); } ! 886: ; ! 887: ! 888: nested_function: ! 889: declarator ! 890: { push_c_function_context (); ! 891: if (! start_function (current_declspecs, $1, 1)) ! 892: { ! 893: pop_c_function_context (); ! 894: YYERROR1; ! 895: } ! 896: reinit_parse_for_function (); ! 897: store_parm_decls (); } ! 898: /* This used to use compstmt_or_error. ! 899: That caused a bug with input `f(g) int g {}', ! 900: where the use of YYERROR1 above caused an error ! 901: which then was handled by compstmt_or_error. ! 902: There followed a repeated execution of that same rule, ! 903: which called YYERROR1 again, and so on. */ ! 904: compstmt ! 905: { finish_function (1); ! 906: pop_c_function_context (); } ! 907: ; ! 908: ! 909: notype_nested_function: ! 910: notype_declarator ! 911: { push_c_function_context (); ! 912: if (! start_function (current_declspecs, $1, 1)) ! 913: { ! 914: pop_c_function_context (); ! 915: YYERROR1; ! 916: } ! 917: reinit_parse_for_function (); ! 918: store_parm_decls (); } ! 919: /* This used to use compstmt_or_error. ! 920: That caused a bug with input `f(g) int g {}', ! 921: where the use of YYERROR1 above caused an error ! 922: which then was handled by compstmt_or_error. ! 923: There followed a repeated execution of that same rule, ! 924: which called YYERROR1 again, and so on. */ ! 925: compstmt ! 926: { finish_function (1); ! 927: pop_c_function_context (); } ! 928: ; ! 929: ! 930: /* Any kind of declarator (thus, all declarators allowed ! 931: after an explicit typespec). */ ! 932: ! 933: declarator: ! 934: after_type_declarator ! 935: | notype_declarator ! 936: ; ! 937: ! 938: /* A declarator that is allowed only after an explicit typespec. */ ! 939: ! 940: after_type_declarator: ! 941: '(' after_type_declarator ')' ! 942: { $$ = $2; } ! 943: | after_type_declarator '(' parmlist_or_identifiers %prec '.' ! 944: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 945: /* | after_type_declarator '(' error ')' %prec '.' ! 946: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 947: poplevel (0, 0, 0); } */ ! 948: | after_type_declarator '[' expr ']' %prec '.' ! 949: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 950: | after_type_declarator '[' ']' %prec '.' ! 951: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 952: | '*' type_quals after_type_declarator %prec UNARY ! 953: { $$ = make_pointer_declarator ($2, $3); } ! 954: | TYPENAME ! 955: ; ! 956: ! 957: /* Kinds of declarator that can appear in a parameter list ! 958: in addition to notype_declarator. This is like after_type_declarator ! 959: but does not allow a typedef name in parentheses as an identifier ! 960: (because it would conflict with a function with that typedef as arg). */ ! 961: ! 962: parm_declarator: ! 963: parm_declarator '(' parmlist_or_identifiers %prec '.' ! 964: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 965: /* | parm_declarator '(' error ')' %prec '.' ! 966: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 967: poplevel (0, 0, 0); } */ ! 968: | parm_declarator '[' expr ']' %prec '.' ! 969: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 970: | parm_declarator '[' ']' %prec '.' ! 971: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 972: | '*' type_quals parm_declarator %prec UNARY ! 973: { $$ = make_pointer_declarator ($2, $3); } ! 974: | TYPENAME ! 975: ; ! 976: ! 977: /* A declarator allowed whether or not there has been ! 978: an explicit typespec. These cannot redeclare a typedef-name. */ ! 979: ! 980: notype_declarator: ! 981: notype_declarator '(' parmlist_or_identifiers %prec '.' ! 982: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 983: /* | notype_declarator '(' error ')' %prec '.' ! 984: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); ! 985: poplevel (0, 0, 0); } */ ! 986: | '(' notype_declarator ')' ! 987: { $$ = $2; } ! 988: | '*' type_quals notype_declarator %prec UNARY ! 989: { $$ = make_pointer_declarator ($2, $3); } ! 990: | notype_declarator '[' expr ']' %prec '.' ! 991: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 992: | notype_declarator '[' ']' %prec '.' ! 993: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 994: | IDENTIFIER ! 995: ; ! 996: ! 997: structsp: ! 998: STRUCT identifier '{' ! 999: { $$ = start_struct (RECORD_TYPE, $2); ! 1000: /* Start scope of tag before parsing components. */ ! 1001: } ! 1002: component_decl_list '}' ! 1003: { $$ = finish_struct ($<ttype>4, $5); ! 1004: /* Really define the structure. */ ! 1005: } ! 1006: | STRUCT '{' component_decl_list '}' ! 1007: { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), ! 1008: $3); } ! 1009: | STRUCT identifier ! 1010: { $$ = xref_tag (RECORD_TYPE, $2); } ! 1011: | UNION identifier '{' ! 1012: { $$ = start_struct (UNION_TYPE, $2); } ! 1013: component_decl_list '}' ! 1014: { $$ = finish_struct ($<ttype>4, $5); } ! 1015: | UNION '{' component_decl_list '}' ! 1016: { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE), ! 1017: $3); } ! 1018: | UNION identifier ! 1019: { $$ = xref_tag (UNION_TYPE, $2); } ! 1020: | ENUM identifier '{' ! 1021: { $<itype>3 = suspend_momentary (); ! 1022: $$ = start_enum ($2); } ! 1023: enumlist maybecomma_warn '}' ! 1024: { $$ = finish_enum ($<ttype>4, nreverse ($5)); ! 1025: resume_momentary ($<itype>3); } ! 1026: | ENUM '{' ! 1027: { $<itype>2 = suspend_momentary (); ! 1028: $$ = start_enum (NULL_TREE); } ! 1029: enumlist maybecomma_warn '}' ! 1030: { $$ = finish_enum ($<ttype>3, nreverse ($4)); ! 1031: resume_momentary ($<itype>2); } ! 1032: | ENUM identifier ! 1033: { $$ = xref_tag (ENUMERAL_TYPE, $2); } ! 1034: ; ! 1035: ! 1036: maybecomma: ! 1037: /* empty */ ! 1038: | ',' ! 1039: ; ! 1040: ! 1041: maybecomma_warn: ! 1042: /* empty */ ! 1043: | ',' ! 1044: { if (pedantic) pedwarn ("comma at end of enumerator list"); } ! 1045: ; ! 1046: ! 1047: component_decl_list: ! 1048: component_decl_list2 ! 1049: { $$ = $1; } ! 1050: | component_decl_list2 component_decl ! 1051: { $$ = chainon ($1, $2); ! 1052: warning ("no semicolon at end of struct or union"); } ! 1053: ; ! 1054: ! 1055: component_decl_list2: /* empty */ ! 1056: { $$ = NULL_TREE; } ! 1057: | component_decl_list2 component_decl ';' ! 1058: { $$ = chainon ($1, $2); } ! 1059: | component_decl_list2 ';' ! 1060: { if (pedantic) ! 1061: warning ("extra semicolon in struct or union specified"); } ! 1062: /* foo(sizeof(struct{ @defs(ClassName)})); */ ! 1063: | DEFS '(' CLASSNAME ')' ! 1064: { $$ = get_class_ivars ($3); } ! 1065: ; ! 1066: ! 1067: /* There is a shift-reduce conflict here, because `components' may ! 1068: start with a `typename'. It happens that shifting (the default resolution) ! 1069: does the right thing, because it treats the `typename' as part of ! 1070: a `typed_typespecs'. ! 1071: ! 1072: It is possible that this same technique would allow the distinction ! 1073: between `notype_initdecls' and `initdecls' to be eliminated. ! 1074: But I am being cautious and not trying it. */ ! 1075: ! 1076: component_decl: ! 1077: typed_typespecs setspecs components ! 1078: { $$ = $3; ! 1079: current_declspecs = TREE_VALUE (declspec_stack); ! 1080: declspec_stack = TREE_CHAIN (declspec_stack); ! 1081: resume_momentary ($2); } ! 1082: | typed_typespecs ! 1083: { if (pedantic) ! 1084: pedwarn ("ANSI C forbids member declarations with no members"); ! 1085: shadow_tag($1); ! 1086: $$ = NULL_TREE; } ! 1087: | nonempty_type_quals setspecs components ! 1088: { $$ = $3; ! 1089: current_declspecs = TREE_VALUE (declspec_stack); ! 1090: declspec_stack = TREE_CHAIN (declspec_stack); ! 1091: resume_momentary ($2); } ! 1092: | nonempty_type_quals ! 1093: { if (pedantic) ! 1094: pedwarn ("ANSI C forbids member declarations with no members"); ! 1095: shadow_tag($1); ! 1096: $$ = NULL_TREE; } ! 1097: | error ! 1098: { $$ = NULL_TREE; } ! 1099: ; ! 1100: ! 1101: components: ! 1102: component_declarator ! 1103: | components ',' component_declarator ! 1104: { $$ = chainon ($1, $3); } ! 1105: ; ! 1106: ! 1107: component_declarator: ! 1108: save_filename save_lineno declarator maybe_attribute ! 1109: { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE); ! 1110: decl_attributes ($$, $4); } ! 1111: | save_filename save_lineno ! 1112: declarator ':' expr_no_commas maybe_attribute ! 1113: { $$ = grokfield ($1, $2, $3, current_declspecs, $5); ! 1114: decl_attributes ($$, $6); } ! 1115: | save_filename save_lineno ':' expr_no_commas ! 1116: { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); } ! 1117: ; ! 1118: ! 1119: /* We chain the enumerators in reverse order. ! 1120: They are put in forward order where enumlist is used. ! 1121: (The order used to be significant, but no longer is so. ! 1122: However, we still maintain the order, just to be clean.) */ ! 1123: ! 1124: enumlist: ! 1125: enumerator ! 1126: | enumlist ',' enumerator ! 1127: { $$ = chainon ($3, $1); } ! 1128: ; ! 1129: ! 1130: ! 1131: enumerator: ! 1132: identifier ! 1133: { $$ = build_enumerator ($1, NULL_TREE); } ! 1134: | identifier '=' expr_no_commas ! 1135: { $$ = build_enumerator ($1, $3); } ! 1136: ; ! 1137: ! 1138: typename: ! 1139: typed_typespecs absdcl ! 1140: { $$ = build_tree_list ($1, $2); } ! 1141: | nonempty_type_quals absdcl ! 1142: { $$ = build_tree_list ($1, $2); } ! 1143: ; ! 1144: ! 1145: absdcl: /* an absolute declarator */ ! 1146: /* empty */ ! 1147: { $$ = NULL_TREE; } ! 1148: | absdcl1 ! 1149: ; ! 1150: ! 1151: nonempty_type_quals: ! 1152: TYPE_QUAL ! 1153: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 1154: | nonempty_type_quals TYPE_QUAL ! 1155: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 1156: ; ! 1157: ! 1158: type_quals: ! 1159: /* empty */ ! 1160: { $$ = NULL_TREE; } ! 1161: | type_quals TYPE_QUAL ! 1162: { $$ = tree_cons (NULL_TREE, $2, $1); } ! 1163: ; ! 1164: ! 1165: absdcl1: /* a nonempty absolute declarator */ ! 1166: '(' absdcl1 ')' ! 1167: { $$ = $2; } ! 1168: /* `(typedef)1' is `int'. */ ! 1169: | '*' type_quals absdcl1 %prec UNARY ! 1170: { $$ = make_pointer_declarator ($2, $3); } ! 1171: | '*' type_quals %prec UNARY ! 1172: { $$ = make_pointer_declarator ($2, NULL_TREE); } ! 1173: | absdcl1 '(' parmlist %prec '.' ! 1174: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } ! 1175: | absdcl1 '[' expr ']' %prec '.' ! 1176: { $$ = build_nt (ARRAY_REF, $1, $3); } ! 1177: | absdcl1 '[' ']' %prec '.' ! 1178: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); } ! 1179: | '(' parmlist %prec '.' ! 1180: { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); } ! 1181: | '[' expr ']' %prec '.' ! 1182: { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); } ! 1183: | '[' ']' %prec '.' ! 1184: { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); } ! 1185: ; ! 1186: ! 1187: /* at least one statement, the first of which parses without error. */ ! 1188: /* stmts is used only after decls, so an invalid first statement ! 1189: is actually regarded as an invalid decl and part of the decls. */ ! 1190: ! 1191: stmts: ! 1192: lineno_stmt ! 1193: | stmts lineno_stmt ! 1194: | stmts errstmt ! 1195: ; ! 1196: ! 1197: xstmts: ! 1198: /* empty */ ! 1199: | stmts ! 1200: ; ! 1201: ! 1202: errstmt: error ';' ! 1203: ; ! 1204: ! 1205: pushlevel: /* empty */ ! 1206: { emit_line_note (input_filename, lineno); ! 1207: pushlevel (0); ! 1208: clear_last_expr (); ! 1209: push_momentary (); ! 1210: expand_start_bindings (0); ! 1211: if (objc_method_context) ! 1212: add_objc_decls (); } ! 1213: ; ! 1214: ! 1215: /* Read zero or more forward-declarations for labels ! 1216: that nested functions can jump to. */ ! 1217: maybe_label_decls: ! 1218: /* empty */ ! 1219: | label_decls ! 1220: { if (pedantic) ! 1221: pedwarn ("ANSI C forbids label declarations"); } ! 1222: ; ! 1223: ! 1224: label_decls: ! 1225: label_decl ! 1226: | label_decls label_decl ! 1227: ; ! 1228: ! 1229: label_decl: ! 1230: LABEL identifiers ';' ! 1231: { tree link; ! 1232: for (link = $2; link; link = TREE_CHAIN (link)) ! 1233: { ! 1234: tree label = shadow_label (TREE_VALUE (link)); ! 1235: C_DECLARED_LABEL_FLAG (label) = 1; ! 1236: declare_nonlocal_label (label); ! 1237: } ! 1238: } ! 1239: ; ! 1240: ! 1241: /* This is the body of a function definition. ! 1242: It causes syntax errors to ignore to the next openbrace. */ ! 1243: ! 1244: /* allow for: main () { Example *anObject = [Example new]; } */ ! 1245: ! 1246: compstmt_or_error: ! 1247: compstmt ! 1248: {} ! 1249: | error compstmt ! 1250: ; ! 1251: ! 1252: compstmt: '{' '}' ! 1253: { $$ = convert (void_type_node, integer_zero_node); } ! 1254: | '{' pushlevel maybe_label_decls decls xstmts '}' ! 1255: { emit_line_note (input_filename, lineno); ! 1256: expand_end_bindings (getdecls (), 1, 0); ! 1257: $$ = poplevel (1, 1, 0); ! 1258: pop_momentary (); } ! 1259: | '{' pushlevel maybe_label_decls error '}' ! 1260: { emit_line_note (input_filename, lineno); ! 1261: expand_end_bindings (getdecls (), kept_level_p (), 0); ! 1262: $$ = poplevel (kept_level_p (), 0, 0); ! 1263: pop_momentary (); } ! 1264: | '{' pushlevel maybe_label_decls stmts '}' ! 1265: { emit_line_note (input_filename, lineno); ! 1266: expand_end_bindings (getdecls (), kept_level_p (), 0); ! 1267: $$ = poplevel (kept_level_p (), 0, 0); ! 1268: pop_momentary (); } ! 1269: ; ! 1270: ! 1271: /* Value is number of statements counted as of the closeparen. */ ! 1272: simple_if: ! 1273: IF '(' expr ')' ! 1274: { emit_line_note ($<filename>-1, $<lineno>0); ! 1275: expand_start_cond (truthvalue_conversion ($3), 0); ! 1276: $<itype>1 = stmt_count; ! 1277: if_stmt_file = $<filename>-1; ! 1278: if_stmt_line = $<lineno>0; ! 1279: position_after_white_space (); } ! 1280: lineno_stmt ! 1281: ; ! 1282: ! 1283: save_filename: ! 1284: { $$ = input_filename; } ! 1285: ; ! 1286: ! 1287: save_lineno: ! 1288: { $$ = lineno; } ! 1289: ; ! 1290: ! 1291: lineno_stmt: ! 1292: save_filename save_lineno stmt ! 1293: { } ! 1294: ; ! 1295: ! 1296: stmt: ! 1297: compstmt ! 1298: { stmt_count++; } ! 1299: | expr ';' ! 1300: { stmt_count++; ! 1301: emit_line_note ($<filename>-1, $<lineno>0); ! 1302: c_expand_expr_stmt ($1); ! 1303: clear_momentary (); } ! 1304: | simple_if ELSE ! 1305: { expand_start_else (); ! 1306: $<itype>1 = stmt_count; ! 1307: position_after_white_space (); } ! 1308: lineno_stmt ! 1309: { expand_end_cond (); ! 1310: if (extra_warnings && stmt_count == $<itype>1) ! 1311: warning ("empty body in an else-statement"); } ! 1312: | simple_if %prec IF ! 1313: { expand_end_cond (); ! 1314: if (extra_warnings && stmt_count == $<itype>1) ! 1315: warning_with_file_and_line (if_stmt_file, if_stmt_line, ! 1316: "empty body in an if-statement"); } ! 1317: | WHILE ! 1318: { emit_nop (); ! 1319: stmt_count++; ! 1320: emit_line_note ($<filename>-1, $<lineno>0); ! 1321: expand_start_loop (1); } ! 1322: '(' expr ')' ! 1323: { emit_line_note (input_filename, lineno); ! 1324: expand_exit_loop_if_false (0, truthvalue_conversion ($4)); ! 1325: position_after_white_space (); } ! 1326: lineno_stmt ! 1327: { expand_end_loop (); } ! 1328: | DO ! 1329: { emit_nop (); ! 1330: stmt_count++; ! 1331: emit_line_note ($<filename>-1, $<lineno>0); ! 1332: expand_start_loop_continue_elsewhere (1); ! 1333: position_after_white_space (); } ! 1334: lineno_stmt WHILE ! 1335: { expand_loop_continue_here (); } ! 1336: '(' expr ')' ';' ! 1337: { emit_line_note (input_filename, lineno); ! 1338: expand_exit_loop_if_false (0, truthvalue_conversion ($7)); ! 1339: expand_end_loop (); ! 1340: clear_momentary (); } ! 1341: | FOR ! 1342: '(' xexpr ';' ! 1343: { emit_nop (); ! 1344: stmt_count++; ! 1345: emit_line_note ($<filename>-1, $<lineno>0); ! 1346: if ($3) c_expand_expr_stmt ($3); ! 1347: expand_start_loop_continue_elsewhere (1); } ! 1348: xexpr ';' ! 1349: { emit_line_note (input_filename, lineno); ! 1350: if ($6) ! 1351: expand_exit_loop_if_false (0, truthvalue_conversion ($6)); } ! 1352: xexpr ')' ! 1353: /* Don't let the tree nodes for $9 be discarded ! 1354: by clear_momentary during the parsing of the next stmt. */ ! 1355: { push_momentary (); ! 1356: position_after_white_space (); } ! 1357: lineno_stmt ! 1358: { emit_line_note ($<filename>-1, $<lineno>0); ! 1359: expand_loop_continue_here (); ! 1360: if ($9) ! 1361: c_expand_expr_stmt ($9); ! 1362: pop_momentary (); ! 1363: expand_end_loop (); } ! 1364: | SWITCH '(' expr ')' ! 1365: { stmt_count++; ! 1366: emit_line_note ($<filename>-1, $<lineno>0); ! 1367: c_expand_start_case ($3); ! 1368: /* Don't let the tree nodes for $3 be discarded by ! 1369: clear_momentary during the parsing of the next stmt. */ ! 1370: push_momentary (); ! 1371: position_after_white_space (); } ! 1372: lineno_stmt ! 1373: { expand_end_case ($3); ! 1374: pop_momentary (); } ! 1375: | CASE expr ':' ! 1376: { register tree value = check_case_value ($2); ! 1377: register tree label ! 1378: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 1379: ! 1380: stmt_count++; ! 1381: ! 1382: if (value != error_mark_node) ! 1383: { ! 1384: tree duplicate; ! 1385: int success = pushcase (value, label, &duplicate); ! 1386: if (success == 1) ! 1387: error ("case label not within a switch statement"); ! 1388: else if (success == 2) ! 1389: { ! 1390: error ("duplicate case value"); ! 1391: error_with_decl (duplicate, "this is the first entry for that value"); ! 1392: } ! 1393: else if (success == 3) ! 1394: warning ("case value out of range"); ! 1395: else if (success == 5) ! 1396: error ("case label within scope of cleanup or variable array"); ! 1397: } ! 1398: position_after_white_space (); } ! 1399: lineno_stmt ! 1400: | CASE expr ELLIPSIS expr ':' ! 1401: { register tree value1 = check_case_value ($2); ! 1402: register tree value2 = check_case_value ($4); ! 1403: register tree label ! 1404: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 1405: ! 1406: stmt_count++; ! 1407: ! 1408: if (value1 != error_mark_node && value2 != error_mark_node) ! 1409: { ! 1410: tree duplicate; ! 1411: int success = pushcase_range (value1, value2, label, ! 1412: &duplicate); ! 1413: if (success == 1) ! 1414: error ("case label not within a switch statement"); ! 1415: else if (success == 2) ! 1416: { ! 1417: error ("duplicate case value"); ! 1418: error_with_decl (duplicate, "this is the first entry overlapping that value"); ! 1419: } ! 1420: else if (success == 3) ! 1421: warning ("case value out of range"); ! 1422: else if (success == 4) ! 1423: warning ("empty case range"); ! 1424: else if (success == 5) ! 1425: error ("case label within scope of cleanup or variable array"); ! 1426: } ! 1427: position_after_white_space (); } ! 1428: lineno_stmt ! 1429: | DEFAULT ':' ! 1430: { ! 1431: tree duplicate; ! 1432: register tree label ! 1433: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 1434: int success = pushcase (NULL_TREE, label, &duplicate); ! 1435: stmt_count++; ! 1436: if (success == 1) ! 1437: error ("default label not within a switch statement"); ! 1438: else if (success == 2) ! 1439: { ! 1440: error ("multiple default labels in one switch"); ! 1441: error_with_decl (duplicate, "this is the first default albel"); ! 1442: } ! 1443: position_after_white_space (); } ! 1444: lineno_stmt ! 1445: | BREAK ';' ! 1446: { stmt_count++; ! 1447: emit_line_note ($<filename>-1, $<lineno>0); ! 1448: if ( ! expand_exit_something ()) ! 1449: error ("break statement not within loop or switch"); } ! 1450: | CONTINUE ';' ! 1451: { stmt_count++; ! 1452: emit_line_note ($<filename>-1, $<lineno>0); ! 1453: if (! expand_continue_loop (0)) ! 1454: error ("continue statement not within a loop"); } ! 1455: | RETURN ';' ! 1456: { stmt_count++; ! 1457: emit_line_note ($<filename>-1, $<lineno>0); ! 1458: c_expand_return (NULL_TREE); } ! 1459: | RETURN expr ';' ! 1460: { stmt_count++; ! 1461: emit_line_note ($<filename>-1, $<lineno>0); ! 1462: c_expand_return ($2); } ! 1463: | ASM maybe_type_qual '(' string ')' ';' ! 1464: { stmt_count++; ! 1465: emit_line_note ($<filename>-1, $<lineno>0); ! 1466: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 1467: expand_asm ($4); } ! 1468: /* This is the case with just output operands. */ ! 1469: | ASM maybe_type_qual '(' string ':' asm_operands ')' ';' ! 1470: { stmt_count++; ! 1471: emit_line_note ($<filename>-1, $<lineno>0); ! 1472: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 1473: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE, ! 1474: $2 == ridpointers[(int)RID_VOLATILE], ! 1475: input_filename, lineno); } ! 1476: /* This is the case with input operands as well. */ ! 1477: | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';' ! 1478: { stmt_count++; ! 1479: emit_line_note ($<filename>-1, $<lineno>0); ! 1480: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 1481: c_expand_asm_operands ($4, $6, $8, NULL_TREE, ! 1482: $2 == ridpointers[(int)RID_VOLATILE], ! 1483: input_filename, lineno); } ! 1484: /* This is the case with clobbered registers as well. */ ! 1485: | ASM maybe_type_qual '(' string ':' asm_operands ':' ! 1486: asm_operands ':' asm_clobbers ')' ';' ! 1487: { stmt_count++; ! 1488: emit_line_note ($<filename>-1, $<lineno>0); ! 1489: if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 1490: c_expand_asm_operands ($4, $6, $8, $10, ! 1491: $2 == ridpointers[(int)RID_VOLATILE], ! 1492: input_filename, lineno); } ! 1493: | GOTO identifier ';' ! 1494: { tree decl; ! 1495: stmt_count++; ! 1496: emit_line_note ($<filename>-1, $<lineno>0); ! 1497: decl = lookup_label ($2); ! 1498: if (decl != 0) ! 1499: { ! 1500: TREE_USED (decl) = 1; ! 1501: expand_goto (decl); ! 1502: } ! 1503: } ! 1504: | GOTO '*' expr ';' ! 1505: { stmt_count++; ! 1506: emit_line_note ($<filename>-1, $<lineno>0); ! 1507: expand_computed_goto ($3); } ! 1508: | identifier ':' ! 1509: { tree label = define_label (input_filename, lineno, $1); ! 1510: stmt_count++; ! 1511: emit_nop (); ! 1512: if (label) ! 1513: expand_label (label); ! 1514: position_after_white_space (); } ! 1515: lineno_stmt ! 1516: | ';' ! 1517: ; ! 1518: ! 1519: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ ! 1520: ! 1521: maybe_type_qual: ! 1522: /* empty */ ! 1523: { if (pedantic) ! 1524: pedwarn ("ANSI C forbids use of `asm' keyword"); ! 1525: emit_line_note (input_filename, lineno); } ! 1526: | TYPE_QUAL ! 1527: { if (pedantic) ! 1528: pedwarn ("ANSI C forbids use of `asm' keyword"); ! 1529: emit_line_note (input_filename, lineno); } ! 1530: ; ! 1531: ! 1532: xexpr: ! 1533: /* empty */ ! 1534: { $$ = NULL_TREE; } ! 1535: | expr ! 1536: ; ! 1537: ! 1538: /* These are the operands other than the first string and colon ! 1539: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ ! 1540: asm_operands: /* empty */ ! 1541: { $$ = NULL_TREE; } ! 1542: | nonnull_asm_operands ! 1543: ; ! 1544: ! 1545: nonnull_asm_operands: ! 1546: asm_operand ! 1547: | nonnull_asm_operands ',' asm_operand ! 1548: { $$ = chainon ($1, $3); } ! 1549: ; ! 1550: ! 1551: asm_operand: ! 1552: STRING '(' expr ')' ! 1553: { $$ = build_tree_list ($1, $3); } ! 1554: ; ! 1555: ! 1556: asm_clobbers: ! 1557: string ! 1558: { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); } ! 1559: | asm_clobbers ',' string ! 1560: { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); } ! 1561: ; ! 1562: ! 1563: /* This is what appears inside the parens in a function declarator. ! 1564: Its value is a list of ..._TYPE nodes. */ ! 1565: parmlist: ! 1566: { pushlevel (0); ! 1567: declare_parm_level (0); } ! 1568: parmlist_1 ! 1569: { $$ = $2; ! 1570: parmlist_tags_warning (); ! 1571: poplevel (0, 0, 0); } ! 1572: ; ! 1573: ! 1574: /* This is referred to where either a parmlist or an identifier list is ok. ! 1575: Its value is a list of ..._TYPE nodes or a list of identifiers. */ ! 1576: parmlist_or_identifiers: ! 1577: { pushlevel (0); ! 1578: declare_parm_level (1); } ! 1579: parmlist_or_identifiers_1 ! 1580: { $$ = $2; ! 1581: parmlist_tags_warning (); ! 1582: poplevel (0, 0, 0); } ! 1583: ; ! 1584: ! 1585: parmlist_or_identifiers_1: ! 1586: parmlist_2 ')' ! 1587: | identifiers ')' ! 1588: { $$ = tree_cons (NULL_TREE, NULL_TREE, $1); } ! 1589: | error ')' ! 1590: { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); } ! 1591: ; ! 1592: ! 1593: parmlist_1: ! 1594: parmlist_2 ')' ! 1595: | error ')' ! 1596: { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); } ! 1597: ; ! 1598: ! 1599: /* This is what appears inside the parens in a function declarator. ! 1600: Is value is represented in the format that grokdeclarator expects. */ ! 1601: parmlist_2: /* empty */ ! 1602: { $$ = get_parm_info (0); } ! 1603: | parms ! 1604: { $$ = get_parm_info (1); } ! 1605: | parms ',' ELLIPSIS ! 1606: { $$ = get_parm_info (0); } ! 1607: ; ! 1608: ! 1609: parms: ! 1610: parm ! 1611: { push_parm_decl ($1); } ! 1612: | parms ',' parm ! 1613: { push_parm_decl ($3); } ! 1614: ; ! 1615: ! 1616: /* A single parameter declaration or parameter type name, ! 1617: as found in a parmlist. */ ! 1618: parm: ! 1619: typed_declspecs parm_declarator ! 1620: { $$ = build_tree_list ($1, $2) ; } ! 1621: | typed_declspecs notype_declarator ! 1622: { $$ = build_tree_list ($1, $2) ; } ! 1623: | typed_declspecs absdcl ! 1624: { $$ = build_tree_list ($1, $2); } ! 1625: | declmods notype_declarator ! 1626: { $$ = build_tree_list ($1, $2) ; } ! 1627: | declmods absdcl ! 1628: { $$ = build_tree_list ($1, $2); } ! 1629: ; ! 1630: ! 1631: /* A nonempty list of identifiers. */ ! 1632: identifiers: ! 1633: IDENTIFIER ! 1634: { $$ = build_tree_list (NULL_TREE, $1); } ! 1635: | identifiers ',' IDENTIFIER ! 1636: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 1637: ; ! 1638: ! 1639: /* ! 1640: * Objective-C productions. ! 1641: */ ! 1642: objcdef: ! 1643: classdef ! 1644: | methoddef ! 1645: | END ! 1646: { ! 1647: if (objc_implementation_context) ! 1648: { ! 1649: finish_class (objc_implementation_context); ! 1650: objc_ivar_chain = NULL_TREE; ! 1651: objc_implementation_context = NULL_TREE; ! 1652: } ! 1653: else ! 1654: warning ("`@end' must appear in an implementation context"); ! 1655: } ! 1656: ; ! 1657: ! 1658: classdef: ! 1659: INTERFACE identifier '{' ! 1660: { ! 1661: objc_interface_context = objc_ivar_context ! 1662: = start_class (INTERFACE_TYPE, $2, NULL_TREE); ! 1663: objc_public_flag = 0; ! 1664: } ! 1665: ivar_decl_list '}' ! 1666: { ! 1667: continue_class (objc_interface_context); ! 1668: } ! 1669: methodprotolist ! 1670: END ! 1671: { ! 1672: finish_class (objc_interface_context); ! 1673: objc_interface_context = NULL_TREE; ! 1674: } ! 1675: ! 1676: | INTERFACE identifier ! 1677: { ! 1678: objc_interface_context ! 1679: = start_class (INTERFACE_TYPE, $2, NULL_TREE); ! 1680: continue_class (objc_interface_context); ! 1681: } ! 1682: methodprotolist ! 1683: END ! 1684: { ! 1685: finish_class (objc_interface_context); ! 1686: objc_interface_context = NULL_TREE; ! 1687: } ! 1688: ! 1689: | INTERFACE identifier ':' identifier '{' ! 1690: { ! 1691: objc_interface_context = objc_ivar_context ! 1692: = start_class (INTERFACE_TYPE, $2, $4); ! 1693: objc_public_flag = 0; ! 1694: } ! 1695: ivar_decl_list '}' ! 1696: { ! 1697: continue_class (objc_interface_context); ! 1698: } ! 1699: methodprotolist ! 1700: END ! 1701: { ! 1702: finish_class (objc_interface_context); ! 1703: objc_interface_context = NULL_TREE; ! 1704: } ! 1705: ! 1706: | INTERFACE identifier ':' identifier ! 1707: { ! 1708: objc_interface_context ! 1709: = start_class (INTERFACE_TYPE, $2, $4); ! 1710: continue_class (objc_interface_context); ! 1711: } ! 1712: methodprotolist ! 1713: END ! 1714: { ! 1715: finish_class (objc_interface_context); ! 1716: objc_interface_context = NULL_TREE; ! 1717: } ! 1718: ! 1719: | IMPLEMENTATION identifier '{' ! 1720: { ! 1721: objc_implementation_context = objc_ivar_context ! 1722: = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE); ! 1723: objc_public_flag = 0; ! 1724: } ! 1725: ivar_decl_list '}' ! 1726: { ! 1727: objc_ivar_chain ! 1728: = continue_class (objc_implementation_context); ! 1729: } ! 1730: ! 1731: | IMPLEMENTATION identifier ! 1732: { ! 1733: objc_implementation_context ! 1734: = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE); ! 1735: objc_ivar_chain ! 1736: = continue_class (objc_implementation_context); ! 1737: } ! 1738: ! 1739: | IMPLEMENTATION identifier ':' identifier '{' ! 1740: { ! 1741: objc_implementation_context = objc_ivar_context ! 1742: = start_class (IMPLEMENTATION_TYPE, $2, $4); ! 1743: objc_public_flag = 0; ! 1744: } ! 1745: ivar_decl_list '}' ! 1746: { ! 1747: objc_ivar_chain ! 1748: = continue_class (objc_implementation_context); ! 1749: } ! 1750: ! 1751: | IMPLEMENTATION identifier ':' identifier ! 1752: { ! 1753: objc_implementation_context ! 1754: = start_class (IMPLEMENTATION_TYPE, $2, $4); ! 1755: objc_ivar_chain ! 1756: = continue_class (objc_implementation_context); ! 1757: } ! 1758: ! 1759: | INTERFACE identifier '(' identifier ')' ! 1760: { ! 1761: objc_interface_context ! 1762: = start_class (PROTOCOL_TYPE, $2, $4); ! 1763: continue_class (objc_interface_context); ! 1764: } ! 1765: methodprotolist ! 1766: END ! 1767: { ! 1768: finish_class (objc_interface_context); ! 1769: objc_interface_context = NULL_TREE; ! 1770: } ! 1771: ! 1772: | IMPLEMENTATION identifier '(' identifier ')' ! 1773: { ! 1774: objc_implementation_context ! 1775: = start_class (CATEGORY_TYPE, $2, $4); ! 1776: objc_ivar_chain ! 1777: = continue_class (objc_implementation_context); ! 1778: } ! 1779: ; ! 1780: ! 1781: ivar_decl_list: ! 1782: ivar_decls PUBLIC { objc_public_flag = 1; } ivar_decls ! 1783: | ivar_decls ! 1784: ; ! 1785: ! 1786: ivar_decls: ! 1787: /* empty */ ! 1788: { ! 1789: $$ = NULL_TREE; ! 1790: } ! 1791: | ivar_decls ivar_decl ';' ! 1792: | ivar_decls ';' ! 1793: { ! 1794: if (pedantic) ! 1795: warning ("extra semicolon in struct or union specified"); ! 1796: } ! 1797: ; ! 1798: ! 1799: ! 1800: /* There is a shift-reduce conflict here, because `components' may ! 1801: start with a `typename'. It happens that shifting (the default resolution) ! 1802: does the right thing, because it treats the `typename' as part of ! 1803: a `typed_typespecs'. ! 1804: ! 1805: It is possible that this same technique would allow the distinction ! 1806: between `notype_initdecls' and `initdecls' to be eliminated. ! 1807: But I am being cautious and not trying it. */ ! 1808: ! 1809: ivar_decl: ! 1810: typed_typespecs setspecs ivars ! 1811: { ! 1812: $$ = $3; ! 1813: resume_momentary ($2); ! 1814: } ! 1815: | nonempty_type_quals setspecs ivars ! 1816: { ! 1817: $$ = $3; ! 1818: resume_momentary ($2); ! 1819: } ! 1820: | error ! 1821: { $$ = NULL_TREE; } ! 1822: ; ! 1823: ! 1824: ivars: ! 1825: /* empty */ ! 1826: { $$ = NULL_TREE; } ! 1827: | ivar_declarator ! 1828: | ivars ',' ivar_declarator ! 1829: ; ! 1830: ! 1831: ivar_declarator: ! 1832: declarator ! 1833: { ! 1834: $$ = add_instance_variable (objc_ivar_context, ! 1835: objc_public_flag, ! 1836: $1, current_declspecs, ! 1837: NULL_TREE); ! 1838: } ! 1839: | declarator ':' expr_no_commas ! 1840: { ! 1841: $$ = add_instance_variable (objc_ivar_context, ! 1842: objc_public_flag, ! 1843: $1, current_declspecs, $3); ! 1844: } ! 1845: | ':' expr_no_commas ! 1846: { ! 1847: $$ = add_instance_variable (objc_ivar_context, ! 1848: objc_public_flag, ! 1849: NULL_TREE, ! 1850: current_declspecs, $2); ! 1851: } ! 1852: ; ! 1853: ! 1854: methoddef: ! 1855: '+' ! 1856: { ! 1857: if (objc_implementation_context) ! 1858: objc_inherit_code = CLASS_METHOD_DECL; ! 1859: else ! 1860: fatal ("method definition not in class context"); ! 1861: } ! 1862: methoddecl ! 1863: { ! 1864: add_class_method (objc_implementation_context, $3); ! 1865: start_method_def ($3); ! 1866: objc_method_context = $3; ! 1867: } ! 1868: optarglist ! 1869: { ! 1870: continue_method_def (); ! 1871: } ! 1872: compstmt_or_error ! 1873: { ! 1874: finish_method_def (); ! 1875: objc_method_context = NULL_TREE; ! 1876: } ! 1877: ! 1878: | '-' ! 1879: { ! 1880: if (objc_implementation_context) ! 1881: objc_inherit_code = INSTANCE_METHOD_DECL; ! 1882: else ! 1883: fatal ("method definition not in class context"); ! 1884: } ! 1885: methoddecl ! 1886: { ! 1887: add_instance_method (objc_implementation_context, $3); ! 1888: start_method_def ($3); ! 1889: objc_method_context = $3; ! 1890: } ! 1891: optarglist ! 1892: { ! 1893: continue_method_def (); ! 1894: } ! 1895: compstmt_or_error ! 1896: { ! 1897: finish_method_def (); ! 1898: objc_method_context = NULL_TREE; ! 1899: } ! 1900: ; ! 1901: ! 1902: /* the reason for the strange actions in this rule ! 1903: is so that notype_initdecls when reached via datadef ! 1904: can find a valid list of type and sc specs in $0. */ ! 1905: ! 1906: methodprotolist: ! 1907: /* empty */ ! 1908: | {$<ttype>$ = NULL_TREE; } methodprotolist2 ! 1909: ; ! 1910: ! 1911: methodprotolist2: /* eliminates a shift/reduce conflict */ ! 1912: methodproto ! 1913: | datadef ! 1914: | methodprotolist2 methodproto ! 1915: | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef ! 1916: ; ! 1917: ! 1918: semi_or_error: ! 1919: ';' ! 1920: | error ! 1921: ; ! 1922: ! 1923: methodproto: ! 1924: '+' ! 1925: { ! 1926: objc_inherit_code = CLASS_METHOD_DECL; ! 1927: } ! 1928: methoddecl ! 1929: { ! 1930: add_class_method (objc_interface_context, $3); ! 1931: } ! 1932: semi_or_error ! 1933: ! 1934: | '-' ! 1935: { ! 1936: objc_inherit_code = INSTANCE_METHOD_DECL; ! 1937: } ! 1938: methoddecl ! 1939: { ! 1940: add_instance_method (objc_interface_context, $3); ! 1941: } ! 1942: semi_or_error ! 1943: ; ! 1944: ! 1945: methoddecl: ! 1946: '(' typename ')' unaryselector ! 1947: { ! 1948: $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE); ! 1949: } ! 1950: ! 1951: | unaryselector ! 1952: { ! 1953: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE); ! 1954: } ! 1955: ! 1956: | '(' typename ')' keywordselector optparmlist ! 1957: { ! 1958: $$ = build_method_decl (objc_inherit_code, $2, $4, $5); ! 1959: } ! 1960: ! 1961: | keywordselector optparmlist ! 1962: { ! 1963: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2); ! 1964: } ! 1965: ; ! 1966: ! 1967: /* "optarglist" assumes that start_method_def has already been called... ! 1968: if it is not, the "xdecls" will not be placed in the proper scope */ ! 1969: ! 1970: optarglist: ! 1971: /* empty */ ! 1972: | ';' myxdecls ! 1973: ; ! 1974: ! 1975: /* to get around the following situation: "int foo (int a) int b; {}" that ! 1976: is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */ ! 1977: ! 1978: myxdecls: ! 1979: /* empty */ ! 1980: | mydecls ! 1981: ; ! 1982: ! 1983: mydecls: ! 1984: mydecl ! 1985: | errstmt ! 1986: | mydecls mydecl ! 1987: | mydecl errstmt ! 1988: ; ! 1989: ! 1990: mydecl: ! 1991: typed_declspecs setspecs myparms ';' ! 1992: { resume_momentary ($2); } ! 1993: | typed_declspecs ';' ! 1994: { shadow_tag ($1); } ! 1995: | declmods ';' ! 1996: { warning ("empty declaration"); } ! 1997: ; ! 1998: ! 1999: myparms: ! 2000: myparm ! 2001: { push_parm_decl ($1); } ! 2002: | myparms ',' myparm ! 2003: { push_parm_decl ($3); } ! 2004: ; ! 2005: ! 2006: /* A single parameter declaration or parameter type name, ! 2007: as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */ ! 2008: ! 2009: myparm: ! 2010: parm_declarator ! 2011: { $$ = build_tree_list (current_declspecs, $1) ; } ! 2012: | notype_declarator ! 2013: { $$ = build_tree_list (current_declspecs, $1) ; } ! 2014: | absdcl ! 2015: { $$ = build_tree_list (current_declspecs, $1) ; } ! 2016: ; ! 2017: ! 2018: optparmlist: ! 2019: /* empty */ ! 2020: { ! 2021: $$ = NULL_TREE; ! 2022: } ! 2023: | ',' ELLIPSIS ! 2024: { ! 2025: /* oh what a kludge! */ ! 2026: $$ = (tree)1; ! 2027: } ! 2028: | ',' ! 2029: { ! 2030: pushlevel (0); ! 2031: } ! 2032: parmlist_2 ! 2033: { ! 2034: /* returns a tree list node generated by get_parm_info */ ! 2035: $$ = $3; ! 2036: poplevel (0, 0, 0); ! 2037: } ! 2038: ; ! 2039: ! 2040: unaryselector: ! 2041: selector ! 2042: ; ! 2043: ! 2044: keywordselector: ! 2045: keyworddecl ! 2046: ! 2047: | keywordselector keyworddecl ! 2048: { ! 2049: $$ = chainon ($1, $2); ! 2050: } ! 2051: ; ! 2052: ! 2053: selector: ! 2054: IDENTIFIER ! 2055: | TYPENAME ! 2056: | reservedwords ! 2057: ; ! 2058: ! 2059: reservedwords: ! 2060: ENUM { $$ = get_identifier (token_buffer); } ! 2061: | STRUCT { $$ = get_identifier (token_buffer); } ! 2062: | UNION { $$ = get_identifier (token_buffer); } ! 2063: | IF { $$ = get_identifier (token_buffer); } ! 2064: | ELSE { $$ = get_identifier (token_buffer); } ! 2065: | WHILE { $$ = get_identifier (token_buffer); } ! 2066: | DO { $$ = get_identifier (token_buffer); } ! 2067: | FOR { $$ = get_identifier (token_buffer); } ! 2068: | SWITCH { $$ = get_identifier (token_buffer); } ! 2069: | CASE { $$ = get_identifier (token_buffer); } ! 2070: | DEFAULT { $$ = get_identifier (token_buffer); } ! 2071: | BREAK { $$ = get_identifier (token_buffer); } ! 2072: | CONTINUE { $$ = get_identifier (token_buffer); } ! 2073: | RETURN { $$ = get_identifier (token_buffer); } ! 2074: | GOTO { $$ = get_identifier (token_buffer); } ! 2075: | ASM { $$ = get_identifier (token_buffer); } ! 2076: | SIZEOF { $$ = get_identifier (token_buffer); } ! 2077: | TYPEOF { $$ = get_identifier (token_buffer); } ! 2078: | ALIGNOF { $$ = get_identifier (token_buffer); } ! 2079: | TYPESPEC | TYPE_QUAL ! 2080: ; ! 2081: ! 2082: keyworddecl: ! 2083: selector ':' '(' typename ')' identifier ! 2084: { ! 2085: $$ = build_keyword_decl ($1, $4, $6); ! 2086: } ! 2087: ! 2088: | selector ':' identifier ! 2089: { ! 2090: $$ = build_keyword_decl ($1, NULL_TREE, $3); ! 2091: } ! 2092: ! 2093: | ':' '(' typename ')' identifier ! 2094: { ! 2095: $$ = build_keyword_decl (NULL_TREE, $3, $5); ! 2096: } ! 2097: ! 2098: | ':' identifier ! 2099: { ! 2100: $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2); ! 2101: } ! 2102: ; ! 2103: ! 2104: messageargs: ! 2105: selector ! 2106: | keywordarglist ! 2107: ; ! 2108: ! 2109: keywordarglist: ! 2110: keywordarg ! 2111: | keywordarglist keywordarg ! 2112: { ! 2113: $$ = chainon ($1, $2); ! 2114: } ! 2115: ; ! 2116: ! 2117: ! 2118: keywordexpr: ! 2119: nonnull_exprlist ! 2120: { ! 2121: if (TREE_CHAIN ($1) == NULL_TREE) ! 2122: /* just return the expr., remove a level of indirection */ ! 2123: $$ = TREE_VALUE ($1); ! 2124: else ! 2125: /* we have a comma expr., we will collapse later */ ! 2126: $$ = $1; ! 2127: } ! 2128: ; ! 2129: ! 2130: keywordarg: ! 2131: selector ':' keywordexpr ! 2132: { ! 2133: $$ = build_tree_list ($1, $3); ! 2134: } ! 2135: | ':' keywordexpr ! 2136: { ! 2137: $$ = build_tree_list (NULL_TREE, $2); ! 2138: } ! 2139: ; ! 2140: ! 2141: receiver: ! 2142: expr ! 2143: | CLASSNAME ! 2144: { ! 2145: $$ = get_class_reference ($1); ! 2146: } ! 2147: ; ! 2148: ! 2149: objcmessageexpr: ! 2150: '[' ! 2151: { objc_receiver_context = 1; } ! 2152: receiver ! 2153: { objc_receiver_context = 0; } ! 2154: messageargs ']' ! 2155: { ! 2156: $$ = build_tree_list ($3, $5); ! 2157: } ! 2158: ; ! 2159: ! 2160: selectorarg: ! 2161: selector ! 2162: | keywordnamelist ! 2163: ; ! 2164: ! 2165: keywordnamelist: ! 2166: keywordname ! 2167: | keywordnamelist keywordname ! 2168: { ! 2169: $$ = chainon ($1, $2); ! 2170: } ! 2171: ; ! 2172: ! 2173: keywordname: ! 2174: selector ':' ! 2175: { ! 2176: $$ = build_tree_list ($1, NULL_TREE); ! 2177: } ! 2178: | ':' ! 2179: { ! 2180: $$ = build_tree_list (NULL_TREE, NULL_TREE); ! 2181: } ! 2182: ; ! 2183: ! 2184: objcselectorexpr: ! 2185: SELECTOR '(' selectorarg ')' ! 2186: { ! 2187: $$ = $3; ! 2188: } ! 2189: ; ! 2190: ! 2191: /* extension to support C-structures in the archiver */ ! 2192: ! 2193: objcencodeexpr: ! 2194: ENCODE '(' typename ')' ! 2195: { ! 2196: $$ = groktypename ($3); ! 2197: } ! 2198: ; ! 2199: %% ! 2200: /* If STRING is the name of an Objective C @-keyword ! 2201: (not including the @), return the token type for that keyword. ! 2202: Otherwise return 0. */ ! 2203: ! 2204: int ! 2205: recognize_objc_keyword (string) ! 2206: char *string; ! 2207: { ! 2208: switch (string[0]) ! 2209: { ! 2210: case 'd': ! 2211: if (!strcmp (string, "defs")) ! 2212: return DEFS; ! 2213: break; ! 2214: case 'e': ! 2215: if (!strcmp (string, "end")) ! 2216: return END; ! 2217: if (!strcmp (string, "encode")) ! 2218: return ENCODE; ! 2219: break; ! 2220: case 'i': ! 2221: if (!strcmp (string, "interface")) ! 2222: return INTERFACE; ! 2223: if (!strcmp (string, "implementation")) ! 2224: return IMPLEMENTATION; ! 2225: break; ! 2226: case 'p': ! 2227: if (!strcmp (string, "public")) ! 2228: return PUBLIC; ! 2229: break; ! 2230: case 's': ! 2231: if (!strcmp (string, "selector")) ! 2232: return SELECTOR; ! 2233: break; ! 2234: } ! 2235: return 0; ! 2236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.