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