|
|
1.1 ! root 1: /* YACC parser for C++ syntax and for Objective-C. ! 2: Copyright (C) 1988, 1989, 1993 Free Software Foundation, Inc. ! 3: Hacked by Michael Tiemann ([email protected]) ! 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: /* This file defines the grammar of C++ and that of Objective C. ! 22: %if objc ... %endif objc conditionals contain code for Objective C only. ! 23: %if cplus ... %endif cplus conditionals contain code for C++ only. ! 24: Sed commands in Makefile.in are used to convert this file into ! 25: cp-parse.y and into obcp-parse.y. */ ! 26: ! 27: ! 28: /* This grammar is based on the GNU CC grammar. */ ! 29: ! 30: /* Note: Bison automatically applies a default action of "$$ = $1" for ! 31: all derivations; this is applied before the explicit action, if one ! 32: is given. Keep this in mind when reading the actions. */ ! 33: ! 34: /* Also note: this version contains experimental exception ! 35: handling features. They could break, change, disappear, ! 36: or otherwise exhibit volatile behavior. Don't depend on ! 37: me (Michael Tiemann) to protect you from any negative impact ! 38: this may have on your professional, personal, or spiritual life. ! 39: ! 40: NEWS FLASH: This version now supports the exception handling ! 41: syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given. ! 42: THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the ! 43: 'catch' much match EXACTLY (no inheritance support or coercions). ! 44: Also, throw-specifications of functions don't work. ! 45: Destructors aren't called correctly. Etc, etc. --Per Bothner. ! 46: */ ! 47: ! 48: %{ ! 49: ! 50: %ifobjc ! 51: #define OBJCPLUS ! 52: %endifobjc ! 53: ! 54: #if defined(GATHER_STATISTICS) || defined(SPEW_DEBUG) ! 55: #undef YYDEBUG ! 56: #define YYDEBUG 1 ! 57: #endif ! 58: ! 59: #include "config.h" ! 60: ! 61: #include <stdio.h> ! 62: #include <errno.h> ! 63: ! 64: #include "tree.h" ! 65: #include "input.h" ! 66: #include "flags.h" ! 67: #include "cp-lex.h" ! 68: #include "cp-tree.h" ! 69: ! 70: /* Since parsers are distinct for each language, put the language string ! 71: definition here. (fnf) */ ! 72: %ifobjc ! 73: char *language_string = "GNU Objective-C++"; ! 74: %endifobjc ! 75: %ifcplus ! 76: char *language_string = "GNU C++"; ! 77: %endifcplus ! 78: ! 79: extern tree void_list_node; ! 80: extern struct obstack permanent_obstack; ! 81: ! 82: #ifndef errno ! 83: extern int errno; ! 84: #endif ! 85: ! 86: extern int end_of_file; ! 87: ! 88: void yyerror (); ! 89: ! 90: /* Like YYERROR but do call yyerror. */ ! 91: #define YYERROR1 { yyerror ("syntax error"); YYERROR; } ! 92: ! 93: static void position_after_white_space (); ! 94: ! 95: /* Contains the statement keyword (if/while/do) to include in an ! 96: error message if the user supplies an empty conditional expression. */ ! 97: static char *cond_stmt_keyword; ! 98: ! 99: %ifobjc ! 100: #include "objc-act.h" ! 101: ! 102: /* the `decl' list operators optimization is not appropriate for Objective-C */ ! 103: #define build_decl_list build_tree_list ! 104: #define decl_tree_cons tree_cons ! 105: %endifobjc ! 106: ! 107: /* Nonzero if we have an `extern "C"' acting as an extern specifier. */ ! 108: int have_extern_spec; ! 109: int used_extern_spec; ! 110: ! 111: void yyhook (); ! 112: ! 113: /* Cons up an empty parameter list. */ ! 114: #ifdef __GNUC__ ! 115: __inline ! 116: #endif ! 117: static tree ! 118: empty_parms () ! 119: { ! 120: tree parms; ! 121: ! 122: if (strict_prototype) ! 123: parms = void_list_node; ! 124: else ! 125: parms = NULL_TREE; ! 126: return parms; ! 127: } ! 128: %} ! 129: ! 130: %start program ! 131: ! 132: %union {long itype; tree ttype; char *strtype; enum tree_code code; } ! 133: ! 134: /* All identifiers that are not reserved words ! 135: and are not declared typedefs in the current block */ ! 136: %token IDENTIFIER ! 137: ! 138: /* All identifiers that are declared typedefs in the current block. ! 139: In some contexts, they are treated just like IDENTIFIER, ! 140: but they can also serve as typespecs in declarations. */ ! 141: %token TYPENAME ! 142: ! 143: /* Qualified identifiers that end in a TYPENAME. */ ! 144: %token SCOPED_TYPENAME ! 145: ! 146: /* Reserved words that specify storage class. ! 147: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 148: %token SCSPEC ! 149: ! 150: /* Reserved words that specify type. ! 151: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 152: %token TYPESPEC ! 153: ! 154: /* Reserved words that qualify type: "const" or "volatile". ! 155: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 156: %token TYPE_QUAL ! 157: ! 158: /* Character or numeric constants. ! 159: yylval is the node for the constant. */ ! 160: %token CONSTANT ! 161: ! 162: /* String constants in raw form. ! 163: yylval is a STRING_CST node. */ ! 164: %token STRING ! 165: ! 166: /* "...", used for functions with variable arglists. */ ! 167: %token ELLIPSIS ! 168: ! 169: /* the reserved words */ ! 170: /* SCO include files test "ASM", so use something else. */ ! 171: %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT ! 172: %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF ! 173: %token HEADOF CLASSOF ! 174: %token ATTRIBUTE EXTENSION LABEL ! 175: ! 176: /* the reserved words... C++ extensions */ ! 177: %token <ttype> AGGR ! 178: %token <itype> VISSPEC ! 179: %token DELETE NEW OVERLOAD THIS OPERATOR ! 180: %token LEFT_RIGHT TEMPLATE ! 181: %token TYPEID DYNAMIC_CAST ! 182: %token <itype> SCOPE ! 183: ! 184: %ifobjc ! 185: /* the Objective-C keywords */ ! 186: %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE ! 187: %token CLASSNAME PROTOCOL OBJECTNAME CLASS ALIAS ! 188: %token PRIVATE PUBLIC PROTECTED ! 189: ! 190: /* Objective-C string constants in raw form. ! 191: yylval is a OBJC_STRING_CST node. */ ! 192: %token OBJC_STRING ! 193: %endifobjc ! 194: ! 195: /* Special token created by the lexer to separate TYPENAME ! 196: from an ABSDCL. This allows us to parse `foo (*pf)()'. */ ! 197: ! 198: %token START_DECLARATOR ! 199: ! 200: /* Define the operator tokens and their precedences. ! 201: The value is an integer because, if used, it is the tree code ! 202: to use in the expression made from the operator. */ ! 203: ! 204: %left EMPTY /* used to resolve s/r with epsilon */ ! 205: ! 206: /* Add precedence rules to solve dangling else s/r conflict */ ! 207: %nonassoc IF ! 208: %nonassoc ELSE ! 209: ! 210: %left IDENTIFIER TYPENAME TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ! 211: ! 212: %left '{' ',' ! 213: ! 214: %right <code> ASSIGN '=' ! 215: %right <code> '?' ':' RANGE ! 216: %left <code> OROR ! 217: %left <code> ANDAND ! 218: %left <code> '|' ! 219: %left <code> '^' ! 220: %left <code> '&' ! 221: %left <code> MIN_MAX ! 222: %left <code> EQCOMPARE ! 223: %left <code> ARITHCOMPARE '<' '>' ! 224: %left <code> LSHIFT RSHIFT ! 225: %left <code> '+' '-' ! 226: %left <code> '*' '/' '%' ! 227: %right <code> UNARY PLUSPLUS MINUSMINUS ! 228: %left HYPERUNARY ! 229: %left <ttype> PAREN_STAR_PAREN LEFT_RIGHT ! 230: %left <code> POINTSAT POINTSAT_STAR '.' DOT_STAR '(' '[' ! 231: ! 232: %right SCOPE /* C++ extension */ ! 233: %nonassoc NEW DELETE RAISE RAISES RERAISE TRY EXCEPT CATCH THROW ! 234: %nonassoc ANSI_TRY ANSI_THROW ! 235: ! 236: %type <code> unop ! 237: ! 238: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist ! 239: %type <ttype> optional_identifier paren_expr_or_null ! 240: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING ! 241: %type <ttype> typed_declspecs reserved_declspecs ! 242: %type <ttype> typed_typespecs reserved_typespecquals ! 243: %type <ttype> declmods typespec typespecqual_reserved ! 244: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual ! 245: %type <itype> initdecls notype_initdecls initdcl /* C++ modification */ ! 246: %type <ttype> init initlist maybeasm ! 247: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers ! 248: %type <ttype> maybe_attribute attribute_list attrib ! 249: %type <ttype> abs_member_declarator after_type_member_declarator ! 250: ! 251: %type <ttype> compstmt except_stmts ansi_except_stmts implicitly_scoped_stmt ! 252: ! 253: %type <ttype> declarator notype_declarator after_type_declarator ! 254: ! 255: %type <ttype> structsp opt.component_decl_list component_decl_list ! 256: %type <ttype> component_decl components component_declarator ! 257: %type <ttype> enumlist enumerator ! 258: %type <ttype> typename absdcl absdcl1 type_quals abs_or_notype_decl ! 259: %type <ttype> xexpr see_typename parmlist parms parm bad_parm ! 260: %type <ttype> identifiers_or_typenames ! 261: ! 262: /* C++ extensions */ ! 263: %type <ttype> typename_scope ! 264: %token <ttype> TYPENAME_COLON TYPENAME_ELLIPSIS ! 265: %token <ttype> PTYPENAME SCOPED_TYPENAME ! 266: %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL ! 267: %token <ttype> PRE_PARSED_CLASS_DECL ! 268: %type <ttype> fn.def1 /* Not really! */ ! 269: %type <ttype> fn.def2 return_id ! 270: %type <ttype> named_class_head named_class_head_sans_basetype ! 271: %type <ttype> unnamed_class_head ! 272: %type <ttype> class_head base_class_list ! 273: %type <itype> base_class_visibility_list ! 274: %type <ttype> base_class maybe_base_class_list base_class.1 ! 275: %type <ttype> after_type_declarator_no_typename ! 276: %type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers ! 277: %type <ttype> component_declarator0 id_scope scoped_typename scoped_base_class ! 278: %type <ttype> forhead.1 identifier_or_opname operator_name ! 279: %type <ttype> new delete object object_star aggr ! 280: /* %type <ttype> primary_no_id */ ! 281: %type <ttype> nonmomentary_expr ! 282: %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list ! 283: %type <itype> .scope try ansi_try ! 284: %type <ttype> template_header template_parm_list template_parm ! 285: %type <ttype> template_type template_arg_list template_arg ! 286: %type <ttype> template_instantiation template_type_name tmpl.1 tmpl.2 ! 287: %type <ttype> template_instantiate_once template_instantiate_some ! 288: %type <itype> fn_tmpl_end ! 289: /* %type <itype> try_for_typename */ ! 290: %type <ttype> condition partially_scoped_stmt xcond paren_cond_or_null ! 291: %type <strtype> .kindof_pushlevel ! 292: ! 293: /* in order to recognize aggr tags as defining and thus shadowing. */ ! 294: %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN ! 295: %type <ttype> named_class_head_sans_basetype_defn ! 296: %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN ! 297: ! 298: %type <strtype> .pushlevel ! 299: ! 300: %ifobjc ! 301: /* the Objective-C productions */ ! 302: %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator ! 303: %type <ttype> methoddecl unaryselector keywordselector selector methodtype ! 304: %type <ttype> keyworddecl receiver objcmessageexpr messageargs ! 305: %type <ttype> keywordexpr keywordarglist keywordarg reservedword ! 306: %type <ttype> myparms myparm optparmlist objcselectorexpr ! 307: %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr ! 308: %type <ttype> objc_string protocolrefs identifier_list identifier_colon ! 309: %type <ttype> objcprotocolexpr CLASSNAME OBJC_STRING OBJECTNAME ! 310: %type <ttype> objc_openbracket.expr objc_closebracket ! 311: %endifobjc ! 312: ! 313: /* cp-spew.c depends on this being the last token. Define ! 314: any new tokens before this one! */ ! 315: %token END_OF_SAVED_INPUT ! 316: ! 317: %{ ! 318: /* List of types and structure classes of the current declaration. */ ! 319: static tree current_declspecs; ! 320: ! 321: /* When defining an aggregate, this is the most recent one being defined. */ ! 322: static tree current_aggr; ! 323: ! 324: %ifobjc ! 325: /* List of Objective-C specific information */ ! 326: ! 327: static tree objc_interface_context; ! 328: tree objc_implementation_context; ! 329: tree objc_method_context; ! 330: tree objc_ivar_chain; ! 331: static tree objc_ivar_context; ! 332: static enum tree_code objc_inherit_code; ! 333: int objc_receiver_context = 0; ! 334: int objc_declarator_context = 0; ! 335: int objc_msg_context = 0; ! 336: static int objc_public_flag; ! 337: ! 338: extern char *token_buffer; ! 339: ! 340: tree current_objc_implementation_context (void) ! 341: { ! 342: return objc_implementation_context; ! 343: } ! 344: %endifobjc ! 345: ! 346: /* Tell yyparse how to print a token's value, if yydebug is set. */ ! 347: ! 348: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) ! 349: extern void yyprint (); ! 350: extern tree combine_strings PROTO((tree)); ! 351: extern tree truthvalue_conversion PROTO((tree)); ! 352: %} ! 353: ! 354: %% ! 355: program: /* empty */ ! 356: %ifobjc ! 357: { objc_finish (); } ! 358: %endifobjc ! 359: | extdefs ! 360: { ! 361: /* In case there were missing closebraces, ! 362: get us back to the global binding level. */ ! 363: while (! global_bindings_p ()) ! 364: poplevel (0, 0, 0); ! 365: finish_file (); ! 366: %ifobjc ! 367: objc_finish (); ! 368: %endifobjc ! 369: } ! 370: ; ! 371: ! 372: /* the reason for the strange actions in this rule ! 373: is so that notype_initdecls when reached via datadef ! 374: can find a valid list of type and sc specs in $0. */ ! 375: ! 376: extdefs: ! 377: { $<ttype>$ = NULL_TREE; } extdef ! 378: {$<ttype>$ = NULL_TREE; } ! 379: | extdefs extdef ! 380: {$<ttype>$ = NULL_TREE; } ! 381: ; ! 382: ! 383: .hush_warning: ! 384: { have_extern_spec = 1; ! 385: used_extern_spec = 0; ! 386: $<ttype>$ = NULL_TREE; } ! 387: ; ! 388: .warning_ok: ! 389: { have_extern_spec = 0; } ! 390: ; ! 391: ! 392: asm_keyword: ! 393: ASM_KEYWORD { if (pedantic) ! 394: pedwarn ("ANSI C++ forbids use of `asm' keyword"); } ! 395: | GCC_ASM_KEYWORD ! 396: ; ! 397: ! 398: extdef: ! 399: fndef ! 400: { if (pending_inlines) do_pending_inlines (); } ! 401: | datadef ! 402: { if (pending_inlines) do_pending_inlines (); } ! 403: %ifobjc ! 404: | objcdef ! 405: %endifobjc ! 406: | template_def ! 407: { if (pending_inlines) do_pending_inlines (); } ! 408: | overloaddef ! 409: | asm_keyword '(' string ')' ';' ! 410: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 411: assemble_asm ($3); } ! 412: | extern_lang_string '{' extdefs '}' ! 413: { pop_lang_context (); } ! 414: | extern_lang_string '{' '}' ! 415: { pop_lang_context (); } ! 416: | extern_lang_string .hush_warning fndef .warning_ok ! 417: { if (pending_inlines) do_pending_inlines (); ! 418: pop_lang_context (); } ! 419: | extern_lang_string .hush_warning datadef .warning_ok ! 420: { if (pending_inlines) do_pending_inlines (); ! 421: pop_lang_context (); } ! 422: ; ! 423: ! 424: extern_lang_string: ! 425: EXTERN_LANG_STRING ! 426: { push_lang_context ($1); } ! 427: ; ! 428: ! 429: template_header: ! 430: TEMPLATE '<' ! 431: { begin_template_parm_list (); } ! 432: template_parm_list '>' ! 433: { $$ = end_template_parm_list ($4); } ! 434: ; ! 435: ! 436: template_parm_list: ! 437: template_parm ! 438: { $$ = process_template_parm (NULL_TREE, $1); } ! 439: | template_parm_list ',' template_parm ! 440: { $$ = process_template_parm ($1, $3); } ! 441: ; ! 442: ! 443: template_parm: ! 444: /* The following rules introduce a new reduce/reduce ! 445: conflict: they are valid prefixes for a `structsp', ! 446: which means they could match a nameless parameter. ! 447: By putting them before the `parm' rule, we get ! 448: their match before considering them nameless parameter ! 449: declarations. */ ! 450: aggr identifier ! 451: { ! 452: if ($1 != class_type_node) ! 453: error ("template type parameter must use keyword `class'"); ! 454: $$ = build_tree_list ($2, NULL_TREE); ! 455: } ! 456: | aggr identifier_defn ':' base_class.1 ! 457: { ! 458: if ($1 != class_type_node) ! 459: error ("template type parameter must use keyword `class'"); ! 460: warning ("restricted template type parameters not yet implemented"); ! 461: $$ = build_tree_list ($2, $4); ! 462: } ! 463: | aggr TYPENAME_COLON base_class.1 ! 464: { ! 465: if ($1 != class_type_node) ! 466: error ("template type parameter must use keyword `class'"); ! 467: warning ("restricted template type parameters not yet implemented"); ! 468: $$ = build_tree_list ($2, $3); ! 469: } ! 470: | parm ! 471: ; ! 472: ! 473: overloaddef: ! 474: OVERLOAD ov_identifiers ';' ! 475: { warning ("use of `overload' is an anachronism"); } ! 476: ; ! 477: ! 478: ov_identifiers: IDENTIFIER ! 479: { declare_overloaded ($1); } ! 480: | ov_identifiers ',' IDENTIFIER ! 481: { declare_overloaded ($3); } ! 482: ; ! 483: ! 484: template_def: ! 485: /* Class template declarations go here; they aren't normal class ! 486: declarations, because we can't process the bodies yet. */ ! 487: template_header named_class_head_sans_basetype '{' ! 488: { yychar = '{'; goto template1; } ! 489: ';' ! 490: | template_header named_class_head_sans_basetype_defn '{' ! 491: { yychar = '{'; goto template1; } ! 492: ';' ! 493: | template_header named_class_head_sans_basetype ':' ! 494: { yychar = ':'; goto template1; } ! 495: ';' ! 496: | template_header named_class_head_sans_basetype_defn ':' ! 497: { ! 498: yychar = ':'; ! 499: template1: ! 500: if (current_aggr == exception_type_node) ! 501: error ("template type must define an aggregate or union"); ! 502: /* Maybe pedantic warning for union? ! 503: How about an enum? :-) */ ! 504: end_template_decl ($1, $2, current_aggr); ! 505: reinit_parse_for_template (yychar, $1, $2); ! 506: yychar = YYEMPTY; ! 507: } ! 508: ';' ! 509: | template_header named_class_head_sans_basetype ';' ! 510: { ! 511: end_template_decl ($1, $2, current_aggr); ! 512: /* declare $2 as template name with $1 parm list */ ! 513: } ! 514: | template_header named_class_head_sans_basetype_defn ';' ! 515: { ! 516: end_template_decl ($1, $2, current_aggr); ! 517: /* declare $2 as template name with $1 parm list */ ! 518: } ! 519: | template_header /* notype_initdcl0 ';' */ ! 520: notype_declarator maybe_raises maybeasm maybe_attribute ! 521: fn_tmpl_end ! 522: { ! 523: tree d; ! 524: int momentary; ! 525: momentary = suspend_momentary (); ! 526: d = start_decl ($<ttype>2, /*current_declspecs*/NULL_TREE, 0, $3); ! 527: cplus_decl_attributes (d, $5); ! 528: finish_decl (d, NULL_TREE, $4, 0); ! 529: end_template_decl ($1, d, 0); ! 530: if ($6 != ';') ! 531: reinit_parse_for_template ((int) $6, $1, d); ! 532: resume_momentary (momentary); ! 533: } ! 534: | template_header typed_declspecs /*initdcl0*/ ! 535: declarator maybe_raises maybeasm maybe_attribute ! 536: fn_tmpl_end ! 537: { ! 538: tree d; ! 539: int momentary; ! 540: ! 541: current_declspecs = $2; ! 542: momentary = suspend_momentary (); ! 543: d = start_decl ($<ttype>3, current_declspecs, ! 544: 0, $<ttype>4); ! 545: cplus_decl_attributes (d, $6); ! 546: finish_decl (d, NULL_TREE, $5, 0); ! 547: end_exception_decls (); ! 548: end_template_decl ($1, d, 0); ! 549: if ($7 != ';') ! 550: { ! 551: reinit_parse_for_template ((int) $7, $1, d); ! 552: yychar = YYEMPTY; ! 553: } ! 554: note_list_got_semicolon ($<ttype>2); ! 555: resume_momentary (momentary); ! 556: } ! 557: | template_header declmods declarator fn_tmpl_end ! 558: { ! 559: tree d = start_decl ($<ttype>3, $<ttype>2, 0, NULL_TREE); ! 560: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 561: end_template_decl ($1, d, 0); ! 562: if ($4 != ';') ! 563: reinit_parse_for_template ((int) $4, $1, d); ! 564: } ! 565: /* Try to recover from syntax errors in templates. */ ! 566: | template_header error '}' { end_template_decl ($1, 0, 0); } ! 567: | template_header error ';' { end_template_decl ($1, 0, 0); } ! 568: ; ! 569: ! 570: fn_tmpl_end: '{' { $$ = '{'; } ! 571: | ':' { $$ = ':'; } ! 572: | ';' { $$ = ';'; } ! 573: | '=' { $$ = '='; } ! 574: | RETURN { $$ = RETURN; } ! 575: ; ! 576: ! 577: datadef: ! 578: notype_initdecls ';' ! 579: { if (pedantic) ! 580: pedwarn ("ANSI C++ forbids data definition with no type or storage class"); ! 581: else if (! flag_traditional && ! have_extern_spec) ! 582: warning ("data definition has no type or storage class"); } ! 583: | declmods notype_initdecls ';' ! 584: {} ! 585: /* Normal case to make fast: "int i;". */ ! 586: | declmods declarator ';' ! 587: { tree d; ! 588: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE); ! 589: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 590: } ! 591: | typed_declspecs initdecls ';' ! 592: { ! 593: end_exception_decls (); ! 594: note_list_got_semicolon ($<ttype>$); ! 595: } ! 596: /* Normal case: make this fast. */ ! 597: | typed_declspecs declarator ';' ! 598: { tree d; ! 599: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE); ! 600: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 601: end_exception_decls (); ! 602: note_list_got_semicolon ($<ttype>$); ! 603: } ! 604: | declmods ';' ! 605: { pedwarn ("empty declaration"); } ! 606: | typed_declspecs ';' ! 607: { ! 608: tree t = $<ttype>$; ! 609: shadow_tag (t); ! 610: if (TREE_CODE (t) == TREE_LIST ! 611: && TREE_PURPOSE (t) == NULL_TREE) ! 612: { ! 613: t = TREE_VALUE (t); ! 614: if (TREE_CODE (t) == RECORD_TYPE ! 615: && TYPE_SIZE (t) ! 616: && CLASSTYPE_USE_TEMPLATE (t) == 0) ! 617: CLASSTYPE_USE_TEMPLATE (t) = 2; ! 618: else if (TREE_CODE (t) == ENUMERAL_TYPE ! 619: && !TYPE_SIZE (t)) ! 620: cp_error ("forward declaration of `%#T'", t); ! 621: } ! 622: note_list_got_semicolon ($<ttype>$); ! 623: } ! 624: | error ';' ! 625: | error '}' ! 626: | ';' ! 627: ; ! 628: ! 629: fndef: ! 630: fn.def1 base_init compstmt_or_error ! 631: { ! 632: finish_function (lineno, 1); ! 633: /* finish_function performs these three statements: ! 634: ! 635: expand_end_bindings (getdecls (), 1, 0); ! 636: poplevel (1, 1, 0); ! 637: ! 638: expand_end_bindings (0, 0, 0); ! 639: poplevel (0, 0, 1); ! 640: */ ! 641: if ($<ttype>$) process_next_inline ($<ttype>$); ! 642: } ! 643: | fn.def1 return_init base_init compstmt_or_error ! 644: { ! 645: finish_function (lineno, 1); ! 646: /* finish_function performs these three statements: ! 647: ! 648: expand_end_bindings (getdecls (), 1, 0); ! 649: poplevel (1, 1, 0); ! 650: ! 651: expand_end_bindings (0, 0, 0); ! 652: poplevel (0, 0, 1); ! 653: */ ! 654: if ($<ttype>$) process_next_inline ($<ttype>$); ! 655: } ! 656: | fn.def1 nodecls compstmt_or_error ! 657: { finish_function (lineno, 0); ! 658: if ($<ttype>$) process_next_inline ($<ttype>$); } ! 659: | fn.def1 return_init ';' nodecls compstmt_or_error ! 660: { finish_function (lineno, 0); ! 661: if ($<ttype>$) process_next_inline ($<ttype>$); } ! 662: | fn.def1 return_init nodecls compstmt_or_error ! 663: { finish_function (lineno, 0); ! 664: if ($<ttype>$) process_next_inline ($<ttype>$); } ! 665: | typed_declspecs declarator error ! 666: {} ! 667: | declmods notype_declarator error ! 668: {} ! 669: | notype_declarator error ! 670: {} ! 671: ; ! 672: ! 673: fn.def1: ! 674: typed_declspecs declarator maybe_raises ! 675: { if (! start_function ($$, $2, $3, 0)) ! 676: YYERROR1; ! 677: reinit_parse_for_function (); ! 678: $$ = NULL_TREE; } ! 679: | declmods notype_declarator maybe_raises ! 680: { if (! start_function ($$, $2, $3, 0)) ! 681: YYERROR1; ! 682: reinit_parse_for_function (); ! 683: $$ = NULL_TREE; } ! 684: | notype_declarator maybe_raises ! 685: { if (! start_function (NULL_TREE, $$, $2, 0)) ! 686: YYERROR1; ! 687: reinit_parse_for_function (); ! 688: $$ = NULL_TREE; } ! 689: | TYPENAME '(' parmlist ')' type_quals maybe_raises ! 690: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0)) ! 691: YYERROR1; ! 692: reinit_parse_for_function (); ! 693: $$ = NULL_TREE; } ! 694: | scoped_typename '(' parmlist ')' type_quals maybe_raises ! 695: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0)) ! 696: YYERROR1; ! 697: reinit_parse_for_function (); ! 698: $$ = NULL_TREE; } ! 699: | TYPENAME LEFT_RIGHT type_quals maybe_raises ! 700: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0)) ! 701: YYERROR1; ! 702: reinit_parse_for_function (); ! 703: $$ = NULL_TREE; } ! 704: | scoped_typename LEFT_RIGHT type_quals maybe_raises ! 705: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0)) ! 706: YYERROR1; ! 707: reinit_parse_for_function (); ! 708: $$ = NULL_TREE; } ! 709: | PRE_PARSED_FUNCTION_DECL ! 710: { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1); ! 711: reinit_parse_for_function (); } ! 712: ; ! 713: ! 714: /* more C++ complexity */ ! 715: fn.def2: ! 716: typed_declspecs '(' parmlist ')' type_quals maybe_raises ! 717: { ! 718: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5); ! 719: $$ = start_method (TREE_CHAIN ($$), decl, $6); ! 720: if (! $$) ! 721: YYERROR1; ! 722: if (yychar == YYEMPTY) ! 723: yychar = YYLEX; ! 724: reinit_parse_for_method (yychar, $$); } ! 725: | typed_declspecs LEFT_RIGHT type_quals maybe_raises ! 726: { ! 727: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3); ! 728: $$ = start_method (TREE_CHAIN ($$), decl, $4); ! 729: if (! $$) ! 730: YYERROR1; ! 731: if (yychar == YYEMPTY) ! 732: yychar = YYLEX; ! 733: reinit_parse_for_method (yychar, $$); } ! 734: | typed_declspecs declarator maybe_raises ! 735: { $$ = start_method ($$, $2, $3); ! 736: if (! $$) ! 737: YYERROR1; ! 738: if (yychar == YYEMPTY) ! 739: yychar = YYLEX; ! 740: reinit_parse_for_method (yychar, $$); } ! 741: | declmods '(' parmlist ')' type_quals maybe_raises ! 742: { ! 743: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5); ! 744: $$ = start_method (TREE_CHAIN ($$), decl, $6); ! 745: if (! $$) ! 746: YYERROR1; ! 747: if (yychar == YYEMPTY) ! 748: yychar = YYLEX; ! 749: reinit_parse_for_method (yychar, $$); } ! 750: | declmods LEFT_RIGHT type_quals maybe_raises ! 751: { ! 752: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3); ! 753: $$ = start_method (TREE_CHAIN ($$), decl, $4); ! 754: if (! $$) ! 755: YYERROR1; ! 756: if (yychar == YYEMPTY) ! 757: yychar = YYLEX; ! 758: reinit_parse_for_method (yychar, $$); } ! 759: | declmods declarator maybe_raises ! 760: { $$ = start_method ($$, $2, $3); ! 761: if (! $$) ! 762: YYERROR1; ! 763: if (yychar == YYEMPTY) ! 764: yychar = YYLEX; ! 765: reinit_parse_for_method (yychar, $$); } ! 766: | notype_declarator maybe_raises ! 767: { $$ = start_method (NULL_TREE, $$, $2); ! 768: if (! $$) ! 769: YYERROR1; ! 770: if (yychar == YYEMPTY) ! 771: yychar = YYLEX; ! 772: reinit_parse_for_method (yychar, $$); } ! 773: ; ! 774: ! 775: return_id: RETURN IDENTIFIER ! 776: { ! 777: if (! current_function_parms_stored) ! 778: store_parm_decls (); ! 779: $$ = $2; ! 780: } ! 781: ; ! 782: ! 783: return_init: return_id ! 784: { store_return_init ($<ttype>$, NULL_TREE); } ! 785: | return_id '=' init ! 786: { store_return_init ($<ttype>$, $3); } ! 787: | return_id '(' nonnull_exprlist ')' ! 788: { store_return_init ($<ttype>$, $3); } ! 789: | return_id LEFT_RIGHT ! 790: { store_return_init ($<ttype>$, NULL_TREE); } ! 791: ; ! 792: ! 793: base_init: ! 794: ':' .set_base_init member_init_list ! 795: { ! 796: if ($3 == 0) ! 797: error ("no base initializers given following ':'"); ! 798: setup_vtbl_ptr (); ! 799: /* Always keep the BLOCK node associated with the outermost ! 800: pair of curley braces of a function. These are needed ! 801: for correct operation of dwarfout.c. */ ! 802: keep_next_level (); ! 803: } ! 804: ; ! 805: ! 806: .set_base_init: ! 807: /* empty */ ! 808: { ! 809: if (! current_function_parms_stored) ! 810: store_parm_decls (); ! 811: ! 812: /* Flag that we are processing base and member initializers. */ ! 813: current_vtable_decl = error_mark_node; ! 814: ! 815: if (DECL_CONSTRUCTOR_P (current_function_decl)) ! 816: { ! 817: /* Make a contour for the initializer list. */ ! 818: pushlevel (0); ! 819: clear_last_expr (); ! 820: expand_start_bindings (0); ! 821: } ! 822: else if (current_class_type == NULL_TREE) ! 823: error ("base initializers not allowed for non-member functions"); ! 824: else if (! DECL_CONSTRUCTOR_P (current_function_decl)) ! 825: error ("only constructors take base initializers"); ! 826: } ! 827: ; ! 828: ! 829: member_init_list: ! 830: /* empty */ ! 831: { $$ = 0; } ! 832: | member_init ! 833: { $$ = 1; } ! 834: | member_init_list ',' member_init ! 835: | member_init_list error ! 836: ; ! 837: ! 838: member_init: '(' nonnull_exprlist ')' ! 839: { ! 840: if (current_class_name && !flag_traditional) ! 841: pedwarn ("ANSI C++ forbids old style base class initialization", ! 842: IDENTIFIER_POINTER (current_class_name)); ! 843: expand_member_init (C_C_D, NULL_TREE, $2); ! 844: } ! 845: | LEFT_RIGHT ! 846: { ! 847: if (current_class_name && !flag_traditional) ! 848: pedwarn ("ANSI C++ forbids old style base class initialization", ! 849: IDENTIFIER_POINTER (current_class_name)); ! 850: expand_member_init (C_C_D, NULL_TREE, void_type_node); ! 851: } ! 852: | identifier '(' nonnull_exprlist ')' ! 853: { ! 854: expand_member_init (C_C_D, $<ttype>$, $3); ! 855: } ! 856: | identifier LEFT_RIGHT ! 857: { expand_member_init (C_C_D, $<ttype>$, void_type_node); } ! 858: | template_type_name '(' nonnull_exprlist ')' ! 859: { expand_member_init (C_C_D, $<ttype>$, $3); } ! 860: | template_type_name LEFT_RIGHT ! 861: { expand_member_init (C_C_D, $<ttype>$, void_type_node); } ! 862: | scoped_typename '(' nonnull_exprlist ')' ! 863: { expand_member_init (C_C_D, $<ttype>$, $3); } ! 864: | scoped_typename LEFT_RIGHT ! 865: { expand_member_init (C_C_D, $<ttype>$, void_type_node); } ! 866: | id_scope identifier '(' nonnull_exprlist ')' ! 867: { ! 868: do_member_init ($<ttype>$, $2, $4); ! 869: } ! 870: | id_scope identifier LEFT_RIGHT ! 871: { ! 872: do_member_init ($<ttype>$, $2, void_type_node); ! 873: } ! 874: ; ! 875: ! 876: identifier: ! 877: IDENTIFIER ! 878: | TYPENAME ! 879: | PTYPENAME ! 880: %ifobjc ! 881: | OBJECTNAME ! 882: | CLASSNAME ! 883: %endifobjc ! 884: ; ! 885: ! 886: identifier_defn: ! 887: IDENTIFIER_DEFN ! 888: | TYPENAME_DEFN ! 889: | PTYPENAME_DEFN ! 890: ; ! 891: ! 892: identifier_or_opname: ! 893: IDENTIFIER ! 894: | TYPENAME ! 895: | PTYPENAME ! 896: %ifobjc ! 897: | OBJECTNAME ! 898: | CLASSNAME ! 899: %endifobjc ! 900: /* | '~' TYPENAME ! 901: { $$ = build_parse_node (BIT_NOT_EXPR, $2); }*/ ! 902: /* get rid of the next line, replace it with the above */ ! 903: | '~' identifier { $$ = build_parse_node (BIT_NOT_EXPR,$2);} ! 904: | operator_name ! 905: ; ! 906: ! 907: template_type: ! 908: template_type_name tmpl.1 template_instantiation ! 909: { ! 910: extern tree template_type_seen_before_scope; ! 911: ! 912: if ($3) ! 913: $$ = $3; ! 914: else if ($$ != error_mark_node) ! 915: $$ = IDENTIFIER_TYPE_VALUE ($$); ! 916: /* This is a kludge: In order to detect nested types inside ! 917: * template classes, we have to tell the lexer that it should ! 918: * try to replace a following SCOPE token with the correct ! 919: * SCOPED_TYPENAME for the nested type. This SCOPED_TYPENAME ! 920: * token will be handled in the rule "scoped_typename". ! 921: * - [email protected] */ ! 922: if (yychar == SCOPE) ! 923: { ! 924: /* We set template_type_seen_before_scope to be ! 925: an error_mark_node so we can avoid meaningless ! 926: and unhelpful syntax errors later. */ ! 927: if ($$ != error_mark_node) ! 928: template_type_seen_before_scope = TYPE_IDENTIFIER ($$); ! 929: else ! 930: template_type_seen_before_scope = error_mark_node; ! 931: yychar = YYLEX; ! 932: } ! 933: } ! 934: ; ! 935: ! 936: template_type_name: ! 937: PTYPENAME '<' template_arg_list '>' ! 938: { $$ = lookup_template_class ($$, $3, NULL_TREE); } ! 939: | TYPENAME '<' template_arg_list '>' ! 940: { $$ = lookup_template_class ($$, $3, NULL_TREE); } ! 941: ; ! 942: ! 943: tmpl.1: ! 944: /* Expansion of template may be required, unless we're followed by ! 945: a class definition. */ ! 946: '{' { yyungetc ('{', 1); $$ = 0; } ! 947: | ':' { yyungetc (':', 1); $$ = 0; } ! 948: | /* empty */ %prec EMPTY ! 949: { $$ = instantiate_class_template ($<ttype>0, 1); } ! 950: ; ! 951: ! 952: tmpl.2: ! 953: /* Always do expansion if it hasn't been done already. */ ! 954: { $$ = instantiate_class_template ($<ttype>0, 1); } ! 955: ; ! 956: ! 957: template_arg_list: ! 958: template_arg ! 959: { $$ = build_tree_list (NULL_TREE, $$); } ! 960: | template_arg_list ',' template_arg ! 961: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } ! 962: ; ! 963: ! 964: template_arg: ! 965: typename ! 966: { $$ = groktypename ($$); } ! 967: | expr_no_commas %prec UNARY ! 968: ; ! 969: ! 970: template_instantiate_once: ! 971: PRE_PARSED_CLASS_DECL maybe_base_class_list ! 972: { ! 973: tree t, decl, id, tmpl; ! 974: ! 975: id = TREE_VALUE ($1); ! 976: tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE (id)); ! 977: t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, id, $2); ! 978: set_current_level_tags_transparency (1); ! 979: my_friendly_assert (TREE_CODE (t) == RECORD_TYPE ! 980: || TREE_CODE (t) == UNION_TYPE, 257); ! 981: $<ttype>$ = t; ! 982: ! 983: /* Now, put a copy of the decl in global scope, to avoid ! 984: recursive expansion. */ ! 985: decl = IDENTIFIER_LOCAL_VALUE (id); ! 986: if (!decl) ! 987: decl = IDENTIFIER_CLASS_VALUE (id); ! 988: /* Now, put a copy of the decl in global scope, to avoid ! 989: recursive expansion. */ ! 990: if (decl) ! 991: { ! 992: /* Need to copy it to clear the chain pointer, ! 993: and need to get it into permanent storage. */ ! 994: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 258); ! 995: push_obstacks (&permanent_obstack, &permanent_obstack); ! 996: decl = copy_node (decl); ! 997: if (DECL_LANG_SPECIFIC (decl)) ! 998: copy_lang_decl (decl); ! 999: pop_obstacks (); ! 1000: pushdecl_top_level (decl); ! 1001: } ! 1002: } ! 1003: left_curly opt.component_decl_list '}' ! 1004: { ! 1005: $$ = finish_struct ($<ttype>3, $5, 0); ! 1006: ! 1007: pop_obstacks (); ! 1008: end_template_instantiation ($1, $<ttype>3); ! 1009: ! 1010: /* Now go after the methods & class data. */ ! 1011: instantiate_member_templates ($1); ! 1012: ! 1013: pop_tinst_level(); ! 1014: ! 1015: CLASSTYPE_GOT_SEMICOLON ($$) = 1; ! 1016: } ! 1017: ; ! 1018: ! 1019: template_instantiation: ! 1020: /* empty */ ! 1021: { $$ = NULL_TREE; } ! 1022: | template_instantiate_once ! 1023: { $$ = $1; } ! 1024: ; ! 1025: ! 1026: template_instantiate_some: ! 1027: /* empty */ ! 1028: { $$ = NULL_TREE; /* never used from here... */} ! 1029: | template_instantiate_once template_instantiate_some ! 1030: { $$ = $1; /*???*/ } ! 1031: ; ! 1032: ! 1033: unop: '-' ! 1034: { $$ = NEGATE_EXPR; } ! 1035: | '+' ! 1036: { $$ = CONVERT_EXPR; } ! 1037: | PLUSPLUS ! 1038: { $$ = PREINCREMENT_EXPR; } ! 1039: | MINUSMINUS ! 1040: { $$ = PREDECREMENT_EXPR; } ! 1041: | '!' ! 1042: { $$ = TRUTH_NOT_EXPR; } ! 1043: ; ! 1044: ! 1045: expr: nonnull_exprlist ! 1046: { $$ = build_x_compound_expr ($$); } ! 1047: /* Ugly, but faster. */ ! 1048: | expr_no_commas ! 1049: ; ! 1050: ! 1051: paren_expr_or_null: ! 1052: LEFT_RIGHT ! 1053: { error ("ANSI C++ forbids an empty condition for `%s'", ! 1054: cond_stmt_keyword); ! 1055: $$ = integer_zero_node; } ! 1056: | '(' expr ')' ! 1057: { $$ = $2; } ! 1058: ; ! 1059: ! 1060: paren_cond_or_null: ! 1061: LEFT_RIGHT ! 1062: { error ("ANSI C++ forbids an empty condition for `%s'", ! 1063: cond_stmt_keyword); ! 1064: $$ = integer_zero_node; } ! 1065: | '(' condition ')' ! 1066: { $$ = $2; } ! 1067: ; ! 1068: ! 1069: xcond: ! 1070: /* empty */ ! 1071: { $$ = NULL_TREE; } ! 1072: | condition ! 1073: | error ! 1074: { $$ = NULL_TREE; } ! 1075: ; ! 1076: ! 1077: condition: ! 1078: typed_typespecs declarator maybe_raises maybeasm maybe_attribute '=' ! 1079: { { ! 1080: tree d; ! 1081: for (d = getdecls (); d; d = TREE_CHAIN (d)) ! 1082: if (TREE_CODE (d) == TYPE_DECL) { ! 1083: tree s = TREE_TYPE (d); ! 1084: if (TREE_CODE (s) == RECORD_TYPE) ! 1085: cp_error ("definition of class `%T' in condition", s); ! 1086: else if (TREE_CODE (s) == ENUMERAL_TYPE) ! 1087: cp_error ("definition of enum `%T' in condition", s); ! 1088: } ! 1089: } ! 1090: current_declspecs = $1; ! 1091: $<itype>6 = suspend_momentary (); ! 1092: $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, $3); ! 1093: cplus_decl_attributes ($<ttype>$, $5); ! 1094: } ! 1095: init ! 1096: { ! 1097: finish_decl ($<ttype>7, $8, $5, 0); ! 1098: resume_momentary ($<itype>6); ! 1099: $$ = $<ttype>7; ! 1100: if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) ! 1101: cp_error ("definition of array `%#D' in condition", $$); ! 1102: } ! 1103: | expr ! 1104: ; ! 1105: ! 1106: /* Used for the blocks controlled by a condition, to add any DECLs in ! 1107: the condition to the controlled block. */ ! 1108: .kindof_pushlevel: /* empty */ ! 1109: { tree d = getdecls (); ! 1110: emit_line_note (input_filename, lineno); ! 1111: pushlevel (0); ! 1112: clear_last_expr (); ! 1113: push_momentary (); ! 1114: expand_start_bindings (0); ! 1115: if (d) pushdecl (d); ! 1116: } ! 1117: ; ! 1118: ! 1119: /* Like implicitly_scoped_stmt, but uses .kindof_pushlevel */ ! 1120: partially_scoped_stmt: ! 1121: '{' .kindof_pushlevel '}' ! 1122: { pop_implicit_try_blocks (NULL_TREE); ! 1123: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 1124: $$ = poplevel (kept_level_p (), 1, 0); ! 1125: pop_momentary (); ! 1126: finish_stmt (); } ! 1127: | '{' .kindof_pushlevel maybe_label_decls stmts '}' ! 1128: { pop_implicit_try_blocks (NULL_TREE); ! 1129: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 1130: $$ = poplevel (kept_level_p (), 1, 0); ! 1131: pop_momentary (); ! 1132: finish_stmt (); } ! 1133: | '{' .kindof_pushlevel maybe_label_decls error '}' ! 1134: { pop_implicit_try_blocks (NULL_TREE); ! 1135: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 1136: $$ = poplevel (kept_level_p (), 0, 0); ! 1137: pop_momentary (); ! 1138: finish_stmt (); } ! 1139: | .kindof_pushlevel simple_stmt ! 1140: { pop_implicit_try_blocks (NULL_TREE); ! 1141: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 1142: $$ = poplevel (kept_level_p (), 1, 0); ! 1143: pop_momentary (); } ! 1144: ; ! 1145: ! 1146: already_scoped_stmt: ! 1147: '{' '}' ! 1148: { finish_stmt (); } ! 1149: | '{' maybe_label_decls stmts '}' ! 1150: { finish_stmt (); } ! 1151: | '{' maybe_label_decls error '}' ! 1152: { finish_stmt (); } ! 1153: | simple_stmt ! 1154: ; ! 1155: ! 1156: nonnull_exprlist: ! 1157: expr_no_commas ! 1158: { $$ = build_tree_list (NULL_TREE, $$); } ! 1159: | nonnull_exprlist ',' expr_no_commas ! 1160: { chainon ($$, build_tree_list (NULL_TREE, $3)); } ! 1161: | nonnull_exprlist ',' error ! 1162: { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); } ! 1163: ; ! 1164: ! 1165: unary_expr: ! 1166: primary %prec UNARY ! 1167: { ! 1168: if (TREE_CODE ($$) == TYPE_EXPR) ! 1169: $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1); ! 1170: } ! 1171: /* __extension__ turns off -pedantic for following primary. */ ! 1172: | EXTENSION ! 1173: { $<itype>1 = pedantic; ! 1174: pedantic = 0; } ! 1175: cast_expr %prec UNARY ! 1176: { $$ = $3; ! 1177: pedantic = $<itype>1; } ! 1178: | '*' cast_expr %prec UNARY ! 1179: { $$ = build_x_indirect_ref ($2, "unary *"); } ! 1180: | '&' cast_expr %prec UNARY ! 1181: { $$ = build_x_unary_op (ADDR_EXPR, $2); } ! 1182: | '~' cast_expr %prec UNARY ! 1183: { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } ! 1184: | unop cast_expr %prec UNARY ! 1185: { $$ = build_x_unary_op ((enum tree_code) $$, $2); ! 1186: if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST) ! 1187: TREE_NEGATED_INT ($$) = 1; ! 1188: overflow_warning ($$); ! 1189: } ! 1190: /* Refer to the address of a label as a pointer. */ ! 1191: | ANDAND identifier ! 1192: { tree label = lookup_label ($2); ! 1193: if (label == NULL_TREE) ! 1194: $$ = null_pointer_node; ! 1195: else ! 1196: { ! 1197: TREE_USED (label) = 1; ! 1198: $$ = build1 (ADDR_EXPR, ptr_type_node, label); ! 1199: TREE_CONSTANT ($$) = 1; ! 1200: } ! 1201: } ! 1202: | SIZEOF unary_expr %prec UNARY ! 1203: { if (TREE_CODE ($2) == COMPONENT_REF ! 1204: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1))) ! 1205: error ("sizeof applied to a bit-field"); ! 1206: /* ANSI says arrays and functions are converted inside comma. ! 1207: But we can't really convert them in build_compound_expr ! 1208: because that would break commas in lvalues. ! 1209: So do the conversion here if operand was a comma. */ ! 1210: if (TREE_CODE ($2) == COMPOUND_EXPR ! 1211: && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE ! 1212: || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE)) ! 1213: $2 = default_conversion ($2); ! 1214: else if (TREE_CODE ($2) == TREE_LIST) ! 1215: { ! 1216: tree t = TREE_VALUE ($2); ! 1217: if (t != NULL_TREE ! 1218: && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) ! 1219: pedwarn ("ANSI C++ forbids using sizeof() on a function"); ! 1220: } ! 1221: $$ = c_sizeof (TREE_TYPE ($2)); } ! 1222: | SIZEOF '(' typename ')' %prec HYPERUNARY ! 1223: { $$ = c_sizeof (groktypename ($3)); } ! 1224: | ALIGNOF unary_expr %prec UNARY ! 1225: { $$ = grok_alignof ($2); } ! 1226: | ALIGNOF '(' typename ')' %prec HYPERUNARY ! 1227: { $$ = c_alignof (groktypename ($3)); } ! 1228: ! 1229: | .scope new typename %prec '=' ! 1230: { $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); } ! 1231: | .scope new '(' nonnull_exprlist ')' typename %prec '=' ! 1232: { $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); } ! 1233: | .scope new typespec '(' nonnull_exprlist ')' ! 1234: { $$ = build_new ($2, $3, $5, $$ != NULL_TREE); } ! 1235: | .scope new typespec '(' typespec ')' ! 1236: { cp_error ("`%T' is not a valid expression", $5); ! 1237: $$ = error_mark_node; } ! 1238: | .scope new '(' nonnull_exprlist ')' typespec '(' nonnull_exprlist ')' ! 1239: { $$ = build_new ($4, $6, $8, $$ != NULL_TREE); } ! 1240: | .scope new typespec LEFT_RIGHT ! 1241: { $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); } ! 1242: | .scope new '(' nonnull_exprlist ')' typespec LEFT_RIGHT ! 1243: { $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); } ! 1244: | .scope new typename '=' init %prec '=' ! 1245: { $$ = build_new ($2, $3, $5, $$ != NULL_TREE); } ! 1246: | .scope new '(' nonnull_exprlist ')' typename '=' init %prec '=' ! 1247: { $$ = build_new ($4, $6, $8, $$ != NULL_TREE); } ! 1248: ! 1249: /* I am not going to add placement syntax to the below complex rules ! 1250: because Ken says the syntax is illegal. (mrs) */ ! 1251: /* I'm not sure why this is disallowed. But since it is, and it ! 1252: doesn't seem difficult to catch it, let's give a message, so ! 1253: the programmer can fix it. --Ken Raeburn */ ! 1254: | .scope new '(' typed_typespecs absdcl ')' '[' nonmomentary_expr ']' ! 1255: { ! 1256: tree absdcl, typename; ! 1257: ! 1258: illegal_new_array: ! 1259: absdcl = build_parse_node (ARRAY_REF, $5, $8); ! 1260: typename = build_decl_list ($4, absdcl); ! 1261: pedwarn ("ANSI C++ forbids array dimensions with parenthesized type"); ! 1262: $$ = build_new ($2, typename, NULL_TREE, $$ != NULL_TREE); ! 1263: } ! 1264: | .scope new '(' nonempty_type_quals absdcl ')' '[' nonmomentary_expr ']' ! 1265: { goto illegal_new_array; } ! 1266: ! 1267: | .scope new '(' typed_typespecs absdcl ')' ! 1268: { $$ = build_new ($2, build_decl_list ($4, $5), NULL_TREE, $$ != NULL_TREE); } ! 1269: | .scope new '(' nonnull_exprlist ')' '(' typed_typespecs absdcl ')' ! 1270: { $$ = build_new ($4, build_decl_list ($7, $8), NULL_TREE, $$ != NULL_TREE); } ! 1271: | .scope new '(' nonempty_type_quals absdcl ')' ! 1272: { $$ = build_new ($2, build_decl_list ($4, $5), NULL_TREE, $$ != NULL_TREE); } ! 1273: | .scope new '(' nonnull_exprlist ')' '(' nonempty_type_quals absdcl ')' ! 1274: { $$ = build_new ($4, build_decl_list ($7, $8), NULL_TREE, $$ != NULL_TREE); } ! 1275: /* Unswallow a ':' which is probably meant for ?: expression. */ ! 1276: | .scope new TYPENAME_COLON ! 1277: { yyungetc (':', 1); $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); } ! 1278: | .scope new '(' nonnull_exprlist ')' TYPENAME_COLON ! 1279: { yyungetc (':', 1); $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); } ! 1280: ! 1281: | delete cast_expr %prec UNARY ! 1282: { $$ = delete_sanity ($2, NULL_TREE, 0); } ! 1283: | delete '[' ']' cast_expr %prec UNARY ! 1284: { $$ = delete_sanity ($4, NULL_TREE, 1); ! 1285: if (yychar == YYEMPTY) ! 1286: yychar = YYLEX; } ! 1287: %ifcplus ! 1288: | delete '[' expr ']' cast_expr %prec UNARY ! 1289: { $$ = delete_sanity ($5, $3, 2); ! 1290: if (yychar == YYEMPTY) ! 1291: yychar = YYLEX; } ! 1292: %endifcplus ! 1293: %ifobjc ! 1294: | delete objc_openbracket.expr objc_closebracket cast_expr %prec UNARY ! 1295: { $$ = delete_sanity ($4, $2, 2); ! 1296: if (yychar == YYEMPTY) ! 1297: yychar = YYLEX; } ! 1298: %endifobjc ! 1299: ; ! 1300: ! 1301: cast_expr: ! 1302: unary_expr ! 1303: | '(' typename ')' expr_no_commas %prec UNARY ! 1304: { tree type = groktypename ($2); ! 1305: $$ = build_c_cast (type, $4); } ! 1306: | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY ! 1307: { tree type = groktypename ($2); ! 1308: tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)); ! 1309: if (pedantic) ! 1310: pedwarn ("ANSI C++ forbids constructor-expressions"); ! 1311: /* Indicate that this was a GNU C constructor expression. */ ! 1312: TREE_HAS_CONSTRUCTOR (init) = 1; ! 1313: $$ = digest_init (type, init, (tree *) 0); ! 1314: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) ! 1315: { ! 1316: int failure = complete_array_type (type, $$, 1); ! 1317: if (failure) ! 1318: my_friendly_abort (78); ! 1319: } ! 1320: } ! 1321: | HEADOF '(' expr ')' ! 1322: { $$ = build_headof ($3); } ! 1323: | CLASSOF '(' expr ')' ! 1324: { $$ = build_classof ($3); } ! 1325: | CLASSOF '(' TYPENAME ')' ! 1326: { if (is_aggr_typedef ($3, 1)) ! 1327: { ! 1328: tree type = IDENTIFIER_TYPE_VALUE ($3); ! 1329: $$ = CLASSTYPE_DOSSIER (type); ! 1330: } ! 1331: else ! 1332: $$ = error_mark_node; ! 1333: } ! 1334: ; ! 1335: ! 1336: expr_no_commas: ! 1337: cast_expr ! 1338: | expr_no_commas '+' expr_no_commas ! 1339: { $$ = build_x_binary_op ($2, $$, $3); } ! 1340: | expr_no_commas '-' expr_no_commas ! 1341: { $$ = build_x_binary_op ($2, $$, $3); } ! 1342: | expr_no_commas '*' expr_no_commas ! 1343: { $$ = build_x_binary_op ($2, $$, $3); } ! 1344: | expr_no_commas '/' expr_no_commas ! 1345: { $$ = build_x_binary_op ($2, $$, $3); } ! 1346: | expr_no_commas '%' expr_no_commas ! 1347: { $$ = build_x_binary_op ($2, $$, $3); } ! 1348: | expr_no_commas LSHIFT expr_no_commas ! 1349: { $$ = build_x_binary_op ($2, $$, $3); } ! 1350: | expr_no_commas RSHIFT expr_no_commas ! 1351: { $$ = build_x_binary_op ($2, $$, $3); } ! 1352: | expr_no_commas ARITHCOMPARE expr_no_commas ! 1353: { $$ = build_x_binary_op ($2, $$, $3); } ! 1354: | expr_no_commas '<' expr_no_commas ! 1355: { $$ = build_x_binary_op (LT_EXPR, $$, $3); } ! 1356: | expr_no_commas '>' expr_no_commas ! 1357: { $$ = build_x_binary_op (GT_EXPR, $$, $3); } ! 1358: | expr_no_commas EQCOMPARE expr_no_commas ! 1359: { $$ = build_x_binary_op ($2, $$, $3); } ! 1360: | expr_no_commas MIN_MAX expr_no_commas ! 1361: { $$ = build_x_binary_op ($2, $$, $3); } ! 1362: | expr_no_commas '&' expr_no_commas ! 1363: { $$ = build_x_binary_op ($2, $$, $3); } ! 1364: | expr_no_commas '|' expr_no_commas ! 1365: { $$ = build_x_binary_op ($2, $$, $3); } ! 1366: | expr_no_commas '^' expr_no_commas ! 1367: { $$ = build_x_binary_op ($2, $$, $3); } ! 1368: | expr_no_commas ANDAND expr_no_commas ! 1369: { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } ! 1370: | expr_no_commas OROR expr_no_commas ! 1371: { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } ! 1372: | expr_no_commas '?' xexpr ':' expr_no_commas ! 1373: { $$ = build_x_conditional_expr ($$, $3, $5); } ! 1374: | expr_no_commas '=' expr_no_commas ! 1375: { $$ = build_modify_expr ($$, NOP_EXPR, $3); } ! 1376: | expr_no_commas ASSIGN expr_no_commas ! 1377: { register tree rval; ! 1378: if (rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3, ! 1379: make_node ($2))) ! 1380: $$ = rval; ! 1381: else ! 1382: $$ = build_modify_expr ($$, $2, $3); } ! 1383: | primary DOT_STAR expr_no_commas %prec UNARY ! 1384: { $$ = build_m_component_ref ($$, $3); } ! 1385: /* Handle general members. */ ! 1386: | object_star expr_no_commas %prec UNARY ! 1387: { $$ = build_x_binary_op (MEMBER_REF, $$, $2); } ! 1388: /* These extensions are not defined. The second arg to build_m_component_ref ! 1389: is old, build_m_component_ref now does an implicit ! 1390: build_indirect_ref (x, NULL_PTR) on the second argument. ! 1391: | object '&' expr_no_commas %prec UNARY ! 1392: { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); } ! 1393: | object unop expr_no_commas %prec UNARY ! 1394: { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); } ! 1395: | object '(' typename ')' expr_no_commas %prec UNARY ! 1396: { tree type = groktypename ($3); ! 1397: $$ = build_m_component_ref ($$, build_c_cast (type, $5)); } ! 1398: | object primary_no_id %prec UNARY ! 1399: { $$ = build_m_component_ref ($$, $2); } ! 1400: */ ! 1401: ; ! 1402: ! 1403: primary: ! 1404: IDENTIFIER ! 1405: { $$ = do_identifier ($$); } ! 1406: | operator_name ! 1407: { ! 1408: tree op = $$; ! 1409: if (TREE_CODE (op) != IDENTIFIER_NODE) ! 1410: $$ = op; ! 1411: else ! 1412: { ! 1413: $$ = lookup_name (op, 0); ! 1414: if ($$ == NULL_TREE) ! 1415: { ! 1416: if (op != ansi_opname[ERROR_MARK]) ! 1417: error ("operator %s not defined", ! 1418: operator_name_string (op)); ! 1419: $$ = error_mark_node; ! 1420: } ! 1421: } ! 1422: } ! 1423: | CONSTANT ! 1424: | string ! 1425: { $$ = combine_strings ($$); } ! 1426: | '(' expr ')' ! 1427: { $$ = $2; } ! 1428: | '(' error ')' ! 1429: { $$ = error_mark_node; } ! 1430: | '(' ! 1431: { if (current_function_decl == 0) ! 1432: { ! 1433: error ("braced-group within expression allowed only inside a function"); ! 1434: YYERROR; ! 1435: } ! 1436: keep_next_level (); ! 1437: $<ttype>$ = expand_start_stmt_expr (); } ! 1438: compstmt ')' ! 1439: { tree rtl_exp; ! 1440: if (pedantic) ! 1441: pedwarn ("ANSI C++ forbids braced-groups within expressions"); ! 1442: rtl_exp = expand_end_stmt_expr ($<ttype>2); ! 1443: /* The statements have side effects, so the group does. */ ! 1444: TREE_SIDE_EFFECTS (rtl_exp) = 1; ! 1445: /* Make a BIND_EXPR for the BLOCK already made. */ ! 1446: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), ! 1447: NULL_TREE, rtl_exp, $3); ! 1448: /* Remove the block from the tree at this point. ! 1449: It gets put back at the proper place ! 1450: when the BIND_EXPR is expanded. */ ! 1451: delete_block ($3); ! 1452: } ! 1453: | primary '(' nonnull_exprlist ')' ! 1454: { /* [eichin:19911016.1902EST] */ ! 1455: $<ttype>$ = build_x_function_call ($1, $3, current_class_decl); ! 1456: /* here we instantiate_class_template as needed... */ ! 1457: do_pending_templates (); ! 1458: } template_instantiate_some { ! 1459: if (TREE_CODE ($<ttype>5) == CALL_EXPR ! 1460: && TREE_TYPE ($<ttype>5) != void_type_node) ! 1461: $$ = require_complete_type ($<ttype>5); ! 1462: else ! 1463: $$ = $<ttype>5; ! 1464: } ! 1465: | primary LEFT_RIGHT ! 1466: { ! 1467: $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); ! 1468: if (TREE_CODE ($$) == CALL_EXPR ! 1469: && TREE_TYPE ($$) != void_type_node) ! 1470: $$ = require_complete_type ($$); ! 1471: } ! 1472: | primary '[' expr ']' ! 1473: { do_array: ! 1474: $$ = grok_array_decl ($$, $3); } ! 1475: | object identifier_or_opname %prec UNARY ! 1476: { $$ = build_component_ref ($$, $2, NULL_TREE, 1); } ! 1477: | object id_scope identifier_or_opname %prec UNARY ! 1478: { $$ = build_object_ref ($$, $2, $3); } ! 1479: | primary PLUSPLUS ! 1480: { /* If we get an OFFSET_REF, turn it into what it really ! 1481: means (e.g., a COMPONENT_REF). This way if we've got, ! 1482: say, a reference to a static member that's being operated ! 1483: on, we don't end up trying to find a member operator for ! 1484: the class it's in. */ ! 1485: if (TREE_CODE ($$) == OFFSET_REF) ! 1486: $$ = resolve_offset_ref ($$); ! 1487: $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } ! 1488: | primary MINUSMINUS ! 1489: { if (TREE_CODE ($$) == OFFSET_REF) ! 1490: $$ = resolve_offset_ref ($$); ! 1491: $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } ! 1492: /* C++ extensions */ ! 1493: | THIS ! 1494: { if (current_class_decl) ! 1495: { ! 1496: #ifdef WARNING_ABOUT_CCD ! 1497: TREE_USED (current_class_decl) = 1; ! 1498: #endif ! 1499: $$ = current_class_decl; ! 1500: } ! 1501: else if (current_function_decl ! 1502: && DECL_STATIC_FUNCTION_P (current_function_decl)) ! 1503: { ! 1504: error ("`this' is unavailable for static member functions"); ! 1505: $$ = error_mark_node; ! 1506: } ! 1507: else ! 1508: { ! 1509: if (current_function_decl) ! 1510: error ("invalid use of `this' in non-member function"); ! 1511: else ! 1512: error ("invalid use of `this' at top level"); ! 1513: $$ = error_mark_node; ! 1514: } ! 1515: } ! 1516: | TYPE_QUAL '(' nonnull_exprlist ')' ! 1517: { ! 1518: tree type; ! 1519: tree id = $$; ! 1520: ! 1521: /* This is a C cast in C++'s `functional' notation. */ ! 1522: if ($3 == error_mark_node) ! 1523: { ! 1524: $$ = error_mark_node; ! 1525: break; ! 1526: } ! 1527: #if 0 ! 1528: if ($3 == NULL_TREE) ! 1529: { ! 1530: error ("cannot cast null list to type `%s'", ! 1531: IDENTIFIER_POINTER (TYPE_NAME (id))); ! 1532: $$ = error_mark_node; ! 1533: break; ! 1534: } ! 1535: #endif ! 1536: #if 0 ! 1537: /* type is not set! (mrs) */ ! 1538: if (type == error_mark_node) ! 1539: $$ = error_mark_node; ! 1540: else ! 1541: #endif ! 1542: { ! 1543: if (id == ridpointers[(int) RID_CONST]) ! 1544: type = build_type_variant (integer_type_node, 1, 0); ! 1545: else if (id == ridpointers[(int) RID_VOLATILE]) ! 1546: type = build_type_variant (integer_type_node, 0, 1); ! 1547: #if 0 ! 1548: /* should not be able to get here (mrs) */ ! 1549: else if (id == ridpointers[(int) RID_FRIEND]) ! 1550: { ! 1551: error ("cannot cast expression to `friend' type"); ! 1552: $$ = error_mark_node; ! 1553: break; ! 1554: } ! 1555: #endif ! 1556: else my_friendly_abort (79); ! 1557: $$ = build_c_cast (type, build_compound_expr ($3)); ! 1558: } ! 1559: } ! 1560: | typespec '(' nonnull_exprlist ')' ! 1561: { $$ = build_functional_cast ($$, $3); } ! 1562: | typespec LEFT_RIGHT ! 1563: { $$ = build_functional_cast ($$, NULL_TREE); } ! 1564: /* Stroustrup RTTI */ ! 1565: | DYNAMIC_CAST '<' typename '>' '(' expr ')' ! 1566: { tree type = groktypename ($3); ! 1567: $$ = build_dynamic_cast (type, $6); } ! 1568: | TYPEID '(' expr ')' ! 1569: { $$ = build_typeid ($3); } ! 1570: | TYPEID '(' typename ')' ! 1571: { tree type = groktypename ($3); ! 1572: $$ = get_typeid (type); } ! 1573: | SCOPE typespec '(' nonnull_exprlist ')' ! 1574: { $$ = build_functional_cast ($2, $4); } ! 1575: | SCOPE typespec LEFT_RIGHT ! 1576: { $$ = build_functional_cast ($2, NULL_TREE); } ! 1577: | SCOPE IDENTIFIER ! 1578: { ! 1579: do_scoped_id: ! 1580: $$ = IDENTIFIER_GLOBAL_VALUE ($2); ! 1581: if (yychar == YYEMPTY) ! 1582: yychar = YYLEX; ! 1583: if (! $$) ! 1584: { ! 1585: if (yychar == '(' || yychar == LEFT_RIGHT) ! 1586: $$ = implicitly_declare ($2); ! 1587: else ! 1588: { ! 1589: if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node) ! 1590: error ("undeclared variable `%s' (first use here)", ! 1591: IDENTIFIER_POINTER ($2)); ! 1592: $$ = error_mark_node; ! 1593: /* Prevent repeated error messages. */ ! 1594: IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node; ! 1595: } ! 1596: } ! 1597: else ! 1598: { ! 1599: if (TREE_CODE ($$) == ADDR_EXPR) ! 1600: assemble_external (TREE_OPERAND ($$, 0)); ! 1601: else ! 1602: assemble_external ($$); ! 1603: TREE_USED ($$) = 1; ! 1604: } ! 1605: if (TREE_CODE ($$) == CONST_DECL) ! 1606: { ! 1607: /* XXX CHS - should we set TREE_USED of the constant? */ ! 1608: $$ = DECL_INITIAL ($$); ! 1609: /* This is to prevent an enum whose value is 0 ! 1610: from being considered a null pointer constant. */ ! 1611: $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$); ! 1612: TREE_CONSTANT ($$) = 1; ! 1613: } ! 1614: ! 1615: } ! 1616: /* p->int::~int() is valid -- 12.4 */ ! 1617: | object '~' TYPESPEC LEFT_RIGHT ! 1618: { ! 1619: if (TREE_CODE (TREE_TYPE ($1)) ! 1620: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))) ! 1621: cp_error ("`%E' is not of type `%T'", $1, $3); ! 1622: $$ = void_zero_node; ! 1623: } ! 1624: | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT ! 1625: { ! 1626: if ($2 != $5) ! 1627: cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5); ! 1628: if (TREE_CODE (TREE_TYPE ($1)) ! 1629: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2)))) ! 1630: cp_error ("`%E' is not of type `%T'", $1, $2); ! 1631: $$ = void_zero_node; ! 1632: } ! 1633: | SCOPE operator_name ! 1634: { ! 1635: if (TREE_CODE ($2) == IDENTIFIER_NODE) ! 1636: goto do_scoped_id; ! 1637: do_scoped_operator: ! 1638: $$ = $2; ! 1639: } ! 1640: | id_scope identifier_or_opname %prec HYPERUNARY ! 1641: { $$ = build_offset_ref ($$, $2); } ! 1642: | id_scope identifier_or_opname '(' nonnull_exprlist ')' ! 1643: { $$ = build_member_call ($$, $2, $4); } ! 1644: | id_scope identifier_or_opname LEFT_RIGHT ! 1645: { $$ = build_member_call ($$, $2, NULL_TREE); } ! 1646: | object identifier_or_opname '(' nonnull_exprlist ')' ! 1647: { ! 1648: #if 0 ! 1649: /* This is a future direction of this code, but because ! 1650: build_x_function_call cannot always undo what is done ! 1651: in build_component_ref entirely yet, we cannot do this. */ ! 1652: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, $$); ! 1653: if (TREE_CODE ($$) == CALL_EXPR ! 1654: && TREE_TYPE ($$) != void_type_node) ! 1655: $$ = require_complete_type ($$); ! 1656: #else ! 1657: $$ = build_method_call ($$, $2, $4, NULL_TREE, ! 1658: (LOOKUP_NORMAL|LOOKUP_AGGR)); ! 1659: #endif ! 1660: } ! 1661: | object identifier_or_opname LEFT_RIGHT ! 1662: { ! 1663: #if 0 ! 1664: /* This is a future direction of this code, but because ! 1665: build_x_function_call cannot always undo what is done ! 1666: in build_component_ref entirely yet, we cannot do this. */ ! 1667: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, $$); ! 1668: if (TREE_CODE ($$) == CALL_EXPR ! 1669: && TREE_TYPE ($$) != void_type_node) ! 1670: $$ = require_complete_type ($$); ! 1671: #else ! 1672: $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE, ! 1673: (LOOKUP_NORMAL|LOOKUP_AGGR)); ! 1674: #endif ! 1675: } ! 1676: | object id_scope identifier_or_opname '(' nonnull_exprlist ')' ! 1677: { $$ = build_scoped_method_call ($$, $2, $3, $5); } ! 1678: | object id_scope identifier_or_opname LEFT_RIGHT ! 1679: { $$ = build_scoped_method_call ($$, $2, $3, NULL_TREE); } ! 1680: ! 1681: %ifobjc ! 1682: /* Objective-C expressions */ ! 1683: | objcmessageexpr ! 1684: { $$ = build_message_expr ($1); } ! 1685: | objcselectorexpr ! 1686: { $$ = build_selector_expr ($1); } ! 1687: | objcprotocolexpr ! 1688: { $$ = build_protocol_expr ($1); } ! 1689: | objcencodeexpr ! 1690: { $$ = build_encode_expr ($1); } ! 1691: | objc_string ! 1692: { $$ = build_objc_string_object ($1); } ! 1693: %endifobjc ! 1694: ; ! 1695: ! 1696: /* Not needed for now. ! 1697: ! 1698: primary_no_id: ! 1699: '(' expr ')' ! 1700: { $$ = $2; } ! 1701: | '(' error ')' ! 1702: { $$ = error_mark_node; } ! 1703: | '(' ! 1704: { if (current_function_decl == 0) ! 1705: { ! 1706: error ("braced-group within expression allowed only inside a function"); ! 1707: YYERROR; ! 1708: } ! 1709: $<ttype>$ = expand_start_stmt_expr (); } ! 1710: compstmt ')' ! 1711: { if (pedantic) ! 1712: pedwarn ("ANSI C++ forbids braced-groups within expressions"); ! 1713: $$ = expand_end_stmt_expr ($<ttype>2); } ! 1714: | primary_no_id '(' nonnull_exprlist ')' ! 1715: { $$ = build_x_function_call ($$, $3, current_class_decl); } ! 1716: | primary_no_id LEFT_RIGHT ! 1717: { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); } ! 1718: | primary_no_id '[' expr ']' ! 1719: { goto do_array; } ! 1720: | primary_no_id PLUSPLUS ! 1721: { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } ! 1722: | primary_no_id MINUSMINUS ! 1723: { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } ! 1724: | SCOPE IDENTIFIER ! 1725: { goto do_scoped_id; } ! 1726: | SCOPE operator_name ! 1727: { if (TREE_CODE ($2) == IDENTIFIER_NODE) ! 1728: goto do_scoped_id; ! 1729: goto do_scoped_operator; ! 1730: } ! 1731: ; ! 1732: */ ! 1733: ! 1734: new: NEW ! 1735: { $$ = NULL_TREE; } ! 1736: | NEW '{' nonnull_exprlist '}' ! 1737: { ! 1738: $$ = $3; ! 1739: pedwarn ("old style placement syntax, use () instead"); ! 1740: } ! 1741: ; ! 1742: ! 1743: .scope: ! 1744: /* empty */ ! 1745: { $$ = 0; } ! 1746: | SCOPE ! 1747: { $$ = 1; } ! 1748: ; ! 1749: ! 1750: delete: DELETE ! 1751: { $$ = NULL_TREE; } ! 1752: | SCOPE delete ! 1753: { if ($2) ! 1754: error ("extra `::' before `delete' ignored"); ! 1755: $$ = error_mark_node; ! 1756: } ! 1757: ; ! 1758: ! 1759: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ ! 1760: string: ! 1761: STRING ! 1762: | string STRING ! 1763: { $$ = chainon ($$, $2); } ! 1764: ; ! 1765: ! 1766: %ifobjc ! 1767: /* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained ! 1768: onto it. */ ! 1769: objc_string: ! 1770: OBJC_STRING ! 1771: | objc_string OBJC_STRING ! 1772: { $$ = chainon ($1, $2); } ! 1773: ; ! 1774: %endifobjc ! 1775: ! 1776: nodecls: ! 1777: /* empty */ ! 1778: { ! 1779: if (! current_function_parms_stored) ! 1780: store_parm_decls (); ! 1781: setup_vtbl_ptr (); ! 1782: /* Always keep the BLOCK node associated with the outermost ! 1783: pair of curley braces of a function. These are needed ! 1784: for correct operation of dwarfout.c. */ ! 1785: keep_next_level (); ! 1786: } ! 1787: ; ! 1788: ! 1789: object: primary '.' ! 1790: | primary POINTSAT ! 1791: { ! 1792: $$ = build_x_arrow ($$); ! 1793: } ! 1794: ; ! 1795: ! 1796: object_star: primary POINTSAT_STAR ! 1797: ; ! 1798: ! 1799: decl: ! 1800: typed_declspecs initdecls ';' ! 1801: { ! 1802: resume_momentary ($2); ! 1803: note_list_got_semicolon ($<ttype>$); ! 1804: } ! 1805: /* Normal case: make this fast. */ ! 1806: | typed_declspecs declarator ';' ! 1807: { tree d; ! 1808: int yes = suspend_momentary (); ! 1809: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE); ! 1810: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 1811: resume_momentary (yes); ! 1812: note_list_got_semicolon ($<ttype>$); ! 1813: } ! 1814: | declmods notype_initdecls ';' ! 1815: { resume_momentary ((int) $<itype>2); } ! 1816: /* Normal case: make this fast. */ ! 1817: | declmods declarator ';' ! 1818: { tree d; ! 1819: int yes = suspend_momentary (); ! 1820: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE); ! 1821: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 1822: resume_momentary (yes); ! 1823: } ! 1824: | typed_declspecs ';' ! 1825: { ! 1826: shadow_tag ($<ttype>$); ! 1827: note_list_got_semicolon ($<ttype>$); ! 1828: } ! 1829: | declmods ';' ! 1830: { warning ("empty declaration"); } ! 1831: ; ! 1832: ! 1833: /* Any kind of declarator (thus, all declarators allowed ! 1834: after an explicit typespec). */ ! 1835: ! 1836: declarator: ! 1837: after_type_declarator ! 1838: | notype_declarator ! 1839: | START_DECLARATOR after_type_declarator ! 1840: { $$ = $2; } ! 1841: | START_DECLARATOR notype_declarator ! 1842: { $$ = $2; } ! 1843: ; ! 1844: ! 1845: /* Declspecs which contain at least one type specifier or typedef name. ! 1846: (Just `const' or `volatile' is not enough.) ! 1847: A typedef'd name following these is taken as a name to be declared. */ ! 1848: ! 1849: typed_declspecs: ! 1850: typespec %prec HYPERUNARY ! 1851: { if ($$) $$ = list_hash_lookup_or_cons ($$); } ! 1852: | declmods typespec ! 1853: { $$ = hash_tree_chain ($2, $$); } ! 1854: | typespec reserved_declspecs %prec HYPERUNARY ! 1855: { $$ = hash_tree_chain ($$, $2); } ! 1856: | declmods typespec reserved_declspecs ! 1857: { $$ = hash_tree_chain ($2, hash_chainon ($3, $$)); } ! 1858: ; ! 1859: ! 1860: reserved_declspecs: /* empty ! 1861: { $$ = NULL_TREE; } */ ! 1862: typespecqual_reserved ! 1863: { $$ = build_decl_list (NULL_TREE, $$); } ! 1864: | SCSPEC ! 1865: { if (extra_warnings) ! 1866: warning ("`%s' is not at beginning of declaration", ! 1867: IDENTIFIER_POINTER ($$)); ! 1868: $$ = build_decl_list (NULL_TREE, $$); } ! 1869: | reserved_declspecs typespecqual_reserved ! 1870: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1871: | reserved_declspecs SCSPEC ! 1872: { if (extra_warnings) ! 1873: warning ("`%s' is not at beginning of declaration", ! 1874: IDENTIFIER_POINTER ($2)); ! 1875: $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1876: ; ! 1877: ! 1878: /* List of just storage classes and type modifiers. ! 1879: A declaration can start with just this, but then it cannot be used ! 1880: to redeclare a typedef-name. */ ! 1881: ! 1882: declmods: ! 1883: TYPE_QUAL ! 1884: { $$ = IDENTIFIER_AS_LIST ($$); ! 1885: TREE_STATIC ($$) = 1; } ! 1886: | SCSPEC ! 1887: { $$ = IDENTIFIER_AS_LIST ($$); } ! 1888: | declmods TYPE_QUAL ! 1889: { $$ = hash_tree_chain ($2, $$); ! 1890: TREE_STATIC ($$) = 1; } ! 1891: | declmods SCSPEC ! 1892: { if (extra_warnings && TREE_STATIC ($$)) ! 1893: warning ("`%s' is not at beginning of declaration", ! 1894: IDENTIFIER_POINTER ($2)); ! 1895: $$ = hash_tree_chain ($2, $$); ! 1896: TREE_STATIC ($$) = TREE_STATIC ($1); } ! 1897: ; ! 1898: ! 1899: ! 1900: /* Used instead of declspecs where storage classes are not allowed ! 1901: (that is, for typenames and structure components). ! 1902: ! 1903: C++ can takes storage classes for structure components. ! 1904: Don't accept a typedef-name if anything but a modifier precedes it. */ ! 1905: ! 1906: typed_typespecs: ! 1907: typespec %prec EMPTY ! 1908: { $$ = get_decl_list ($$); } ! 1909: | nonempty_type_quals typespec ! 1910: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1911: | typespec reserved_typespecquals ! 1912: { $$ = decl_tree_cons (NULL_TREE, $$, $2); } ! 1913: | nonempty_type_quals typespec reserved_typespecquals ! 1914: { $$ = decl_tree_cons (NULL_TREE, $2, hash_chainon ($3, $$)); } ! 1915: ; ! 1916: ! 1917: reserved_typespecquals: ! 1918: typespecqual_reserved ! 1919: { $$ = get_decl_list ($$); } ! 1920: | reserved_typespecquals typespecqual_reserved ! 1921: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1922: ; ! 1923: ! 1924: /* A typespec (but not a type qualifier). ! 1925: Once we have seen one of these in a declaration, ! 1926: if a typedef name appears then it is being redeclared. */ ! 1927: ! 1928: typespec: structsp ! 1929: | TYPESPEC %prec EMPTY ! 1930: | TYPENAME %prec EMPTY ! 1931: %ifobjc ! 1932: | CLASSNAME protocolrefs ! 1933: { $$ = get_static_reference ($1, $2); } ! 1934: | OBJECTNAME protocolrefs ! 1935: { $$ = get_object_reference ($2); } ! 1936: %endifobjc ! 1937: | scoped_typename ! 1938: | TYPEOF '(' expr ')' ! 1939: { $$ = TREE_TYPE ($3); ! 1940: if (pedantic) ! 1941: pedwarn ("ANSI C++ forbids `typeof'"); } ! 1942: | TYPEOF '(' typename ')' ! 1943: { $$ = groktypename ($3); ! 1944: if (pedantic) ! 1945: pedwarn ("ANSI C++ forbids `typeof'"); } ! 1946: | template_type ! 1947: ; ! 1948: ! 1949: /* A typespec that is a reserved word, or a type qualifier. */ ! 1950: ! 1951: typespecqual_reserved: TYPESPEC ! 1952: | TYPE_QUAL ! 1953: | structsp ! 1954: ; ! 1955: ! 1956: initdecls: ! 1957: initdcl0 ! 1958: | initdecls ',' initdcl ! 1959: ; ! 1960: ! 1961: notype_initdecls: ! 1962: notype_initdcl0 ! 1963: | notype_initdecls ',' initdcl ! 1964: ; ! 1965: ! 1966: maybeasm: ! 1967: /* empty */ ! 1968: { $$ = NULL_TREE; } ! 1969: | asm_keyword '(' string ')' ! 1970: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } ! 1971: ; ! 1972: ! 1973: initdcl0: ! 1974: declarator maybe_raises maybeasm maybe_attribute '=' ! 1975: { current_declspecs = $<ttype>0; ! 1976: $<itype>5 = suspend_momentary (); ! 1977: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); ! 1978: cplus_decl_attributes ($<ttype>$, $4); } ! 1979: init ! 1980: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1981: { finish_decl ($<ttype>6, $7, $3, 0); ! 1982: $$ = $<itype>5; } ! 1983: | declarator maybe_raises maybeasm maybe_attribute ! 1984: { tree d; ! 1985: current_declspecs = $<ttype>0; ! 1986: $$ = suspend_momentary (); ! 1987: d = start_decl ($<ttype>1, current_declspecs, 0, $2); ! 1988: cplus_decl_attributes (d, $4); ! 1989: finish_decl (d, NULL_TREE, $3, 0); } ! 1990: ; ! 1991: ! 1992: initdcl: ! 1993: declarator maybe_raises maybeasm maybe_attribute '=' ! 1994: { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); ! 1995: cplus_decl_attributes ($<ttype>$, $4); } ! 1996: init ! 1997: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1998: { finish_decl ($<ttype>6, $7, $3, 0); } ! 1999: | declarator maybe_raises maybeasm maybe_attribute ! 2000: { tree d = start_decl ($<ttype>1, current_declspecs, 0, $2); ! 2001: cplus_decl_attributes ($<ttype>$, $4); ! 2002: finish_decl (d, NULL_TREE, $3, 0); } ! 2003: ; ! 2004: ! 2005: notype_initdcl0: ! 2006: notype_declarator maybe_raises maybeasm maybe_attribute '=' ! 2007: { current_declspecs = $<ttype>0; ! 2008: $<itype>5 = suspend_momentary (); ! 2009: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); ! 2010: cplus_decl_attributes ($<ttype>$, $4); } ! 2011: init ! 2012: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 2013: { finish_decl ($<ttype>6, $7, $3, 0); ! 2014: $$ = $<itype>5; } ! 2015: | notype_declarator maybe_raises maybeasm maybe_attribute ! 2016: { tree d; ! 2017: current_declspecs = $<ttype>0; ! 2018: $$ = suspend_momentary (); ! 2019: d = start_decl ($<ttype>1, current_declspecs, 0, $2); ! 2020: cplus_decl_attributes (d, $4); ! 2021: finish_decl (d, NULL_TREE, $3, 0); } ! 2022: ; ! 2023: ! 2024: /* the * rules are dummies to accept the Apollo extended syntax ! 2025: so that the header files compile. */ ! 2026: maybe_attribute: ! 2027: /* empty */ ! 2028: { $$ = NULL_TREE; } ! 2029: | ATTRIBUTE '(' '(' attribute_list ')' ')' ! 2030: { $$ = $4; } ! 2031: ; ! 2032: ! 2033: attribute_list ! 2034: : attrib ! 2035: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ! 2036: | attribute_list ',' attrib ! 2037: { $$ = tree_cons (NULL_TREE, $3, $1); } ! 2038: ; ! 2039: ! 2040: attrib ! 2041: : IDENTIFIER ! 2042: { if (strcmp (IDENTIFIER_POINTER ($1), "packed") ! 2043: && strcmp (IDENTIFIER_POINTER ($1), "noreturn")) ! 2044: warning ("`%s' attribute directive ignored", ! 2045: IDENTIFIER_POINTER ($1)); ! 2046: $$ = $1; } ! 2047: | IDENTIFIER '(' CONSTANT ')' ! 2048: { /* if not "aligned(n)", then issue warning */ ! 2049: if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0 ! 2050: || TREE_CODE ($3) != INTEGER_CST) ! 2051: { ! 2052: warning ("`%s' attribute directive ignored", ! 2053: IDENTIFIER_POINTER ($1)); ! 2054: $$ = $1; ! 2055: } ! 2056: else ! 2057: $$ = tree_cons ($1, $3, NULL_TREE); } ! 2058: | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')' ! 2059: { /* if not "format(...)", then issue warning */ ! 2060: if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0 ! 2061: || TREE_CODE ($5) != INTEGER_CST ! 2062: || TREE_CODE ($7) != INTEGER_CST) ! 2063: { ! 2064: warning ("`%s' attribute directive ignored", ! 2065: IDENTIFIER_POINTER ($1)); ! 2066: $$ = $1; ! 2067: } ! 2068: else ! 2069: $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7, NULL_TREE), NULL_TREE), NULL_TREE); } ! 2070: ; ! 2071: ! 2072: /* A nonempty list of identifiers, including typenames. */ ! 2073: identifiers_or_typenames: ! 2074: identifier ! 2075: { $$ = build_tree_list (NULL_TREE, $1); } ! 2076: | identifiers_or_typenames ',' identifier ! 2077: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 2078: ; ! 2079: ! 2080: init: ! 2081: expr_no_commas %prec '=' ! 2082: | '{' '}' ! 2083: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); ! 2084: TREE_HAS_CONSTRUCTOR ($$) = 1; ! 2085: if (pedantic) ! 2086: pedwarn ("ANSI C++ forbids empty initializer braces"); } ! 2087: | '{' initlist '}' ! 2088: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); ! 2089: TREE_HAS_CONSTRUCTOR ($$) = 1; } ! 2090: | '{' initlist ',' '}' ! 2091: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); ! 2092: TREE_HAS_CONSTRUCTOR ($$) = 1; } ! 2093: | error ! 2094: { $$ = NULL_TREE; } ! 2095: ; ! 2096: ! 2097: /* This chain is built in reverse order, ! 2098: and put in forward order where initlist is used. */ ! 2099: initlist: ! 2100: init ! 2101: { $$ = build_tree_list (NULL_TREE, $$); } ! 2102: | initlist ',' init ! 2103: { $$ = tree_cons (NULL_TREE, $3, $$); } ! 2104: %ifcplus ! 2105: /* These are for labeled elements. */ ! 2106: | '[' expr_no_commas ']' init ! 2107: { $$ = build_tree_list ($2, $4); } ! 2108: %endifcplus ! 2109: | initlist ',' CASE expr_no_commas ':' init ! 2110: { $$ = tree_cons ($4, $6, $$); } ! 2111: | identifier ':' init ! 2112: { $$ = build_tree_list ($$, $3); } ! 2113: | initlist ',' identifier ':' init ! 2114: { $$ = tree_cons ($3, $5, $$); } ! 2115: ; ! 2116: ! 2117: structsp: ! 2118: ENUM identifier '{' ! 2119: { $<itype>3 = suspend_momentary (); ! 2120: $$ = start_enum ($2); } ! 2121: enumlist maybecomma_warn '}' ! 2122: { $$ = finish_enum ($<ttype>4, $5); ! 2123: resume_momentary ((int) $<itype>3); ! 2124: check_for_missing_semicolon ($<ttype>4); } ! 2125: | ENUM identifier '{' '}' ! 2126: { $$ = finish_enum (start_enum ($2), NULL_TREE); ! 2127: check_for_missing_semicolon ($$); } ! 2128: | ENUM '{' ! 2129: { $<itype>2 = suspend_momentary (); ! 2130: $$ = start_enum (make_anon_name ()); } ! 2131: enumlist maybecomma_warn '}' ! 2132: { $$ = finish_enum ($<ttype>3, $4); ! 2133: resume_momentary ((int) $<itype>1); ! 2134: check_for_missing_semicolon ($<ttype>3); } ! 2135: | ENUM '{' '}' ! 2136: { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE); ! 2137: check_for_missing_semicolon ($$); } ! 2138: | ENUM identifier ! 2139: { $$ = xref_tag (enum_type_node, $2, NULL_TREE); } ! 2140: ! 2141: /* C++ extensions, merged with C to avoid shift/reduce conflicts */ ! 2142: | class_head left_curly opt.component_decl_list '}' ! 2143: { ! 2144: int semi; ! 2145: tree id; ! 2146: ! 2147: #if 0 ! 2148: /* Need to rework class nesting in the ! 2149: presence of nested classes, etc. */ ! 2150: shadow_tag (CLASSTYPE_AS_LIST ($$)); */ ! 2151: #endif ! 2152: if (yychar == YYEMPTY) ! 2153: yychar = YYLEX; ! 2154: semi = yychar == ';'; ! 2155: /* finish_struct nukes this anyway; if ! 2156: finish_exception does too, then it can go. */ ! 2157: if (semi) ! 2158: note_got_semicolon ($$); ! 2159: ! 2160: if (TREE_CODE ($$) == ENUMERAL_TYPE) ! 2161: /* $$ = $1 from default rule. */; ! 2162: else if (CLASSTYPE_DECLARED_EXCEPTION ($$)) ! 2163: { ! 2164: if (! semi) ! 2165: $$ = finish_exception ($$, $3); ! 2166: else ! 2167: warning ("empty exception declaration\n"); ! 2168: } ! 2169: else ! 2170: { ! 2171: $$ = finish_struct ($$, $3, semi); ! 2172: if (semi) note_got_semicolon ($$); ! 2173: } ! 2174: ! 2175: pop_obstacks (); ! 2176: ! 2177: id = TYPE_IDENTIFIER ($$); ! 2178: if (id && IDENTIFIER_TEMPLATE (id)) ! 2179: { ! 2180: tree decl; ! 2181: ! 2182: /* I don't know if the copying of this TYPE_DECL is ! 2183: * really needed. However, it's such a small per- ! 2184: * formance penalty that the extra safety is a bargain. ! 2185: * - [email protected] ! 2186: */ ! 2187: push_obstacks (&permanent_obstack, &permanent_obstack); ! 2188: decl = copy_node (lookup_name (id, 0)); ! 2189: if (DECL_LANG_SPECIFIC (decl)) ! 2190: copy_lang_decl (decl); ! 2191: pop_obstacks (); ! 2192: undo_template_name_overload (id, 0); ! 2193: pushdecl_top_level (decl); ! 2194: } ! 2195: if (! semi) ! 2196: check_for_missing_semicolon ($$); } ! 2197: | class_head %prec EMPTY ! 2198: { ! 2199: #if 0 ! 2200: /* It's no longer clear what the following error is supposed to ! 2201: accomplish. If it turns out to be needed, add a comment why. */ ! 2202: if (TYPE_BINFO_BASETYPES ($$) && !TYPE_SIZE ($$)) ! 2203: { ! 2204: error ("incomplete definition of type `%s'", ! 2205: TYPE_NAME_STRING ($$)); ! 2206: $$ = error_mark_node; ! 2207: } ! 2208: #endif ! 2209: } ! 2210: ; ! 2211: ! 2212: maybecomma: ! 2213: /* empty */ ! 2214: | ',' ! 2215: ; ! 2216: ! 2217: maybecomma_warn: ! 2218: /* empty */ ! 2219: | ',' ! 2220: { if (pedantic) pedwarn ("comma at end of enumerator list"); } ! 2221: ; ! 2222: ! 2223: aggr: AGGR ! 2224: | aggr SCSPEC ! 2225: { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } ! 2226: | aggr TYPESPEC ! 2227: { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } ! 2228: | aggr TYPE_QUAL ! 2229: { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } ! 2230: | aggr AGGR ! 2231: { error ("no body nor ';' separates two class, struct or union declarations"); } ! 2232: ; ! 2233: ! 2234: named_class_head_sans_basetype: ! 2235: aggr identifier ! 2236: { aggr1: current_aggr = $$; $$ = $2; } ! 2237: | aggr template_type_name %prec EMPTY ! 2238: { current_aggr = $$; $$ = $2; } ! 2239: | aggr TYPENAME_COLON ! 2240: { yyungetc (':', 1); goto aggr1; } ! 2241: | aggr template_type_name '{' ! 2242: { yyungetc ('{', 1); ! 2243: aggr2: ! 2244: current_aggr = $$; ! 2245: $$ = $2; ! 2246: overload_template_name ($$, 0); } ! 2247: | aggr template_type_name ':' ! 2248: { yyungetc (':', 1); goto aggr2; } ! 2249: ; ! 2250: ! 2251: named_class_head_sans_basetype_defn: ! 2252: aggr identifier_defn ! 2253: { current_aggr = $$; $$ = $2; } ! 2254: ; ! 2255: ! 2256: named_class_head: ! 2257: named_class_head_sans_basetype ! 2258: { ! 2259: $<ttype>$ = xref_tag (current_aggr, $1, NULL_TREE); ! 2260: } ! 2261: maybe_base_class_list %prec EMPTY ! 2262: { ! 2263: if ($3) ! 2264: $$ = xref_tag (current_aggr, $1, $3); ! 2265: else ! 2266: $$ = $<ttype>2; ! 2267: } ! 2268: | ! 2269: named_class_head_sans_basetype_defn ! 2270: { ! 2271: $<ttype>$ = xref_defn_tag (current_aggr, $1, NULL_TREE); ! 2272: } ! 2273: maybe_base_class_list %prec EMPTY ! 2274: { ! 2275: if ($3) ! 2276: $$ = xref_defn_tag (current_aggr, $1, $3); ! 2277: else ! 2278: $$ = $<ttype>2; ! 2279: } ! 2280: ; ! 2281: ! 2282: unnamed_class_head: aggr '{' ! 2283: { $$ = xref_tag ($$, make_anon_name (), NULL_TREE); ! 2284: yyungetc ('{', 1); } ! 2285: ; ! 2286: ! 2287: class_head: unnamed_class_head | named_class_head ; ! 2288: ! 2289: maybe_base_class_list: ! 2290: /* empty */ ! 2291: { $$ = NULL_TREE; } ! 2292: | ':' %prec EMPTY ! 2293: { yyungetc(':', 1); $$ = NULL_TREE; } ! 2294: | ':' base_class_list %prec EMPTY ! 2295: { $$ = $2; } ! 2296: ; ! 2297: ! 2298: base_class_list: ! 2299: base_class ! 2300: | base_class_list ',' base_class ! 2301: { $$ = chainon ($$, $3); } ! 2302: ; ! 2303: ! 2304: base_class: ! 2305: base_class.1 ! 2306: { if (! is_aggr_typedef ($$, 1)) ! 2307: $$ = NULL_TREE; ! 2308: else $$ = build_tree_list ((tree)visibility_default, $$); } ! 2309: | scoped_base_class ! 2310: { if (! is_aggr_typedef ($$, 1)) ! 2311: $$ = NULL_TREE; ! 2312: else $$ = build_tree_list ((tree)visibility_default, $$); } ! 2313: | base_class_visibility_list base_class.1 ! 2314: { if (! is_aggr_typedef ($2, 1)) ! 2315: $$ = NULL_TREE; ! 2316: else $$ = build_tree_list ((tree) $$, $2); } ! 2317: | base_class_visibility_list scoped_base_class ! 2318: { if (! is_aggr_typedef ($2, 1)) ! 2319: $$ = NULL_TREE; ! 2320: else $$ = build_tree_list ((tree) $$, $2); } ! 2321: ; ! 2322: ! 2323: scoped_base_class: ! 2324: base_class.1 SCOPED_TYPENAME ! 2325: { ! 2326: /* Kludge!!! See rule "template_type" and the code ! 2327: * dealing with "template_type_seen_before_scope" in ! 2328: * yylex(). */ ! 2329: $$ = $2; ! 2330: } ! 2331: ; ! 2332: base_class.1: ! 2333: template_type_name tmpl.2 template_instantiation ! 2334: { ! 2335: extern tree template_type_seen_before_scope; ! 2336: tree id = $3 ? TYPE_IDENTIFIER ($3) : $1; ! 2337: ! 2338: /* Check the rule template_type to get this... */ ! 2339: if (yychar == YYEMPTY) ! 2340: yychar = YYLEX; ! 2341: if (yychar == SCOPE) { ! 2342: template_type_seen_before_scope = id; ! 2343: yychar = YYLEX; ! 2344: } ! 2345: } ! 2346: | identifier ! 2347: ; ! 2348: ! 2349: base_class_visibility_list: ! 2350: VISSPEC ! 2351: | SCSPEC ! 2352: { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL]) ! 2353: sorry ("non-virtual visibility"); ! 2354: $$ = visibility_default_virtual; } ! 2355: | base_class_visibility_list VISSPEC ! 2356: { int err = 0; ! 2357: if ($2 == visibility_protected) ! 2358: { ! 2359: warning ("`protected' visibility not implemented"); ! 2360: $2 = visibility_public; ! 2361: err++; ! 2362: } ! 2363: else if ($2 == visibility_public) ! 2364: { ! 2365: if ($1 == visibility_private) ! 2366: { ! 2367: mixed: ! 2368: error ("base class cannot be public and private"); ! 2369: } ! 2370: else if ($1 == visibility_default_virtual) ! 2371: $$ = visibility_public_virtual; ! 2372: } ! 2373: else /* $2 == visibility_private */ ! 2374: { ! 2375: if ($1 == visibility_public) ! 2376: goto mixed; ! 2377: else if ($1 == visibility_default_virtual) ! 2378: $$ = visibility_private_virtual; ! 2379: } ! 2380: } ! 2381: | base_class_visibility_list SCSPEC ! 2382: { if ($2 != ridpointers[(int)RID_VIRTUAL]) ! 2383: sorry ("non-virtual visibility"); ! 2384: if ($$ == visibility_public) ! 2385: $$ = visibility_public_virtual; ! 2386: else if ($$ == visibility_private) ! 2387: $$ = visibility_private_virtual; } ! 2388: ; ! 2389: ! 2390: left_curly: '{' ! 2391: { tree t; ! 2392: push_obstacks_nochange (); ! 2393: end_temporary_allocation (); ! 2394: ! 2395: if (! IS_AGGR_TYPE ($<ttype>0)) ! 2396: { ! 2397: $<ttype>0 = make_lang_type (RECORD_TYPE); ! 2398: TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type"); ! 2399: } ! 2400: if (TYPE_SIZE ($<ttype>0)) ! 2401: duplicate_tag_error ($<ttype>0); ! 2402: if (TYPE_SIZE ($<ttype>0) || TYPE_BEING_DEFINED ($<ttype>0)) ! 2403: { ! 2404: t = make_lang_type (TREE_CODE ($<ttype>0)); ! 2405: pushtag (TYPE_IDENTIFIER ($<ttype>0), t); ! 2406: $<ttype>0 = t; ! 2407: } ! 2408: pushclass ($<ttype>0, 0); ! 2409: TYPE_BEING_DEFINED ($<ttype>0) = 1; ! 2410: t = TYPE_IDENTIFIER ($<ttype>0); ! 2411: if (t && IDENTIFIER_TEMPLATE (t)) ! 2412: overload_template_name (t, 1); ! 2413: } ! 2414: ; ! 2415: ! 2416: opt.component_decl_list: ! 2417: /* empty */ ! 2418: { $$ = NULL_TREE; } ! 2419: | component_decl_list ! 2420: { $$ = build_tree_list ((tree)visibility_default, $$); } ! 2421: | opt.component_decl_list VISSPEC ':' component_decl_list ! 2422: { $$ = chainon ($$, build_tree_list ((tree) $2, $4)); } ! 2423: | opt.component_decl_list VISSPEC ':' ! 2424: %ifobjc ! 2425: | DEFS '(' CLASSNAME ')' ! 2426: { ! 2427: tree interface = lookup_interface ($3); ! 2428: if (interface) ! 2429: $$ = get_class_ivars (interface); ! 2430: else ! 2431: { ! 2432: error ("Cannot find interface declaration for `%s'", ! 2433: IDENTIFIER_POINTER ($3)); ! 2434: $$ = error_mark_node; ! 2435: } ! 2436: } ! 2437: ; ! 2438: %endifobjc ! 2439: ! 2440: /* Note: we no longer warn about the semicolon after a component_decl_list. ! 2441: ARM $9.2 says that the semicolon is optional, and therefore allowed. */ ! 2442: component_decl_list: ! 2443: component_decl ! 2444: { if ($$ == void_type_node) $$ = NULL_TREE; } ! 2445: | component_decl_list component_decl ! 2446: { /* In pushdecl, we created a reverse list of names ! 2447: in this binding level. Make sure that the chain ! 2448: of what we're trying to add isn't the item itself ! 2449: (which can happen with what pushdecl's doing). */ ! 2450: if ($2 != NULL_TREE && $2 != void_type_node) ! 2451: { ! 2452: if (TREE_CHAIN ($2) != $$) ! 2453: $$ = chainon ($$, $2); ! 2454: else ! 2455: $$ = $2; ! 2456: } ! 2457: } ! 2458: | component_decl_list ';' ! 2459: ; ! 2460: ! 2461: component_decl: ! 2462: typed_declspecs components ';' ! 2463: { do_components: ! 2464: $$ = grok_x_components ($$, $2); ! 2465: end_exception_decls (); ! 2466: } ! 2467: | typed_declspecs '(' parmlist ')' ';' ! 2468: { $$ = groktypefield ($$, $3); } ! 2469: | typed_declspecs '(' parmlist ')' '}' ! 2470: { error ("missing ';' before right brace"); ! 2471: yyungetc ('}', 0); ! 2472: $$ = groktypefield ($$, $3); } ! 2473: | typed_declspecs LEFT_RIGHT ';' ! 2474: { $$ = groktypefield ($$, empty_parms ()); } ! 2475: | typed_declspecs LEFT_RIGHT '}' ! 2476: { error ("missing ';' before right brace"); ! 2477: yyungetc ('}', 0); ! 2478: $$ = groktypefield ($$, empty_parms ()); } ! 2479: | declmods components ';' ! 2480: { goto do_components; } ! 2481: /* Normal case: make this fast. */ ! 2482: | declmods declarator ';' ! 2483: { $$ = grokfield ($<ttype>2, $<ttype>$, ! 2484: NULL_TREE, NULL_TREE, NULL_TREE); } ! 2485: | declmods components '}' ! 2486: { error ("missing ';' before right brace"); ! 2487: yyungetc ('}', 0); ! 2488: goto do_components; } ! 2489: | declmods '(' parmlist ')' ';' ! 2490: { $$ = groktypefield ($$, $3); } ! 2491: | declmods '(' parmlist ')' '}' ! 2492: { error ("missing ';' before right brace"); ! 2493: yyungetc ('}', 0); ! 2494: $$ = groktypefield ($$, $3); } ! 2495: | declmods LEFT_RIGHT ';' ! 2496: { $$ = groktypefield ($$, empty_parms ()); } ! 2497: | declmods LEFT_RIGHT '}' ! 2498: { error ("missing ';' before right brace"); ! 2499: yyungetc ('}', 0); ! 2500: $$ = groktypefield ($$, empty_parms ()); } ! 2501: | ':' expr_no_commas ';' ! 2502: { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } ! 2503: | ':' expr_no_commas '}' ! 2504: { error ("missing ';' before right brace"); ! 2505: yyungetc ('}', 0); ! 2506: $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } ! 2507: | error ! 2508: { $$ = NULL_TREE; } ! 2509: ! 2510: /* C++: handle constructors, destructors and inline functions */ ! 2511: /* note that INLINE is like a TYPESPEC */ ! 2512: | fn.def2 ':' /* base_init compstmt */ ! 2513: { $$ = finish_method ($$); } ! 2514: | fn.def2 '{' /* nodecls compstmt */ ! 2515: { $$ = finish_method ($$); } ! 2516: | notype_declarator maybe_raises ';' ! 2517: { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); } ! 2518: | notype_declarator maybe_raises '}' ! 2519: { error ("missing ';' before right brace"); ! 2520: yyungetc ('}', 0); ! 2521: $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); } ! 2522: ; ! 2523: ! 2524: components: ! 2525: /* empty: possibly anonymous */ ! 2526: { $$ = NULL_TREE; } ! 2527: | component_declarator0 ! 2528: | components ',' component_declarator ! 2529: { ! 2530: /* In this context, void_type_node encodes ! 2531: friends. They have been recorded elsewhere. */ ! 2532: if ($$ == void_type_node) ! 2533: $$ = $3; ! 2534: else ! 2535: $$ = chainon ($$, $3); ! 2536: } ! 2537: ; ! 2538: ! 2539: component_declarator0: ! 2540: declarator maybe_raises maybeasm maybe_attribute ! 2541: { current_declspecs = $<ttype>0; ! 2542: $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); ! 2543: cplus_decl_attributes ($$, $4); } ! 2544: | declarator maybe_raises maybeasm maybe_attribute '=' init ! 2545: { current_declspecs = $<ttype>0; ! 2546: $$ = grokfield ($$, current_declspecs, $2, $6, $3); ! 2547: cplus_decl_attributes ($$, $4); } ! 2548: | IDENTIFIER ':' expr_no_commas maybe_attribute ! 2549: { current_declspecs = $<ttype>0; ! 2550: $$ = grokbitfield ($$, current_declspecs, $3); ! 2551: cplus_decl_attributes ($$, $4); } ! 2552: | TYPENAME ':' expr_no_commas maybe_attribute ! 2553: { current_declspecs = $<ttype>0; ! 2554: $$ = grokbitfield ($$, current_declspecs, $3); ! 2555: cplus_decl_attributes ($$, $4); } ! 2556: | ':' expr_no_commas maybe_attribute ! 2557: { current_declspecs = $<ttype>0; ! 2558: $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); ! 2559: cplus_decl_attributes ($$, $3); } ! 2560: ; ! 2561: ! 2562: component_declarator: ! 2563: declarator maybe_raises maybeasm maybe_attribute ! 2564: { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); ! 2565: cplus_decl_attributes ($$, $4); } ! 2566: | declarator maybe_raises maybeasm maybe_attribute '=' init ! 2567: { $$ = grokfield ($$, current_declspecs, $2, $6, $3); ! 2568: cplus_decl_attributes ($$, $4); } ! 2569: | IDENTIFIER ':' expr_no_commas maybe_attribute ! 2570: { $$ = grokbitfield ($$, current_declspecs, $3); ! 2571: cplus_decl_attributes ($$, $4); } ! 2572: | TYPENAME ':' expr_no_commas maybe_attribute ! 2573: { $$ = grokbitfield ($$, current_declspecs, $3); ! 2574: cplus_decl_attributes ($$, $4); } ! 2575: | ':' expr_no_commas maybe_attribute ! 2576: { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); ! 2577: cplus_decl_attributes ($$, $3); } ! 2578: ; ! 2579: ! 2580: /* We chain the enumerators in reverse order. ! 2581: Because of the way enums are built, the order is ! 2582: insignificant. Take advantage of this fact. */ ! 2583: ! 2584: enumlist: ! 2585: enumerator ! 2586: | enumlist ',' enumerator ! 2587: { TREE_CHAIN ($3) = $$; $$ = $3; } ! 2588: ; ! 2589: ! 2590: enumerator: ! 2591: identifier ! 2592: { $$ = build_enumerator ($$, NULL_TREE); } ! 2593: | identifier '=' expr_no_commas ! 2594: { $$ = build_enumerator ($$, $3); } ! 2595: ; ! 2596: ! 2597: /* ANSI type-id (8.1) */ ! 2598: typename: ! 2599: typed_typespecs absdcl ! 2600: { $$ = build_decl_list ($$, $2); } ! 2601: | nonempty_type_quals absdcl ! 2602: { $$ = build_decl_list ($$, $2); } ! 2603: ; ! 2604: ! 2605: /* ANSI abstract-declarator (8.1) */ ! 2606: absdcl: /* an abstract declarator */ ! 2607: /* empty */ %prec EMPTY ! 2608: { $$ = NULL_TREE; } ! 2609: | absdcl1 %prec EMPTY ! 2610: | START_DECLARATOR absdcl1 %prec EMPTY ! 2611: { $$ = $2; } ! 2612: ; ! 2613: ! 2614: nonempty_type_quals: ! 2615: TYPE_QUAL ! 2616: { $$ = IDENTIFIER_AS_LIST ($$); } ! 2617: | nonempty_type_quals TYPE_QUAL ! 2618: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 2619: ; ! 2620: ! 2621: type_quals: ! 2622: /* empty */ ! 2623: { $$ = NULL_TREE; } ! 2624: | type_quals TYPE_QUAL ! 2625: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 2626: ; ! 2627: ! 2628: /* These rules must follow the rules for function declarations ! 2629: and component declarations. That way, longer rules are preferred. */ ! 2630: ! 2631: /* An expression which will not live on the momentary obstack. */ ! 2632: nonmomentary_expr: ! 2633: { $<itype>$ = suspend_momentary (); } expr ! 2634: { resume_momentary ((int) $<itype>1); $$ = $2; } ! 2635: ! 2636: %ifobjc ! 2637: /* This rule needs to be before after_type_declarator so that we resolve ! 2638: the reduce/reduce conflict in state 111 correctly. We need to resolve it ! 2639: the same way that vanilla C++ resolves the reduce/reduce conflict in state ! 2640: 105. That is we must assume that we are processing a typespec rather than ! 2641: an after_type_declarator when we see a TYPENAME and aren't sure. For the ! 2642: OBJECTNAME case this means we must read any protocolrefs, and then resume ! 2643: processing the typespec. */ ! 2644: protocolrefs: ! 2645: /* empty */ ! 2646: { ! 2647: $$ = NULL_TREE; ! 2648: } ! 2649: | '<' identifier_list '>' ! 2650: { ! 2651: $$ = $2; ! 2652: } ! 2653: ; ! 2654: %endifobjc ! 2655: ! 2656: /* A declarator that is allowed only after an explicit typespec. */ ! 2657: /* may all be followed by prec '.' */ ! 2658: after_type_declarator: ! 2659: after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.' ! 2660: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2661: | after_type_declarator '(' parmlist ')' type_quals %prec '.' ! 2662: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2663: | after_type_declarator LEFT_RIGHT type_quals %prec '.' ! 2664: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2665: | after_type_declarator '(' error ')' type_quals %prec '.' ! 2666: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } ! 2667: | after_type_declarator '[' nonmomentary_expr ']' ! 2668: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2669: | after_type_declarator '[' ']' ! 2670: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2671: | '(' after_type_declarator_no_typename ')' ! 2672: { $$ = $2; } ! 2673: | '(' '*' type_quals after_type_declarator ')' ! 2674: { $$ = make_pointer_declarator ($3, $4); } ! 2675: | PAREN_STAR_PAREN ! 2676: { see_typename (); } ! 2677: | after_type_member_declarator ! 2678: | '(' '&' type_quals after_type_declarator ')' ! 2679: { $$ = make_reference_declarator ($3, $4); } ! 2680: | '*' type_quals after_type_declarator %prec UNARY ! 2681: { $$ = make_pointer_declarator ($2, $3); } ! 2682: | '&' type_quals after_type_declarator %prec UNARY ! 2683: { $$ = make_reference_declarator ($2, $3); } ! 2684: | TYPENAME ! 2685: %ifobjc ! 2686: | OBJECTNAME ! 2687: %endifobjc ! 2688: ; ! 2689: ! 2690: after_type_declarator_no_typename: ! 2691: after_type_declarator_no_typename '(' nonnull_exprlist ')' type_quals %prec '.' ! 2692: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2693: | after_type_declarator_no_typename '(' parmlist ')' type_quals %prec '.' ! 2694: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2695: | after_type_declarator_no_typename LEFT_RIGHT type_quals %prec '.' ! 2696: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2697: | after_type_declarator_no_typename '(' error ')' type_quals %prec '.' ! 2698: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } ! 2699: | after_type_declarator_no_typename '[' nonmomentary_expr ']' ! 2700: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2701: | after_type_declarator_no_typename '[' ']' ! 2702: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2703: | '(' after_type_declarator_no_typename ')' ! 2704: { $$ = $2; } ! 2705: | PAREN_STAR_PAREN ! 2706: { see_typename (); } ! 2707: | after_type_member_declarator ! 2708: | '*' type_quals after_type_declarator %prec UNARY ! 2709: { $$ = make_pointer_declarator ($2, $3); } ! 2710: | '&' type_quals after_type_declarator %prec UNARY ! 2711: { $$ = make_reference_declarator ($2, $3); } ! 2712: ; ! 2713: ! 2714: /* A declarator allowed whether or not there has been ! 2715: an explicit typespec. These cannot redeclare a typedef-name. */ ! 2716: ! 2717: notype_declarator: ! 2718: notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.' ! 2719: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2720: | notype_declarator '(' parmlist ')' type_quals %prec '.' ! 2721: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2722: | notype_declarator LEFT_RIGHT type_quals %prec '.' ! 2723: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2724: | notype_declarator '(' error ')' type_quals %prec '.' ! 2725: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } ! 2726: | '(' notype_declarator ')' ! 2727: { $$ = $2; } ! 2728: | '*' type_quals notype_declarator %prec UNARY ! 2729: { $$ = make_pointer_declarator ($2, $3); } ! 2730: | '&' type_quals notype_declarator %prec UNARY ! 2731: { $$ = make_reference_declarator ($2, $3); } ! 2732: | notype_declarator '[' nonmomentary_expr ']' ! 2733: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2734: | notype_declarator '[' ']' ! 2735: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2736: | IDENTIFIER ! 2737: { see_typename (); } ! 2738: ! 2739: /* C++ extensions. */ ! 2740: | operator_name ! 2741: { see_typename (); } ! 2742: ! 2743: | '~' TYPENAME ! 2744: { ! 2745: destructor_name: ! 2746: see_typename (); ! 2747: $$ = build_parse_node (BIT_NOT_EXPR, $2); ! 2748: } ! 2749: | '~' IDENTIFIER ! 2750: { goto destructor_name; } ! 2751: | '~' PTYPENAME ! 2752: { goto destructor_name; } ! 2753: | id_scope see_typename notype_declarator %prec '(' ! 2754: { see_typename (); ! 2755: if (TREE_CODE ($$) != SCOPE_REF) ! 2756: $$ = build_push_scope ($$, $3); ! 2757: else if (TREE_OPERAND ($$, 1) == NULL_TREE) ! 2758: TREE_OPERAND ($$, 1) = $3; ! 2759: else ! 2760: $$ = build_parse_node (SCOPE_REF, $$, $3); ! 2761: } ! 2762: | id_scope see_typename TYPENAME %prec '(' ! 2763: { $$ = build_push_scope ($$, $3); } ! 2764: | id_scope see_typename TYPENAME '(' nonnull_exprlist ')' type_quals %prec '.' ! 2765: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); } ! 2766: | id_scope see_typename TYPENAME '(' parmlist ')' type_quals %prec '.' ! 2767: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); } ! 2768: | id_scope see_typename TYPENAME LEFT_RIGHT type_quals %prec '.' ! 2769: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); } ! 2770: | id_scope see_typename TYPENAME '(' error ')' type_quals %prec '.' ! 2771: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); } ! 2772: /* For constructor templates. */ ! 2773: | id_scope see_typename PTYPENAME %prec '(' ! 2774: { $$ = build_push_scope ($$, $3); } ! 2775: | id_scope see_typename PTYPENAME '(' nonnull_exprlist ')' type_quals %prec '.' ! 2776: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); } ! 2777: | id_scope see_typename PTYPENAME '(' parmlist ')' type_quals %prec '.' ! 2778: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); } ! 2779: | id_scope see_typename PTYPENAME LEFT_RIGHT type_quals %prec '.' ! 2780: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); } ! 2781: | id_scope see_typename PTYPENAME '(' error ')' type_quals %prec '.' ! 2782: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); } ! 2783: | SCOPE see_typename notype_declarator ! 2784: { $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); } ! 2785: ; ! 2786: ! 2787: id_scope: typename_scope ! 2788: { tree t; ! 2789: do_id_scope: ! 2790: ! 2791: t = resolve_scope_to_name (NULL_TREE, $$); ! 2792: if (t == NULL_TREE) ! 2793: { ! 2794: cp_error ("`%T' is not a valid scope", $$); ! 2795: $$ = error_mark_node; ! 2796: } ! 2797: else ! 2798: $$ = t; ! 2799: } ! 2800: | IDENTIFIER SCOPE ! 2801: { goto do_id_scope; } ! 2802: | template_type SCOPE /* try_for_typename %prec EMPTY */ ! 2803: { ! 2804: if ($$ == error_mark_node) ! 2805: /* leave it alone */; ! 2806: else ! 2807: { ! 2808: $$ = resolve_scope_to_name (NULL_TREE, TYPE_IDENTIFIER ($$)); ! 2809: if ($$ == NULL_TREE) ! 2810: { ! 2811: error ("undefined explicitly scoped type"); ! 2812: $$ = error_mark_node; ! 2813: } ! 2814: } ! 2815: /* if ($3) popclass (1); */ ! 2816: } ! 2817: ; ! 2818: ! 2819: typename_scope: ! 2820: TYPENAME SCOPE; ! 2821: ! 2822: scoped_typename: SCOPED_TYPENAME ! 2823: | template_type SCOPED_TYPENAME ! 2824: { ! 2825: /* Kludge!!! See rule "template_type" and the code ! 2826: * dealing with "template_type_seen_before_scope" in ! 2827: * yylex(). */ ! 2828: $$ = $2; ! 2829: } ! 2830: /* | template_type SCOPE try_for_typename TYPENAME ! 2831: { ! 2832: if ($$ == error_mark_node) ! 2833: ; ! 2834: else ! 2835: { ! 2836: $$ = build_parse_node (SCOPE_REF, ! 2837: TYPE_IDENTIFIER ($$), ! 2838: $4); ! 2839: } ! 2840: if ($3) popclass (1); ! 2841: } */ ! 2842: ; ! 2843: ! 2844: absdcl1: /* a nonempty abstract declarator */ ! 2845: '(' absdcl1 ')' ! 2846: { see_typename (); ! 2847: $$ = $2; } ! 2848: /* `(typedef)1' is `int'. */ ! 2849: | '*' type_quals absdcl1 %prec EMPTY ! 2850: { $$ = make_pointer_declarator ($2, $3); } ! 2851: | '*' type_quals %prec EMPTY ! 2852: { $$ = make_pointer_declarator ($2, NULL_TREE); } ! 2853: | PAREN_STAR_PAREN ! 2854: { see_typename (); } ! 2855: | '(' abs_member_declarator ')' ! 2856: { $$ = $2; } ! 2857: | '&' type_quals absdcl1 %prec EMPTY ! 2858: { $$ = make_reference_declarator ($2, $3); } ! 2859: | '&' type_quals %prec EMPTY ! 2860: { $$ = make_reference_declarator ($2, NULL_TREE); } ! 2861: | absdcl1 '(' parmlist ')' type_quals %prec '.' ! 2862: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2863: | absdcl1 LEFT_RIGHT type_quals %prec '.' ! 2864: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2865: | absdcl1 '[' nonmomentary_expr ']' %prec '.' ! 2866: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2867: | absdcl1 '[' ']' %prec '.' ! 2868: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2869: | '(' parmlist ')' type_quals %prec '.' ! 2870: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); } ! 2871: | LEFT_RIGHT type_quals %prec '.' ! 2872: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (), $2); } ! 2873: | '[' nonmomentary_expr ']' %prec '.' ! 2874: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } ! 2875: | '[' ']' %prec '.' ! 2876: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); } ! 2877: ; ! 2878: ! 2879: abs_member_declarator: ! 2880: id_scope see_typename '*' type_quals ! 2881: { tree t; ! 2882: t = $$; ! 2883: while (TREE_OPERAND (t, 1)) ! 2884: t = TREE_OPERAND (t, 1); ! 2885: TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, 0); ! 2886: } ! 2887: | id_scope see_typename '*' type_quals absdcl1 ! 2888: { tree t; ! 2889: t = $$; ! 2890: while (TREE_OPERAND (t, 1)) ! 2891: t = TREE_OPERAND (t, 1); ! 2892: TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, $5); ! 2893: } ! 2894: | id_scope see_typename '&' type_quals ! 2895: { tree t; ! 2896: t = $$; ! 2897: while (TREE_OPERAND (t, 1)) ! 2898: t = TREE_OPERAND (t, 1); ! 2899: TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, 0); ! 2900: } ! 2901: | id_scope see_typename '&' type_quals absdcl1 ! 2902: { tree t; ! 2903: t = $$; ! 2904: while (TREE_OPERAND (t, 1)) ! 2905: t = TREE_OPERAND (t, 1); ! 2906: TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, $5); ! 2907: } ! 2908: ; ! 2909: ! 2910: after_type_member_declarator: ! 2911: id_scope see_typename '*' type_quals after_type_declarator ! 2912: { tree t; ! 2913: t = $$; ! 2914: while (TREE_OPERAND (t, 1)) ! 2915: t = TREE_OPERAND (t, 1); ! 2916: TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, $5); ! 2917: } ! 2918: | id_scope see_typename '&' type_quals after_type_declarator ! 2919: { tree t; ! 2920: t = $$; ! 2921: while (TREE_OPERAND (t, 1)) ! 2922: t = TREE_OPERAND (t, 1); ! 2923: TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, $5); ! 2924: } ! 2925: ; ! 2926: ! 2927: /* For C++, decls and stmts can be intermixed, so we don't need to ! 2928: have a special rule that won't start parsing the stmt section ! 2929: until we have a stmt that parses without errors. */ ! 2930: ! 2931: stmts: ! 2932: stmt ! 2933: | errstmt ! 2934: | stmts stmt ! 2935: | stmts errstmt ! 2936: ; ! 2937: ! 2938: errstmt: error ';' ! 2939: ; ! 2940: ! 2941: /* build the LET_STMT node before parsing its contents, ! 2942: so that any LET_STMTs within the context can have their display pointers ! 2943: set up to point at this one. */ ! 2944: ! 2945: .pushlevel: /* empty */ ! 2946: { emit_line_note (input_filename, lineno); ! 2947: pushlevel (0); ! 2948: clear_last_expr (); ! 2949: push_momentary (); ! 2950: expand_start_bindings (0); ! 2951: %ifobjc ! 2952: if (objc_method_context) ! 2953: add_objc_decls(); ! 2954: %endifobjc ! 2955: } ! 2956: ; ! 2957: ! 2958: /* Read zero or more forward-declarations for labels ! 2959: that nested functions can jump to. */ ! 2960: maybe_label_decls: ! 2961: /* empty */ ! 2962: | label_decls ! 2963: { if (pedantic) ! 2964: pedwarn ("ANSI C++ forbids label declarations"); } ! 2965: ; ! 2966: ! 2967: label_decls: ! 2968: label_decl ! 2969: | label_decls label_decl ! 2970: ; ! 2971: ! 2972: label_decl: ! 2973: LABEL identifiers_or_typenames ';' ! 2974: { tree link; ! 2975: for (link = $2; link; link = TREE_CHAIN (link)) ! 2976: { ! 2977: tree label = shadow_label (TREE_VALUE (link)); ! 2978: C_DECLARED_LABEL_FLAG (label) = 1; ! 2979: declare_nonlocal_label (label); ! 2980: } ! 2981: } ! 2982: ; ! 2983: ! 2984: /* This is the body of a function definition. ! 2985: It causes syntax errors to ignore to the next openbrace. */ ! 2986: compstmt_or_error: ! 2987: compstmt ! 2988: {} ! 2989: | error compstmt ! 2990: ; ! 2991: ! 2992: compstmt: '{' .pushlevel '}' ! 2993: { pop_implicit_try_blocks (NULL_TREE); ! 2994: expand_end_bindings (getdecls (), kept_level_p(), 1); ! 2995: $$ = poplevel (kept_level_p (), 1, 0); ! 2996: pop_momentary (); } ! 2997: | '{' .pushlevel maybe_label_decls stmts '}' ! 2998: { pop_implicit_try_blocks (NULL_TREE); ! 2999: expand_end_bindings (getdecls (), kept_level_p(), 1); ! 3000: $$ = poplevel (kept_level_p (), 1, 0); ! 3001: pop_momentary (); } ! 3002: | '{' .pushlevel maybe_label_decls error '}' ! 3003: { pop_implicit_try_blocks (NULL_TREE); ! 3004: expand_end_bindings (getdecls (), kept_level_p(), 1); ! 3005: $$ = poplevel (kept_level_p (), 0, 0); ! 3006: pop_momentary (); } ! 3007: ; ! 3008: ! 3009: simple_if: ! 3010: IF ! 3011: { cond_stmt_keyword = "if"; } ! 3012: .pushlevel paren_cond_or_null ! 3013: { emit_line_note (input_filename, lineno); ! 3014: expand_start_cond (truthvalue_conversion ($4), 0); } ! 3015: partially_scoped_stmt ! 3016: ; ! 3017: ! 3018: implicitly_scoped_stmt: ! 3019: compstmt ! 3020: { finish_stmt (); } ! 3021: | .pushlevel simple_stmt ! 3022: { pop_implicit_try_blocks (NULL_TREE); ! 3023: expand_end_bindings (getdecls (), getdecls() != NULL_TREE, 1); ! 3024: $$ = poplevel (kept_level_p (), 1, 0); ! 3025: pop_momentary (); } ! 3026: ; ! 3027: ! 3028: stmt: ! 3029: compstmt ! 3030: { finish_stmt (); } ! 3031: | simple_stmt ! 3032: ; ! 3033: ! 3034: simple_stmt: ! 3035: decl ! 3036: { finish_stmt (); } ! 3037: | expr ';' ! 3038: { ! 3039: tree expr = $1; ! 3040: emit_line_note (input_filename, lineno); ! 3041: /* Do default conversion if safe and possibly important, ! 3042: in case within ({...}). */ ! 3043: if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE ! 3044: && lvalue_p (expr)) ! 3045: || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) ! 3046: expr = default_conversion (expr); ! 3047: cplus_expand_expr_stmt (expr); ! 3048: clear_momentary (); ! 3049: finish_stmt (); } ! 3050: | simple_if ELSE ! 3051: { expand_start_else (); } ! 3052: partially_scoped_stmt ! 3053: { expand_end_cond (); ! 3054: pop_implicit_try_blocks (NULL_TREE); ! 3055: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3056: poplevel (kept_level_p (), 1, 0); ! 3057: pop_momentary (); ! 3058: finish_stmt (); } ! 3059: | simple_if %prec IF ! 3060: { expand_end_cond (); ! 3061: pop_implicit_try_blocks (NULL_TREE); ! 3062: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3063: poplevel (kept_level_p (), 1, 0); ! 3064: pop_momentary (); ! 3065: finish_stmt (); } ! 3066: | WHILE ! 3067: { emit_nop (); ! 3068: emit_line_note (input_filename, lineno); ! 3069: expand_start_loop (1); ! 3070: cond_stmt_keyword = "while"; } ! 3071: .pushlevel paren_cond_or_null ! 3072: { expand_exit_loop_if_false (0, truthvalue_conversion ($4)); } ! 3073: already_scoped_stmt ! 3074: { pop_implicit_try_blocks (NULL_TREE); ! 3075: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3076: poplevel (kept_level_p (), 1, 0); ! 3077: pop_momentary (); ! 3078: expand_end_loop (); ! 3079: finish_stmt (); } ! 3080: | DO ! 3081: { emit_nop (); ! 3082: emit_line_note (input_filename, lineno); ! 3083: expand_start_loop_continue_elsewhere (1); } ! 3084: implicitly_scoped_stmt WHILE ! 3085: { expand_loop_continue_here (); ! 3086: cond_stmt_keyword = "do"; } ! 3087: paren_expr_or_null ';' ! 3088: { emit_line_note (input_filename, lineno); ! 3089: expand_exit_loop_if_false (0, truthvalue_conversion ($6)); ! 3090: expand_end_loop (); ! 3091: clear_momentary (); ! 3092: finish_stmt (); } ! 3093: | forhead.1 ! 3094: { emit_nop (); ! 3095: emit_line_note (input_filename, lineno); ! 3096: if ($1) cplus_expand_expr_stmt ($1); ! 3097: expand_start_loop_continue_elsewhere (1); } ! 3098: .pushlevel xcond ';' ! 3099: { emit_line_note (input_filename, lineno); ! 3100: if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); } ! 3101: xexpr ')' ! 3102: /* Don't let the tree nodes for $7 be discarded ! 3103: by clear_momentary during the parsing of the next stmt. */ ! 3104: { push_momentary (); } ! 3105: already_scoped_stmt ! 3106: { emit_line_note (input_filename, lineno); ! 3107: expand_loop_continue_here (); ! 3108: if ($7) cplus_expand_expr_stmt ($7); ! 3109: pop_momentary (); ! 3110: pop_implicit_try_blocks (NULL_TREE); ! 3111: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3112: poplevel (kept_level_p (), 1, 0); ! 3113: pop_momentary (); ! 3114: expand_end_loop (); ! 3115: finish_stmt (); } ! 3116: | forhead.2 ! 3117: { emit_nop (); ! 3118: emit_line_note (input_filename, lineno); ! 3119: expand_start_loop_continue_elsewhere (1); } ! 3120: .pushlevel xcond ';' ! 3121: { emit_line_note (input_filename, lineno); ! 3122: if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); } ! 3123: xexpr ')' ! 3124: /* Don't let the tree nodes for $7 be discarded ! 3125: by clear_momentary during the parsing of the next stmt. */ ! 3126: { push_momentary (); ! 3127: $<itype>8 = lineno; } ! 3128: already_scoped_stmt ! 3129: { emit_line_note (input_filename, (int) $<itype>8); ! 3130: expand_loop_continue_here (); ! 3131: if ($7) cplus_expand_expr_stmt ($7); ! 3132: pop_momentary (); ! 3133: pop_implicit_try_blocks (NULL_TREE); ! 3134: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3135: poplevel (kept_level_p (), 1, 0); ! 3136: pop_momentary (); ! 3137: expand_end_loop (); ! 3138: finish_stmt (); ! 3139: } ! 3140: | SWITCH .pushlevel '(' condition ')' ! 3141: { emit_line_note (input_filename, lineno); ! 3142: c_expand_start_case ($4); ! 3143: /* Don't let the tree nodes for $4 be discarded by ! 3144: clear_momentary during the parsing of the next stmt. */ ! 3145: push_momentary (); } ! 3146: partially_scoped_stmt ! 3147: { expand_end_case ($4); ! 3148: pop_momentary (); ! 3149: pop_implicit_try_blocks (NULL_TREE); ! 3150: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3151: poplevel (kept_level_p (), 1, 0); ! 3152: pop_momentary (); ! 3153: finish_stmt (); } ! 3154: | CASE expr_no_commas ':' ! 3155: { register tree value = $2; ! 3156: register tree label ! 3157: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 3158: ! 3159: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue. ! 3160: Strip such NOP_EXPRs. */ ! 3161: if (TREE_CODE (value) == NOP_EXPR ! 3162: && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0))) ! 3163: value = TREE_OPERAND (value, 0); ! 3164: ! 3165: if (TREE_READONLY_DECL_P (value)) ! 3166: { ! 3167: value = decl_constant_value (value); ! 3168: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue. ! 3169: Strip such NOP_EXPRs. */ ! 3170: if (TREE_CODE (value) == NOP_EXPR ! 3171: && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0))) ! 3172: value = TREE_OPERAND (value, 0); ! 3173: } ! 3174: value = fold (value); ! 3175: ! 3176: if (TREE_CODE (value) != INTEGER_CST ! 3177: && value != error_mark_node) ! 3178: { ! 3179: cp_error ("case label `%E' does not reduce to an integer constant", $2); ! 3180: value = error_mark_node; ! 3181: } ! 3182: else ! 3183: /* Promote char or short to int. */ ! 3184: value = default_conversion (value); ! 3185: if (value != error_mark_node) ! 3186: { ! 3187: tree duplicate; ! 3188: int success = pushcase (value, convert_and_check, ! 3189: label, &duplicate); ! 3190: if (success == 1) ! 3191: cp_error ("case label `%E' not within a switch statement", $2); ! 3192: else if (success == 2) ! 3193: { ! 3194: cp_error ("duplicate case value `%E'", $2); ! 3195: cp_error_at ("`%E' previously used here", duplicate); ! 3196: } ! 3197: else if (success == 3) ! 3198: warning ("case value out of range"); ! 3199: else if (success == 5) ! 3200: cp_error ("case label `%E' within scope of cleanup or variable array", $2); ! 3201: } ! 3202: define_case_label (label); ! 3203: } ! 3204: stmt ! 3205: | CASE expr_no_commas RANGE expr_no_commas ':' ! 3206: { register tree value1 = $2; ! 3207: register tree value2 = $4; ! 3208: register tree label ! 3209: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 3210: ! 3211: if (pedantic) ! 3212: pedwarn ("ANSI C++ forbids range expressions in switch statement"); ! 3213: ! 3214: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue. ! 3215: Strip such NOP_EXPRs. */ ! 3216: if (TREE_CODE (value1) == NOP_EXPR ! 3217: && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0))) ! 3218: value1 = TREE_OPERAND (value1, 0); ! 3219: ! 3220: if (TREE_READONLY_DECL_P (value1)) ! 3221: { ! 3222: value1 = decl_constant_value (value1); ! 3223: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue. ! 3224: Strip such NOP_EXPRs. */ ! 3225: if (TREE_CODE (value1) == NOP_EXPR ! 3226: && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0))) ! 3227: value1 = TREE_OPERAND (value1, 0); ! 3228: } ! 3229: value1 = fold (value1); ! 3230: ! 3231: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue. ! 3232: Strip such NOP_EXPRs. */ ! 3233: if (TREE_CODE (value2) == NOP_EXPR ! 3234: && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0))) ! 3235: value2 = TREE_OPERAND (value2, 0); ! 3236: ! 3237: if (TREE_READONLY_DECL_P (value2)) ! 3238: { ! 3239: value2 = decl_constant_value (value2); ! 3240: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue. ! 3241: Strip such NOP_EXPRs. */ ! 3242: if (TREE_CODE (value2) == NOP_EXPR ! 3243: && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0))) ! 3244: value2 = TREE_OPERAND (value2, 0); ! 3245: } ! 3246: value2 = fold (value2); ! 3247: ! 3248: ! 3249: if (TREE_CODE (value1) != INTEGER_CST ! 3250: && value1 != error_mark_node) ! 3251: { ! 3252: error ("case label does not reduce to an integer constant"); ! 3253: value1 = error_mark_node; ! 3254: } ! 3255: if (TREE_CODE (value2) != INTEGER_CST ! 3256: && value2 != error_mark_node) ! 3257: { ! 3258: error ("case label does not reduce to an integer constant"); ! 3259: value2 = error_mark_node; ! 3260: } ! 3261: if (value1 != error_mark_node ! 3262: && value2 != error_mark_node) ! 3263: { ! 3264: tree duplicate; ! 3265: int success = pushcase_range (value1, value2, ! 3266: convert_and_check, label, ! 3267: &duplicate); ! 3268: if (success == 1) ! 3269: error ("case label not within a switch statement"); ! 3270: else if (success == 2) ! 3271: { ! 3272: error ("duplicate (or overlapping) case value"); ! 3273: error_with_decl (duplicate, "this is the first entry overlapping that value"); ! 3274: } ! 3275: else if (success == 3) ! 3276: warning ("case value out of range"); ! 3277: else if (success == 4) ! 3278: warning ("empty range specified"); ! 3279: else if (success == 5) ! 3280: error ("case label within scope of cleanup or variable array"); ! 3281: } ! 3282: define_case_label (label); ! 3283: } ! 3284: stmt ! 3285: | DEFAULT ':' ! 3286: { ! 3287: tree duplicate; ! 3288: register tree label ! 3289: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 3290: int success = pushcase (NULL_TREE, 0, label, &duplicate); ! 3291: if (success == 1) ! 3292: error ("default label not within a switch statement"); ! 3293: else if (success == 2) ! 3294: { ! 3295: error ("multiple default labels in one switch"); ! 3296: error_with_decl (duplicate, "this is the first default label"); ! 3297: } ! 3298: define_case_label (NULL_TREE); ! 3299: } ! 3300: stmt ! 3301: | BREAK ';' ! 3302: { emit_line_note (input_filename, lineno); ! 3303: if ( ! expand_exit_something ()) ! 3304: error ("break statement not within loop or switch"); } ! 3305: | CONTINUE ';' ! 3306: { emit_line_note (input_filename, lineno); ! 3307: if (! expand_continue_loop (0)) ! 3308: error ("continue statement not within a loop"); } ! 3309: | RETURN ';' ! 3310: { emit_line_note (input_filename, lineno); ! 3311: c_expand_return (NULL_TREE); } ! 3312: | RETURN expr ';' ! 3313: { emit_line_note (input_filename, lineno); ! 3314: c_expand_return ($2); ! 3315: finish_stmt (); ! 3316: } ! 3317: | asm_keyword maybe_type_qual '(' string ')' ';' ! 3318: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3319: emit_line_note (input_filename, lineno); ! 3320: expand_asm ($4); ! 3321: finish_stmt (); ! 3322: } ! 3323: /* This is the case with just output operands. */ ! 3324: | asm_keyword maybe_type_qual '(' string ':' asm_operands ')' ';' ! 3325: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3326: emit_line_note (input_filename, lineno); ! 3327: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE, ! 3328: $2 == ridpointers[(int)RID_VOLATILE], ! 3329: input_filename, lineno); ! 3330: finish_stmt (); ! 3331: } ! 3332: /* This is the case with input operands as well. */ ! 3333: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';' ! 3334: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3335: emit_line_note (input_filename, lineno); ! 3336: c_expand_asm_operands ($4, $6, $8, NULL_TREE, ! 3337: $2 == ridpointers[(int)RID_VOLATILE], ! 3338: input_filename, lineno); ! 3339: finish_stmt (); ! 3340: } ! 3341: /* This is the case with clobbered registers as well. */ ! 3342: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':' ! 3343: asm_operands ':' asm_clobbers ')' ';' ! 3344: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3345: emit_line_note (input_filename, lineno); ! 3346: c_expand_asm_operands ($4, $6, $8, $10, ! 3347: $2 == ridpointers[(int)RID_VOLATILE], ! 3348: input_filename, lineno); ! 3349: finish_stmt (); ! 3350: } ! 3351: | GOTO '*' expr ';' ! 3352: { emit_line_note (input_filename, lineno); ! 3353: expand_computed_goto ($3); } ! 3354: | GOTO identifier ';' ! 3355: { tree decl; ! 3356: emit_line_note (input_filename, lineno); ! 3357: decl = lookup_label ($2); ! 3358: TREE_USED (decl) = 1; ! 3359: expand_goto (decl); } ! 3360: | label_colon stmt ! 3361: { finish_stmt (); } ! 3362: | label_colon '}' ! 3363: { error ("label must be followed by statement"); ! 3364: yyungetc ('}', 0); ! 3365: finish_stmt (); } ! 3366: | ';' ! 3367: { finish_stmt (); } ! 3368: ! 3369: /* Exception handling extensions. */ ! 3370: | ANSI_THROW ';' { cplus_expand_throw (NULL_TREE); } ! 3371: | ANSI_THROW expr ';' { cplus_expand_throw ($2); } ! 3372: | THROW raise_identifier '(' nonnull_exprlist ')' ';' ! 3373: { cplus_expand_raise ($2, $4, NULL_TREE, 0); ! 3374: finish_stmt (); } ! 3375: | THROW raise_identifier LEFT_RIGHT ';' ! 3376: { cplus_expand_raise ($2, NULL_TREE, NULL_TREE, 0); ! 3377: finish_stmt (); } ! 3378: | RAISE raise_identifier '(' nonnull_exprlist ')' ';' ! 3379: { cplus_expand_raise ($2, $4, NULL_TREE, 0); ! 3380: finish_stmt (); } ! 3381: | RAISE raise_identifier LEFT_RIGHT ';' ! 3382: { cplus_expand_raise ($2, NULL_TREE, NULL_TREE, 0); ! 3383: finish_stmt (); } ! 3384: | RAISE identifier ';' ! 3385: { cplus_expand_reraise ($2); ! 3386: finish_stmt (); } ! 3387: | try EXCEPT identifier '{' ! 3388: { ! 3389: tree decl = cplus_expand_end_try ($1); ! 3390: $<ttype>2 = current_exception_type; ! 3391: $<ttype>4 = current_exception_decl; ! 3392: $<ttype>$ = current_exception_object; ! 3393: cplus_expand_start_except ($3, decl); ! 3394: pushlevel (0); ! 3395: clear_last_expr (); ! 3396: push_momentary (); ! 3397: expand_start_bindings (0); ! 3398: } ! 3399: except_stmts '}' ! 3400: { ! 3401: tree decls = getdecls (); ! 3402: /* If there is a default exception to handle, ! 3403: handle it here. */ ! 3404: if ($6) ! 3405: { ! 3406: tree decl = build_decl (CPLUS_CATCH_DECL, NULL_TREE, 0); ! 3407: tree block; ! 3408: ! 3409: pushlevel (1); ! 3410: expand_start_bindings (0); ! 3411: expand_expr ($6, 0, 0, 0); ! 3412: expand_end_bindings (0, 1, 0); ! 3413: block = poplevel (1, 0, 0); ! 3414: ! 3415: /* This is a catch block. */ ! 3416: TREE_LANG_FLAG_2 (block) = 1; ! 3417: BLOCK_VARS (block) = decl; ! 3418: } ! 3419: ! 3420: expand_end_bindings (decls, decls != 0, 1); ! 3421: poplevel (decls != 0, 1, 0); ! 3422: pop_momentary (); ! 3423: current_exception_type = $<ttype>2; ! 3424: current_exception_decl = $<ttype>4; ! 3425: current_exception_object = $<ttype>5; ! 3426: cplus_expand_end_except ($6); ! 3427: } ! 3428: | try error ! 3429: { ! 3430: cplus_expand_end_try ($1); ! 3431: /* These are the important actions of ! 3432: `cplus_expand_end_except' which we must emulate. */ ! 3433: if (expand_escape_except ()) ! 3434: expand_end_except (); ! 3435: expand_end_bindings (0, 0, 1); ! 3436: poplevel (0, 0, 0); ! 3437: } ! 3438: | ansi_try ansi_dummy ansi_dummy ! 3439: { ! 3440: tree decl = cplus_expand_end_try ($1); ! 3441: $<ttype>2 = current_exception_type; ! 3442: $<ttype>3 = current_exception_decl; ! 3443: $<ttype>$ = current_exception_object; ! 3444: cplus_expand_start_except (NULL, decl); ! 3445: pushlevel (0); ! 3446: clear_last_expr (); ! 3447: push_momentary (); ! 3448: expand_start_bindings (0); ! 3449: } ! 3450: ansi_except_stmts ! 3451: { ! 3452: tree decls = getdecls (); ! 3453: /* If there is a default exception to handle, ! 3454: handle it here. */ ! 3455: if ($5) ! 3456: { ! 3457: tree decl = build_decl (CPLUS_CATCH_DECL, NULL_TREE, 0); ! 3458: tree block; ! 3459: ! 3460: pushlevel (1); ! 3461: expand_start_bindings (0); ! 3462: expand_expr ($5, 0, 0, 0); ! 3463: expand_end_bindings (0, 1, 0); ! 3464: block = poplevel (1, 0, 0); ! 3465: ! 3466: /* This is a catch block. */ ! 3467: TREE_LANG_FLAG_2 (block) = 1; ! 3468: BLOCK_VARS (block) = decl; ! 3469: } ! 3470: ! 3471: expand_end_bindings (decls, decls != 0, 1); ! 3472: poplevel (decls != 0, 1, 0); ! 3473: pop_momentary (); ! 3474: current_exception_type = $<ttype>2; ! 3475: current_exception_decl = $<ttype>3; ! 3476: current_exception_object = $<ttype>4; ! 3477: cplus_expand_end_except ($5); ! 3478: } ! 3479: | try RERAISE raise_identifiers /* ';' checked for at bottom. */ ! 3480: { tree name = get_identifier ("(compiler error)"); ! 3481: tree orig_ex_type = current_exception_type; ! 3482: tree orig_ex_decl = current_exception_decl; ! 3483: tree orig_ex_obj = current_exception_object; ! 3484: tree decl = cplus_expand_end_try ($1), decls; ! 3485: ! 3486: /* Start hidden EXCEPT. */ ! 3487: cplus_expand_start_except (name, decl); ! 3488: pushlevel (0); ! 3489: clear_last_expr (); ! 3490: push_momentary (); ! 3491: expand_start_bindings (0); ! 3492: ! 3493: /* This sets up the reraise. */ ! 3494: cplus_expand_reraise ($3); ! 3495: ! 3496: decls = getdecls (); ! 3497: expand_end_bindings (decls, decls != 0, 1); ! 3498: poplevel (decls != 0, 1, 0); ! 3499: pop_momentary (); ! 3500: current_exception_type = orig_ex_type; ! 3501: current_exception_decl = orig_ex_decl; ! 3502: current_exception_object = orig_ex_obj; ! 3503: /* This will reraise for us. */ ! 3504: cplus_expand_end_except (error_mark_node); ! 3505: if (yychar == YYEMPTY) ! 3506: yychar = YYLEX; ! 3507: if (yychar != ';') ! 3508: error ("missing ';' after reraise statement"); ! 3509: } ! 3510: | try %prec EMPTY ! 3511: { yyerror ("`except' missing after `try' statement"); ! 3512: /* Terminate the binding contour started by special ! 3513: code in `.pushlevel'. Automagically pops off ! 3514: the conditional we started for `try' stmt. */ ! 3515: cplus_expand_end_try ($1); ! 3516: expand_end_bindings (0, 0, 1); ! 3517: poplevel (0, 0, 0); ! 3518: pop_momentary (); ! 3519: YYERROR; } ! 3520: ; ! 3521: ! 3522: try: try_head '}' ! 3523: /* An empty try block is degenerate, but it's better to ! 3524: do extra work here than to do all the special-case work ! 3525: everywhere else. */ ! 3526: { ! 3527: $$ = 1; ! 3528: pop_implicit_try_blocks (NULL_TREE); ! 3529: } ! 3530: | try_head stmts '}' ! 3531: { ! 3532: $$ = 1; ! 3533: pop_implicit_try_blocks (NULL_TREE); ! 3534: } ! 3535: | try_head error '}' ! 3536: { ! 3537: $$ = 0; ! 3538: pop_implicit_try_blocks (NULL_TREE); ! 3539: } ! 3540: ; ! 3541: ! 3542: label_colon: ! 3543: IDENTIFIER ':' ! 3544: { tree label; ! 3545: do_label: ! 3546: label = define_label (input_filename, lineno, $1); ! 3547: if (label) ! 3548: expand_label (label); ! 3549: } ! 3550: | PTYPENAME ':' ! 3551: { goto do_label; } ! 3552: | TYPENAME_COLON ! 3553: { tree label = define_label (input_filename, lineno, $1); ! 3554: if (label) ! 3555: expand_label (label); ! 3556: } ! 3557: ; ! 3558: ! 3559: try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel ! 3560: ! 3561: ansi_try: ansi_try_head '}' ! 3562: /* An empty try block is degenerate, but it's better to ! 3563: do extra work here than to do all the special-case work ! 3564: everywhere else. */ ! 3565: { ! 3566: $$ = 1; ! 3567: pop_implicit_try_blocks (NULL_TREE); ! 3568: } ! 3569: | ansi_try_head stmts '}' ! 3570: { ! 3571: $$ = 1; ! 3572: pop_implicit_try_blocks (NULL_TREE); ! 3573: } ! 3574: | ansi_try_head error '}' ! 3575: { ! 3576: $$ = 0; ! 3577: pop_implicit_try_blocks (NULL_TREE); ! 3578: } ! 3579: ; ! 3580: ! 3581: ansi_dummy: ; /* Temporary place-holder. */ ! 3582: ansi_try_head: ANSI_TRY '{' { cplus_expand_start_try (0); } .pushlevel ! 3583: ! 3584: except_stmts: ! 3585: /* empty */ ! 3586: { $$ = NULL_TREE; } ! 3587: | except_stmts raise_identifier ! 3588: { ! 3589: tree type = lookup_exception_type (current_class_type, current_class_name, $2); ! 3590: if (type == NULL_TREE) ! 3591: { ! 3592: error ("`%s' is not an exception type", ! 3593: IDENTIFIER_POINTER (TREE_VALUE ($2))); ! 3594: current_exception_type = NULL_TREE; ! 3595: TREE_TYPE (current_exception_object) = error_mark_node; ! 3596: } ! 3597: else ! 3598: { ! 3599: current_exception_type = type; ! 3600: /* In-place union. */ ! 3601: TREE_TYPE (current_exception_object) = type; ! 3602: } ! 3603: $2 = cplus_expand_start_catch ($2); ! 3604: pushlevel (1); ! 3605: expand_start_bindings (0); ! 3606: } ! 3607: compstmt ! 3608: { ! 3609: expand_end_bindings (0, 1, 0); ! 3610: $4 = poplevel (1, 0, 0); ! 3611: ! 3612: cplus_expand_end_catch (0); ! 3613: ! 3614: /* Mark this as a catch block. */ ! 3615: TREE_LANG_FLAG_2 ($4) = 1; ! 3616: if ($2 != error_mark_node) ! 3617: { ! 3618: tree decl = build_decl (CPLUS_CATCH_DECL, DECL_NAME ($2), 0); ! 3619: DECL_RTL (decl) = DECL_RTL ($2); ! 3620: TREE_CHAIN (decl) = BLOCK_VARS ($4); ! 3621: BLOCK_VARS ($4) = decl; ! 3622: } ! 3623: } ! 3624: | except_stmts DEFAULT ! 3625: { ! 3626: if ($1) ! 3627: error ("duplicate default in exception handler"); ! 3628: current_exception_type = NULL_TREE; ! 3629: /* Takes it right out of scope. */ ! 3630: TREE_TYPE (current_exception_object) = error_mark_node; ! 3631: ! 3632: if (! expand_catch_default ()) ! 3633: compiler_error ("default catch botch"); ! 3634: ! 3635: /* The default exception is handled as the ! 3636: last in the chain of exceptions handled. */ ! 3637: do_pending_stack_adjust (); ! 3638: $1 = make_node (RTL_EXPR); ! 3639: TREE_TYPE ($1) = void_type_node; ! 3640: start_sequence_for_rtl_expr ($1); ! 3641: } ! 3642: compstmt ! 3643: { ! 3644: extern struct rtx_def *get_insns (); ! 3645: do_pending_stack_adjust (); ! 3646: if (! expand_catch (NULL_TREE)) ! 3647: compiler_error ("except nesting botch"); ! 3648: if (! expand_end_catch ()) ! 3649: compiler_error ("except nesting botch"); ! 3650: RTL_EXPR_SEQUENCE ($1) = get_insns (); ! 3651: if ($4) ! 3652: { ! 3653: /* Mark this block as the default catch block. */ ! 3654: TREE_LANG_FLAG_1 ($4) = 1; ! 3655: TREE_LANG_FLAG_2 ($4) = 1; ! 3656: } ! 3657: end_sequence (); ! 3658: } ! 3659: ; ! 3660: ! 3661: optional_identifier: ! 3662: /* empty */ ! 3663: { $$ = NULL_TREE; } ! 3664: | identifier ; ! 3665: ! 3666: ansi_except_stmts: ! 3667: /* empty */ ! 3668: { $$ = NULL_TREE; } ! 3669: | ansi_except_stmts CATCH '(' typename optional_identifier ')' ! 3670: { ! 3671: tree type = groktypename ($4); ! 3672: current_exception_type = type; ! 3673: /* In-place union. */ ! 3674: if ($5) ! 3675: { ! 3676: tree tmp; ! 3677: tmp = pushdecl (build_decl (VAR_DECL, $5, type)); ! 3678: current_exception_object = ! 3679: build1 (INDIRECT_REF, type, tmp); ! 3680: } ! 3681: $4 = ansi_expand_start_catch(type); ! 3682: pushlevel (1); ! 3683: expand_start_bindings (0); ! 3684: } ! 3685: compstmt ! 3686: { ! 3687: expand_end_bindings (0, 1, 0); ! 3688: $8 = poplevel (1, 0, 0); ! 3689: ! 3690: cplus_expand_end_catch (0); ! 3691: ! 3692: /* Mark this as a catch block. */ ! 3693: TREE_LANG_FLAG_2 ($8) = 1; ! 3694: if ($4 != error_mark_node) ! 3695: { ! 3696: tree decl = build_decl (CPLUS_CATCH_DECL, DECL_NAME ($4), 0); ! 3697: DECL_RTL (decl) = DECL_RTL ($4); ! 3698: TREE_CHAIN (decl) = BLOCK_VARS ($8); ! 3699: BLOCK_VARS ($8) = decl; ! 3700: } ! 3701: } ! 3702: ; ! 3703: ! 3704: forhead.1: ! 3705: FOR '(' ';' ! 3706: { $$ = NULL_TREE; } ! 3707: | FOR '(' expr ';' ! 3708: { $$ = $3; } ! 3709: | FOR '(' '{' '}' ! 3710: { $$ = NULL_TREE; } ! 3711: ; ! 3712: ! 3713: forhead.2: ! 3714: FOR '(' decl ! 3715: { $$ = 0; } ! 3716: | FOR '(' error ';' ! 3717: { $$ = 0; } ! 3718: | FOR '(' '{' .pushlevel stmts '}' ! 3719: { $$ = 1; } ! 3720: | FOR '(' '{' .pushlevel error '}' ! 3721: { $$ = -1; } ! 3722: ; ! 3723: ! 3724: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ ! 3725: ! 3726: maybe_type_qual: ! 3727: /* empty */ ! 3728: { emit_line_note (input_filename, lineno); ! 3729: $$ = NULL_TREE; } ! 3730: | TYPE_QUAL ! 3731: { emit_line_note (input_filename, lineno); } ! 3732: ; ! 3733: ! 3734: xexpr: ! 3735: /* empty */ ! 3736: { $$ = NULL_TREE; } ! 3737: | expr ! 3738: | error ! 3739: { $$ = NULL_TREE; } ! 3740: ; ! 3741: ! 3742: /* These are the operands other than the first string and colon ! 3743: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ ! 3744: asm_operands: /* empty */ ! 3745: { $$ = NULL_TREE; } ! 3746: | nonnull_asm_operands ! 3747: ; ! 3748: ! 3749: nonnull_asm_operands: ! 3750: asm_operand ! 3751: | nonnull_asm_operands ',' asm_operand ! 3752: { $$ = chainon ($$, $3); } ! 3753: ; ! 3754: ! 3755: asm_operand: ! 3756: STRING '(' expr ')' ! 3757: { $$ = build_tree_list ($$, $3); } ! 3758: ; ! 3759: ! 3760: asm_clobbers: ! 3761: STRING ! 3762: { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); } ! 3763: | asm_clobbers ',' STRING ! 3764: { $$ = tree_cons (NULL_TREE, $3, $$); } ! 3765: ; ! 3766: ! 3767: /* This is what appears inside the parens in a function declarator. ! 3768: Its value is represented in the format that grokdeclarator expects. ! 3769: ! 3770: In C++, declaring a function with no parameters ! 3771: means that that function takes *no* parameters. */ ! 3772: parmlist: /* empty */ ! 3773: { ! 3774: if (strict_prototype) ! 3775: $$ = void_list_node; ! 3776: else ! 3777: $$ = NULL_TREE; ! 3778: } ! 3779: | parms ! 3780: { ! 3781: $$ = chainon ($$, void_list_node); ! 3782: TREE_PARMLIST ($$) = 1; ! 3783: } ! 3784: | parms ',' ELLIPSIS ! 3785: { ! 3786: TREE_PARMLIST ($$) = 1; ! 3787: } ! 3788: /* C++ allows an ellipsis without a separating ',' */ ! 3789: | parms ELLIPSIS ! 3790: { ! 3791: TREE_PARMLIST ($$) = 1; ! 3792: } ! 3793: | ELLIPSIS ! 3794: { ! 3795: /* ARM $8.2.5 has this as a boxed-off comment. */ ! 3796: if (pedantic) ! 3797: warning ("use of `...' without a first argument is non-portable"); ! 3798: $$ = NULL_TREE; ! 3799: } ! 3800: | TYPENAME_ELLIPSIS ! 3801: { ! 3802: TREE_PARMLIST ($$) = 1; ! 3803: } ! 3804: | parms TYPENAME_ELLIPSIS ! 3805: { ! 3806: TREE_PARMLIST ($$) = 1; ! 3807: } ! 3808: | parms ':' ! 3809: { ! 3810: /* This helps us recover from really nasty ! 3811: parse errors, for example, a missing right ! 3812: parenthesis. */ ! 3813: yyerror ("possibly missing ')'"); ! 3814: $$ = chainon ($$, void_list_node); ! 3815: TREE_PARMLIST ($$) = 1; ! 3816: yyungetc (':', 0); ! 3817: yychar = ')'; ! 3818: } ! 3819: ; ! 3820: ! 3821: /* A nonempty list of parameter declarations or type names. */ ! 3822: parms: ! 3823: parm ! 3824: { $$ = build_tree_list (NULL_TREE, $$); } ! 3825: | parm '=' init ! 3826: { $$ = build_tree_list ($3, $$); } ! 3827: | parms ',' parm ! 3828: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } ! 3829: | parms ',' parm '=' init ! 3830: { $$ = chainon ($$, build_tree_list ($5, $3)); } ! 3831: | parms ',' bad_parm ! 3832: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } ! 3833: | parms ',' bad_parm '=' init ! 3834: { $$ = chainon ($$, build_tree_list ($5, $3)); } ! 3835: ; ! 3836: ! 3837: /* A single parameter declaration or parameter type name, ! 3838: as found in a parmlist. The first four cases make up for 10% ! 3839: of the time spent parsing C++. We cannot use them because ! 3840: of `int id[]' which won't get parsed properly. */ ! 3841: parm: ! 3842: /* ! 3843: typed_declspecs dont_see_typename '*' IDENTIFIER ! 3844: { $$ = build_tree_list ($$, build_parse_node (INDIRECT_REF, $4)); ! 3845: see_typename (); } ! 3846: | typed_declspecs dont_see_typename '&' IDENTIFIER ! 3847: { $$ = build_tree_list ($$, build_parse_node (ADDR_EXPR, $4)); ! 3848: see_typename (); } ! 3849: | TYPENAME IDENTIFIER ! 3850: { $$ = build_tree_list (list_hash_lookup_or_cons ($$), $2); } ! 3851: | TYPESPEC IDENTIFIER ! 3852: { $$ = build_tree_list (list_hash_lookup_or_cons ($$), $2); } ! 3853: | */ ! 3854: typed_declspecs dont_see_typename abs_or_notype_decl ! 3855: { $$ = build_tree_list ($$, $3); ! 3856: see_typename (); } ! 3857: | declmods dont_see_typename abs_or_notype_decl ! 3858: { $$ = build_tree_list ($$, $3); ! 3859: see_typename (); } ! 3860: ; ! 3861: ! 3862: abs_or_notype_decl: absdcl ! 3863: | notype_declarator ! 3864: | START_DECLARATOR notype_declarator ! 3865: { $$ = $2; } ! 3866: ; ! 3867: ! 3868: see_typename: type_quals ! 3869: { see_typename (); } ! 3870: ; ! 3871: ! 3872: dont_see_typename: /* empty */ ! 3873: { dont_see_typename (); } ! 3874: ; ! 3875: ! 3876: /* ! 3877: try_for_typename: ! 3878: { ! 3879: if ($<ttype>-1 == error_mark_node) ! 3880: $$ = 0; ! 3881: else ! 3882: { ! 3883: $$ = 1; ! 3884: pushclass ($<ttype>-1, 1); ! 3885: } ! 3886: } ! 3887: ; ! 3888: */ ! 3889: ! 3890: bad_parm: ! 3891: abs_or_notype_decl ! 3892: { ! 3893: warning ("type specifier omitted for parameter"); ! 3894: $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $$); ! 3895: } ! 3896: ; ! 3897: ! 3898: maybe_raises: ! 3899: /* empty */ ! 3900: { $$ = NULL_TREE; } ! 3901: | RAISES raise_identifiers %prec EMPTY ! 3902: { $$ = $2; } ! 3903: | ANSI_THROW '(' ansi_raise_identifiers ')' %prec EMPTY ! 3904: { $$ = $3; } ! 3905: ; ! 3906: ! 3907: raise_identifier: ! 3908: ALL ! 3909: { $$ = void_list_node; } ! 3910: | IDENTIFIER ! 3911: { $$ = build_decl_list (NULL_TREE, $$); } ! 3912: | TYPENAME ! 3913: { $$ = build_decl_list (NULL_TREE, $$); } ! 3914: | SCOPE IDENTIFIER ! 3915: { $$ = build_decl_list (void_type_node, $2); } ! 3916: | SCOPE TYPENAME ! 3917: { $$ = build_decl_list (void_type_node, $2); } ! 3918: %ifobjc ! 3919: | OBJECTNAME ! 3920: { $$ = build_decl_list (NULL_TREE, $$); } ! 3921: %endifobjc ! 3922: | id_scope IDENTIFIER ! 3923: { $$ = build_decl_list ($$, $2); } ! 3924: | scoped_typename ! 3925: ; ! 3926: ! 3927: ansi_raise_identifier: ! 3928: typename ! 3929: { $$ = build_decl_list (NULL_TREE, $$); } ! 3930: ; ! 3931: ! 3932: raise_identifiers: ! 3933: raise_identifier ! 3934: | raise_identifiers ',' raise_identifier ! 3935: { ! 3936: TREE_CHAIN ($3) = $$; ! 3937: $$ = $3; ! 3938: } ! 3939: ; ! 3940: ! 3941: ansi_raise_identifiers: ! 3942: ansi_raise_identifier ! 3943: | ansi_raise_identifiers ',' ansi_raise_identifier ! 3944: { ! 3945: TREE_CHAIN ($3) = $$; ! 3946: $$ = $3; ! 3947: } ! 3948: ; ! 3949: ! 3950: operator_name: ! 3951: OPERATOR '*' ! 3952: { $$ = ansi_opname[MULT_EXPR]; } ! 3953: | OPERATOR '/' ! 3954: { $$ = ansi_opname[TRUNC_DIV_EXPR]; } ! 3955: | OPERATOR '%' ! 3956: { $$ = ansi_opname[TRUNC_MOD_EXPR]; } ! 3957: | OPERATOR '+' ! 3958: { $$ = ansi_opname[PLUS_EXPR]; } ! 3959: | OPERATOR '-' ! 3960: { $$ = ansi_opname[MINUS_EXPR]; } ! 3961: | OPERATOR '&' ! 3962: { $$ = ansi_opname[BIT_AND_EXPR]; } ! 3963: | OPERATOR '|' ! 3964: { $$ = ansi_opname[BIT_IOR_EXPR]; } ! 3965: | OPERATOR '^' ! 3966: { $$ = ansi_opname[BIT_XOR_EXPR]; } ! 3967: | OPERATOR '~' ! 3968: { $$ = ansi_opname[BIT_NOT_EXPR]; } ! 3969: | OPERATOR ',' ! 3970: { $$ = ansi_opname[COMPOUND_EXPR]; } ! 3971: | OPERATOR ARITHCOMPARE ! 3972: { $$ = ansi_opname[$2]; } ! 3973: | OPERATOR '<' ! 3974: { $$ = ansi_opname[LT_EXPR]; } ! 3975: | OPERATOR '>' ! 3976: { $$ = ansi_opname[GT_EXPR]; } ! 3977: | OPERATOR EQCOMPARE ! 3978: { $$ = ansi_opname[$2]; } ! 3979: | OPERATOR ASSIGN ! 3980: { $$ = ansi_assopname[$2]; } ! 3981: | OPERATOR '=' ! 3982: { ! 3983: $$ = ansi_opname [MODIFY_EXPR]; ! 3984: if (current_class_type) ! 3985: { ! 3986: TYPE_HAS_ASSIGNMENT (current_class_type) = 1; ! 3987: TYPE_GETS_ASSIGNMENT (current_class_type) = 1; ! 3988: } ! 3989: } ! 3990: | OPERATOR LSHIFT ! 3991: { $$ = ansi_opname[$2]; } ! 3992: | OPERATOR RSHIFT ! 3993: { $$ = ansi_opname[$2]; } ! 3994: | OPERATOR PLUSPLUS ! 3995: { $$ = ansi_opname[POSTINCREMENT_EXPR]; } ! 3996: | OPERATOR MINUSMINUS ! 3997: { $$ = ansi_opname[PREDECREMENT_EXPR]; } ! 3998: | OPERATOR ANDAND ! 3999: { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; } ! 4000: | OPERATOR OROR ! 4001: { $$ = ansi_opname[TRUTH_ORIF_EXPR]; } ! 4002: | OPERATOR '!' ! 4003: { $$ = ansi_opname[TRUTH_NOT_EXPR]; } ! 4004: | OPERATOR '?' ':' ! 4005: { $$ = ansi_opname[COND_EXPR]; } ! 4006: | OPERATOR MIN_MAX ! 4007: { $$ = ansi_opname[$2]; } ! 4008: | OPERATOR POINTSAT %prec EMPTY ! 4009: { $$ = ansi_opname[COMPONENT_REF]; ! 4010: if (current_class_type) ! 4011: { ! 4012: tree t = current_class_type; ! 4013: while (t) ! 4014: { ! 4015: TYPE_OVERLOADS_ARROW (t) = 1; ! 4016: t = TYPE_NEXT_VARIANT (t); ! 4017: } ! 4018: } ! 4019: } ! 4020: | OPERATOR POINTSAT_STAR %prec EMPTY ! 4021: { $$ = ansi_opname[MEMBER_REF]; ! 4022: if (current_class_type) ! 4023: { ! 4024: tree t = current_class_type; ! 4025: while (t) ! 4026: { ! 4027: TYPE_OVERLOADS_ARROW (t) = 1; ! 4028: t = TYPE_NEXT_VARIANT (t); ! 4029: } ! 4030: } ! 4031: } ! 4032: | OPERATOR LEFT_RIGHT ! 4033: { $$ = ansi_opname[CALL_EXPR]; ! 4034: if (current_class_type) ! 4035: { ! 4036: tree t = current_class_type; ! 4037: while (t) ! 4038: { ! 4039: TYPE_OVERLOADS_CALL_EXPR (t) = 1; ! 4040: t = TYPE_NEXT_VARIANT (t); ! 4041: } ! 4042: } ! 4043: } ! 4044: | OPERATOR '[' ']' ! 4045: { $$ = ansi_opname[ARRAY_REF]; ! 4046: if (current_class_type) ! 4047: { ! 4048: tree t = current_class_type; ! 4049: while (t) ! 4050: { ! 4051: TYPE_OVERLOADS_ARRAY_REF (t) = 1; ! 4052: t = TYPE_NEXT_VARIANT (t); ! 4053: } ! 4054: } ! 4055: } ! 4056: | OPERATOR NEW ! 4057: { ! 4058: $$ = ansi_opname[NEW_EXPR]; ! 4059: if (current_class_type) ! 4060: { ! 4061: tree t = current_class_type; ! 4062: while (t) ! 4063: { ! 4064: TREE_GETS_NEW (t) = 1; ! 4065: t = TYPE_NEXT_VARIANT (t); ! 4066: } ! 4067: } ! 4068: } ! 4069: /* ! 4070: | OPERATOR NEW '[' ']' ! 4071: { ! 4072: $$ = ansi_opname[VEC_NEW_EXPR]; ! 4073: if (current_class_type) ! 4074: { ! 4075: tree t = current_class_type; ! 4076: while (t) ! 4077: { ! 4078: TREE_GETS_VEC_NEW (t) = 1; ! 4079: t = TYPE_NEXT_VARIANT (t); ! 4080: } ! 4081: } ! 4082: } ! 4083: */ ! 4084: | OPERATOR DELETE ! 4085: { ! 4086: $$ = ansi_opname[DELETE_EXPR]; ! 4087: if (current_class_type) ! 4088: { ! 4089: tree t = current_class_type; ! 4090: while (t) ! 4091: { ! 4092: TREE_GETS_DELETE (t) = 1; ! 4093: t = TYPE_NEXT_VARIANT (t); ! 4094: } ! 4095: } ! 4096: } ! 4097: /* ! 4098: | OPERATOR DELETE '[' ']' ! 4099: { ! 4100: $$ = ansi_opname[VEC_DELETE_EXPR]; ! 4101: if (current_class_type) ! 4102: { ! 4103: tree t = current_class_type; ! 4104: while (t) ! 4105: { ! 4106: TREE_GETS_VEC_DELETE (t) = 1; ! 4107: t = TYPE_NEXT_VARIANT (t); ! 4108: } ! 4109: } ! 4110: } ! 4111: */ ! 4112: ! 4113: /* These should do `groktypename' and set up TREE_HAS_X_CONVERSION ! 4114: here, rather than doing it in class.c . */ ! 4115: | OPERATOR typed_typespecs absdcl ! 4116: { $$ = build1 (TYPE_EXPR, $2, $3); } ! 4117: | OPERATOR error ! 4118: { $$ = ansi_opname[ERROR_MARK]; } ! 4119: ; ! 4120: ! 4121: ! 4122: /* ! 4123: * Objective-C productions. ! 4124: */ ! 4125: ! 4126: /* records the type and storage class specs to use for processing ! 4127: the declarators that follow */ ! 4128: ! 4129: %ifobjc ! 4130: .setspecs: /* empty */ ! 4131: { current_declspecs = $<ttype>0; ! 4132: $<itype>$ = suspend_momentary (); } ! 4133: ; ! 4134: ! 4135: objcdef: ! 4136: classdef ! 4137: | classdecl ! 4138: | protocoldecl ! 4139: | aliasdecl ! 4140: | protocoldef ! 4141: | methoddef ! 4142: | END ! 4143: { ! 4144: if (objc_implementation_context) ! 4145: { ! 4146: finish_class(objc_implementation_context); ! 4147: objc_ivar_chain = NULL_TREE; ! 4148: objc_implementation_context = NULL_TREE; ! 4149: } ! 4150: else ! 4151: warning("`@end' must appear in an implementation context"); ! 4152: } ! 4153: ; ! 4154: ! 4155: /* A nonempty list of identifiers. */ ! 4156: identifier_list: ! 4157: identifier ! 4158: { $$ = build_tree_list (NULL_TREE, $1); } ! 4159: | identifier_list ',' identifier ! 4160: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 4161: ; ! 4162: ! 4163: classdecl: ! 4164: CLASS identifier_list ';' ! 4165: { ! 4166: objc_declare_class ($2); ! 4167: } ! 4168: ! 4169: protocoldecl: ! 4170: PROTOCOL identifier_list ';' ! 4171: { ! 4172: objc_declare_protocols ($2); ! 4173: } ! 4174: ! 4175: aliasdecl: ! 4176: ALIAS identifier identifier ';' ! 4177: { ! 4178: objc_declare_alias ($2, $3); ! 4179: } ! 4180: ! 4181: /* This is necessary for living in this c++ parser */ ! 4182: identifier_colon: ! 4183: identifier ':' ! 4184: { $$ = $1 } ! 4185: | TYPENAME_COLON ! 4186: ; ! 4187: ! 4188: classdef: ! 4189: INTERFACE identifier protocolrefs '{' ! 4190: { ! 4191: objc_interface_context = objc_ivar_context ! 4192: = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3); ! 4193: objc_public_flag = 0; ! 4194: } ! 4195: ivar_decl_list '}' ! 4196: { ! 4197: continue_class (objc_interface_context); ! 4198: } ! 4199: methodprotolist ! 4200: END ! 4201: { ! 4202: finish_class (objc_interface_context); ! 4203: objc_interface_context = NULL_TREE; ! 4204: } ! 4205: ! 4206: | INTERFACE identifier protocolrefs ! 4207: { ! 4208: objc_interface_context ! 4209: = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3); ! 4210: continue_class (objc_interface_context); ! 4211: } ! 4212: methodprotolist ! 4213: END ! 4214: { ! 4215: finish_class(objc_interface_context); ! 4216: objc_interface_context = NULL_TREE; ! 4217: } ! 4218: ! 4219: | INTERFACE identifier_colon identifier protocolrefs '{' ! 4220: { ! 4221: objc_interface_context = objc_ivar_context ! 4222: = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4); ! 4223: objc_public_flag = 0; ! 4224: } ! 4225: ivar_decl_list '}' ! 4226: { ! 4227: continue_class (objc_interface_context); ! 4228: } ! 4229: methodprotolist ! 4230: END ! 4231: { ! 4232: finish_class(objc_interface_context); ! 4233: objc_interface_context = NULL_TREE; ! 4234: } ! 4235: ! 4236: | INTERFACE identifier_colon identifier protocolrefs ! 4237: { ! 4238: objc_interface_context ! 4239: = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4); ! 4240: continue_class (objc_interface_context); ! 4241: } ! 4242: methodprotolist ! 4243: END ! 4244: { ! 4245: finish_class (objc_interface_context); ! 4246: objc_interface_context = NULL_TREE; ! 4247: } ! 4248: ! 4249: | IMPLEMENTATION identifier '{' ! 4250: { ! 4251: objc_implementation_context = objc_ivar_context ! 4252: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE); ! 4253: objc_public_flag = 0; ! 4254: } ! 4255: ivar_decl_list '}' ! 4256: { ! 4257: objc_ivar_chain ! 4258: = continue_class (objc_implementation_context); ! 4259: } ! 4260: ! 4261: | IMPLEMENTATION identifier ! 4262: { ! 4263: objc_implementation_context ! 4264: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE); ! 4265: objc_ivar_chain ! 4266: = continue_class (objc_implementation_context); ! 4267: } ! 4268: ! 4269: | IMPLEMENTATION identifier_colon identifier '{' ! 4270: { ! 4271: objc_implementation_context = objc_ivar_context ! 4272: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE); ! 4273: objc_public_flag = 0; ! 4274: } ! 4275: ivar_decl_list '}' ! 4276: { ! 4277: objc_ivar_chain ! 4278: = continue_class (objc_implementation_context); ! 4279: } ! 4280: ! 4281: | IMPLEMENTATION identifier_colon identifier ! 4282: { ! 4283: objc_implementation_context ! 4284: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE); ! 4285: objc_ivar_chain ! 4286: = continue_class (objc_implementation_context); ! 4287: } ! 4288: ! 4289: | INTERFACE identifier '(' identifier ')' protocolrefs ! 4290: { ! 4291: objc_interface_context ! 4292: = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6); ! 4293: continue_class (objc_interface_context); ! 4294: } ! 4295: methodprotolist ! 4296: END ! 4297: { ! 4298: finish_class (objc_interface_context); ! 4299: objc_interface_context = NULL_TREE; ! 4300: } ! 4301: ! 4302: | IMPLEMENTATION identifier '(' identifier ')' ! 4303: { ! 4304: objc_implementation_context ! 4305: = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); ! 4306: objc_ivar_chain ! 4307: = continue_class (objc_implementation_context); ! 4308: } ! 4309: ; ! 4310: ! 4311: protocoldef: ! 4312: PROTOCOL identifier protocolrefs ! 4313: { ! 4314: objc_interface_context = ! 4315: start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3); ! 4316: } ! 4317: methodprotolist ! 4318: END ! 4319: { ! 4320: finish_protocol(objc_interface_context); ! 4321: objc_interface_context = NULL_TREE; ! 4322: } ! 4323: ; ! 4324: ! 4325: ivar_decl_list: ! 4326: ivar_decl_list visibility_spec ivar_decls ! 4327: | ivar_decls ! 4328: ; ! 4329: ! 4330: visibility_spec: ! 4331: PUBLIC { objc_public_flag = 1; } ! 4332: | PRIVATE { objc_public_flag = 2; } ! 4333: | PROTECTED { objc_public_flag = 0; } ! 4334: ; ! 4335: ! 4336: ivar_decls: ! 4337: /* empty */ ! 4338: { ! 4339: $$ = NULL_TREE; ! 4340: } ! 4341: | ivar_decls ivar_decl ';' ! 4342: | ivar_decls ';' ! 4343: { ! 4344: if (pedantic) ! 4345: warning ("extra semicolon in struct or union specified"); ! 4346: } ! 4347: ; ! 4348: ! 4349: ivar_decl: ! 4350: typed_typespecs .setspecs ivars ! 4351: { ! 4352: $$ = $3; ! 4353: resume_momentary ($<itype>2); ! 4354: } ! 4355: | nonempty_type_quals .setspecs ivars ! 4356: { ! 4357: $$ = $3; ! 4358: resume_momentary ($<itype>2); ! 4359: } ! 4360: | error ! 4361: { $$ = NULL_TREE; } ! 4362: ; ! 4363: ! 4364: ivars: ! 4365: /* empty */ ! 4366: { $$ = NULL_TREE; } ! 4367: | ivar_declarator ! 4368: | ivars ',' ivar_declarator ! 4369: ; ! 4370: ! 4371: ivar_declarator: ! 4372: declarator ! 4373: { ! 4374: $$ = add_instance_variable(objc_ivar_context, objc_public_flag, ! 4375: $1, current_declspecs, NULL_TREE); ! 4376: } ! 4377: | declarator ':' expr_no_commas ! 4378: { ! 4379: $$ = add_instance_variable(objc_ivar_context, objc_public_flag, ! 4380: $1, current_declspecs, $3); ! 4381: } ! 4382: | ':' expr_no_commas ! 4383: { ! 4384: $$ = add_instance_variable(objc_ivar_context, objc_public_flag, ! 4385: NULL_TREE, current_declspecs, $2); ! 4386: } ! 4387: ; ! 4388: ! 4389: methoddef: ! 4390: '+' ! 4391: { ! 4392: if (objc_implementation_context) ! 4393: objc_inherit_code = CLASS_METHOD_DECL; ! 4394: else ! 4395: fatal("Illegal method definition - must be in a class context."); ! 4396: } ! 4397: methoddecl ! 4398: { ! 4399: add_class_method(objc_implementation_context,$3); ! 4400: start_method_def ($3); ! 4401: objc_method_context = $3; ! 4402: } ! 4403: optarglist ! 4404: { ! 4405: continue_method_def(); ! 4406: } ! 4407: compstmt_or_error ! 4408: { ! 4409: finish_method_def (); ! 4410: objc_method_context = NULL_TREE; ! 4411: } ! 4412: ! 4413: | '-' ! 4414: { ! 4415: if (objc_implementation_context) ! 4416: objc_inherit_code = INSTANCE_METHOD_DECL; ! 4417: else ! 4418: fatal("Illegal method definition - must be in a class context."); ! 4419: } ! 4420: methoddecl ! 4421: { ! 4422: add_instance_method(objc_implementation_context,$3); ! 4423: start_method_def ($3); ! 4424: objc_method_context = $3; ! 4425: } ! 4426: optarglist ! 4427: { ! 4428: continue_method_def(); ! 4429: } ! 4430: compstmt_or_error ! 4431: { ! 4432: finish_method_def (); ! 4433: objc_method_context = NULL_TREE; ! 4434: } ! 4435: ; ! 4436: ! 4437: /* the reason for the strange actions in this rule ! 4438: is so that notype_initdecls when reached via datadef ! 4439: can find a valid list of type and sc specs in $0. */ ! 4440: ! 4441: methodprotolist: ! 4442: /* empty */ ! 4443: | {$<ttype>$ = NULL_TREE; } methodprotolist2 ! 4444: ; ! 4445: ! 4446: methodprotolist2: /* eliminates a shift/reduce conflict */ ! 4447: methodproto ! 4448: | datadef ! 4449: | methodprotolist2 methodproto ! 4450: | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef ! 4451: ; ! 4452: ! 4453: semi_or_error: ! 4454: ';' ! 4455: | error ! 4456: ; ! 4457: ! 4458: methodproto: ! 4459: '+' ! 4460: { ! 4461: objc_inherit_code = CLASS_METHOD_DECL; ! 4462: } ! 4463: methoddecl ! 4464: { ! 4465: add_class_method(objc_interface_context,$3); ! 4466: } ! 4467: semi_or_error ! 4468: ! 4469: | '-' ! 4470: { ! 4471: objc_inherit_code = INSTANCE_METHOD_DECL; ! 4472: } ! 4473: methoddecl ! 4474: { ! 4475: add_instance_method(objc_interface_context,$3); ! 4476: } ! 4477: semi_or_error ! 4478: ; ! 4479: ! 4480: methodtype: ! 4481: '(' ! 4482: { ! 4483: remember_protocol_qualifiers(); ! 4484: } ! 4485: typename ! 4486: { ! 4487: forget_protocol_qualifiers(); ! 4488: } ! 4489: ')' ! 4490: { $$ = $3; } ! 4491: ; ! 4492: ! 4493: methoddecl: ! 4494: methodtype unaryselector ! 4495: { ! 4496: $$ = build_method_decl (objc_inherit_code, $1, $2, NULL_TREE); ! 4497: } ! 4498: ! 4499: | unaryselector ! 4500: { ! 4501: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE); ! 4502: } ! 4503: ! 4504: | methodtype keywordselector optparmlist ! 4505: { ! 4506: $$ = build_method_decl (objc_inherit_code, $1, $2, $3); ! 4507: } ! 4508: ! 4509: | keywordselector optparmlist ! 4510: { ! 4511: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2); ! 4512: } ! 4513: ; ! 4514: ! 4515: ! 4516: /* "optarglist" assumes that start_method_def() has already been called... ! 4517: if it is not, the "xdecls" will not be placed in the proper scope */ ! 4518: ! 4519: optarglist: ! 4520: /* empty */ ! 4521: | ';' myxdecls ! 4522: ; ! 4523: ! 4524: /* to get around the following situation: "int foo(int a) int b; {}" that ! 4525: is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */ ! 4526: ! 4527: myxdecls: ! 4528: /* empty */ ! 4529: | mydecls ! 4530: ; ! 4531: ! 4532: mydecls: ! 4533: mydecl ! 4534: | errstmt ! 4535: | mydecls mydecl ! 4536: | mydecl errstmt ! 4537: ; ! 4538: ! 4539: mydecl: ! 4540: typed_declspecs .setspecs myparms ';' ! 4541: { resume_momentary ($<itype>2); } ! 4542: | typed_declspecs ';' ! 4543: { shadow_tag ($1); } ! 4544: | declmods ';' ! 4545: { warning ("empty declaration"); } ! 4546: ; ! 4547: ! 4548: /* this must be converted to live in the g++ world...snaroff */ ! 4549: ! 4550: myparms: ! 4551: myparm ! 4552: { objcplus_push_parm_decl ($1); } ! 4553: | myparms ',' myparm ! 4554: { objcplus_push_parm_decl ($3); } ! 4555: ; ! 4556: ! 4557: /* A single parameter declaration or parameter type name, ! 4558: as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */ ! 4559: ! 4560: myparm: ! 4561: dont_see_typename notype_declarator ! 4562: { $$ = build_tree_list (current_declspecs, $2) ; } ! 4563: | notype_declarator ! 4564: { $$ = build_tree_list (current_declspecs, $1) ; } ! 4565: | absdcl ! 4566: { $$ = build_tree_list (current_declspecs, $1) ; } ! 4567: ; ! 4568: ! 4569: optparmlist: ! 4570: /* empty */ ! 4571: { ! 4572: $$ = NULL_TREE; ! 4573: } ! 4574: | ',' ELLIPSIS ! 4575: { ! 4576: /* oh what a kludge! */ ! 4577: $$ = (tree)1; ! 4578: } ! 4579: | ',' ! 4580: { ! 4581: pushlevel (0); ! 4582: } ! 4583: parmlist ! 4584: { ! 4585: /* returns a tree list node generated by `get_parm_info()' */ ! 4586: $$ = $3; ! 4587: poplevel(0,0,0); ! 4588: } ! 4589: ; ! 4590: ! 4591: unaryselector: ! 4592: selector ! 4593: ; ! 4594: ! 4595: keywordselector: ! 4596: keyworddecl ! 4597: | keywordselector keyworddecl ! 4598: { ! 4599: $$ = chainon($1, $2); ! 4600: } ! 4601: ; ! 4602: ! 4603: selector: ! 4604: IDENTIFIER ! 4605: | TYPENAME ! 4606: | OBJECTNAME ! 4607: | reservedword ! 4608: ; ! 4609: ! 4610: reservedword: ! 4611: ENUM { $$ = get_identifier("enum"); } ! 4612: | AGGR ! 4613: { ! 4614: if (yylval.ttype == class_type_node) ! 4615: $$ = get_identifier("class"); ! 4616: else if (yylval.ttype == record_type_node) ! 4617: $$ = get_identifier("struct"); ! 4618: else if (yylval.ttype == union_type_node) ! 4619: $$ = get_identifier("union"); ! 4620: else if (yylval.ttype == enum_type_node) ! 4621: $$ = get_identifier("enum"); ! 4622: else ! 4623: abort (); ! 4624: } ! 4625: | IF { $$ = get_identifier("if"); } ! 4626: | ELSE { $$ = get_identifier("else"); } ! 4627: | WHILE { $$ = get_identifier("while"); } ! 4628: | DO { $$ = get_identifier("do"); } ! 4629: | FOR { $$ = get_identifier("for"); } ! 4630: | SWITCH { $$ = get_identifier("switch"); } ! 4631: | CASE { $$ = get_identifier("case"); } ! 4632: | DEFAULT { $$ = get_identifier("default"); } ! 4633: | BREAK { $$ = get_identifier("break"); } ! 4634: | CONTINUE { $$ = get_identifier("continue"); } ! 4635: | RETURN { $$ = get_identifier("return"); } ! 4636: | GOTO { $$ = get_identifier("goto"); } ! 4637: | ASM_KEYWORD { $$ = get_identifier("asm"); } ! 4638: | SIZEOF { $$ = get_identifier("sizeof"); } ! 4639: | TYPEOF { $$ = get_identifier("typeof"); } ! 4640: | ALIGNOF { $$ = get_identifier("alignof"); } ! 4641: | NEW { $$ = get_identifier("new"); } ! 4642: | DELETE { $$ = get_identifier("delete"); } ! 4643: | OPERATOR { $$ = get_identifier("operator"); } ! 4644: | VISSPEC { ! 4645: if ($1 == visibility_private) ! 4646: $$ = get_identifier ("private"); ! 4647: else if ($1 == visibility_public) ! 4648: $$ = get_identifier ("public"); ! 4649: else if ($1 == visibility_protected) ! 4650: $$ = get_identifier ("protected"); ! 4651: else ! 4652: abort (); ! 4653: } ! 4654: | SCSPEC { $$ = yylval.ttype; } ! 4655: | TYPESPEC { $$ = yylval.ttype; } ! 4656: | OVERLOAD { $$ = get_identifier("overload"); } ! 4657: ; ! 4658: ! 4659: keyworddecl: ! 4660: selector ':' methodtype identifier ! 4661: { ! 4662: $$ = build_keyword_decl($1, $3, $4); ! 4663: } ! 4664: ! 4665: | selector ':' identifier ! 4666: { ! 4667: $$ = build_keyword_decl($1, NULL_TREE, $3); ! 4668: } ! 4669: ! 4670: | ':' methodtype identifier ! 4671: { ! 4672: $$ = build_keyword_decl(NULL_TREE, $2, $3); ! 4673: } ! 4674: ! 4675: | ':' identifier ! 4676: { ! 4677: $$ = build_keyword_decl(NULL_TREE, NULL_TREE, $2); ! 4678: } ! 4679: ; ! 4680: ! 4681: messageargs: ! 4682: selector ! 4683: | keywordarglist ! 4684: ; ! 4685: ! 4686: keywordarglist: ! 4687: keywordarg ! 4688: | keywordarglist keywordarg ! 4689: { ! 4690: $$ = chainon($1, $2); ! 4691: } ! 4692: ; ! 4693: ! 4694: ! 4695: keywordexpr: ! 4696: nonnull_exprlist ! 4697: { ! 4698: if (TREE_CHAIN($1) == NULL_TREE) ! 4699: /* just return the expr., remove a level of indirection */ ! 4700: $$ = TREE_VALUE($1); ! 4701: else ! 4702: /* we have a comma expr., we will collapse later */ ! 4703: $$ = $1; ! 4704: } ! 4705: ; ! 4706: ! 4707: keywordarg: ! 4708: selector ':' keywordexpr ! 4709: { ! 4710: $$ = build_tree_list($1, $3); ! 4711: } ! 4712: | ':' keywordexpr ! 4713: { ! 4714: $$ = build_tree_list(NULL_TREE,$2); ! 4715: } ! 4716: ; ! 4717: ! 4718: receiver: ! 4719: nonnull_exprlist ! 4720: { ! 4721: $$ = build_x_compound_expr ($1); ! 4722: } ! 4723: | CLASSNAME ! 4724: { ! 4725: $$ = get_class_reference($1); ! 4726: } ! 4727: ; ! 4728: ! 4729: objc_openbracket.expr: ! 4730: '[' ! 4731: { objc_receiver_context = 1; objc_msg_context += 1; } ! 4732: receiver ! 4733: { objc_receiver_context = 0; $$ = $3; } ! 4734: ; ! 4735: ! 4736: objc_closebracket: ! 4737: ']' ! 4738: { objc_msg_context -= 1; } ! 4739: ; ! 4740: ! 4741: objcmessageexpr: ! 4742: objc_openbracket.expr ! 4743: messageargs ! 4744: objc_closebracket ! 4745: { ! 4746: $$ = build_tree_list($1,$2); ! 4747: TREE_TYPE ($$) = NULL_TREE; ! 4748: } ! 4749: /* ! 4750: | CLASSNAME SCOPE '[' ! 4751: { objc_receiver_context = 1; } ! 4752: receiver ! 4753: { objc_receiver_context = 0; } ! 4754: messageargs ']' ! 4755: { ! 4756: $$ = build_tree_list($5,$7); ! 4757: TREE_TYPE ($$) = get_class_reference ($1); ! 4758: } ! 4759: */ ! 4760: ; ! 4761: ! 4762: selectorarg: ! 4763: selector ! 4764: | keywordnamelist ! 4765: ; ! 4766: ! 4767: keywordnamelist: ! 4768: keywordname ! 4769: | keywordnamelist keywordname ! 4770: { ! 4771: $$ = chainon ($1, $2); ! 4772: } ! 4773: ; ! 4774: ! 4775: keywordname: ! 4776: selector ':' ! 4777: { ! 4778: $$ = build_tree_list ($1, NULL_TREE); ! 4779: } ! 4780: | ':' ! 4781: { ! 4782: $$ = build_tree_list (NULL_TREE,NULL_TREE); ! 4783: } ! 4784: | SCOPE ! 4785: { ! 4786: $$ = chainon (build_tree_list (NULL_TREE,NULL_TREE), ! 4787: build_tree_list (NULL_TREE,NULL_TREE)); ! 4788: } ! 4789: ; ! 4790: ! 4791: objcselectorexpr: ! 4792: SELECTOR '(' selectorarg ')' ! 4793: { ! 4794: $$ = $3; ! 4795: } ! 4796: ; ! 4797: ! 4798: objcprotocolexpr: ! 4799: PROTOCOL '(' identifier ')' ! 4800: { ! 4801: $$ = $3; ! 4802: } ! 4803: ; ! 4804: ! 4805: /* extension to support C-structures in the archiver */ ! 4806: ! 4807: objcencodeexpr: ! 4808: ENCODE '(' typename ')' ! 4809: { ! 4810: $$ = groktypename($3); ! 4811: } ! 4812: ; ! 4813: %endifobjc ! 4814: %% ! 4815: ! 4816: ! 4817:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.