|
|
1.1 ! root 1: /* YACC parser for C++ syntax. ! 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: ! 22: /* This grammar is based on the GNU CC grammar. */ ! 23: ! 24: /* Note: Bison automatically applies a default action of "$$ = $1" for ! 25: all derivations; this is applied before the explicit action, if one ! 26: is given. Keep this in mind when reading the actions. */ ! 27: ! 28: /* Also note: this version contains experimental exception ! 29: handling features. They could break, change, disappear, ! 30: or otherwise exhibit volatile behavior. Don't depend on ! 31: me (Michael Tiemann) to protect you from any negative impact ! 32: this may have on your professional, personal, or spiritual life. ! 33: ! 34: NEWS FLASH: This version now supports the exception handling ! 35: syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given. ! 36: THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the ! 37: 'catch' much match EXACTLY (no inheritance support or coercions). ! 38: Also, throw-specifications of functions don't work. ! 39: Destructors aren't called correctly. Etc, etc. --Per Bothner. ! 40: */ ! 41: ! 42: %{ ! 43: /* Cause the `yydebug' variable to be defined. */ ! 44: #define YYDEBUG 1 ! 45: ! 46: #include "config.h" ! 47: ! 48: #include <stdio.h> ! 49: #include <errno.h> ! 50: ! 51: #include "tree.h" ! 52: #include "input.h" ! 53: #include "flags.h" ! 54: #include "lex.h" ! 55: #include "cp-tree.h" ! 56: ! 57: /* Since parsers are distinct for each language, put the language string ! 58: definition here. (fnf) */ ! 59: char *language_string = "GNU C++"; ! 60: ! 61: extern tree void_list_node; ! 62: extern struct obstack permanent_obstack; ! 63: ! 64: #ifndef errno ! 65: extern int errno; ! 66: #endif ! 67: ! 68: extern int end_of_file; ! 69: extern int current_class_depth; ! 70: ! 71: void yyerror (); ! 72: ! 73: /* Like YYERROR but do call yyerror. */ ! 74: #define YYERROR1 { yyerror ("syntax error"); YYERROR; } ! 75: ! 76: #define OP0(NODE) (TREE_OPERAND (NODE, 0)) ! 77: #define OP1(NODE) (TREE_OPERAND (NODE, 1)) ! 78: ! 79: /* Contains the statement keyword (if/while/do) to include in an ! 80: error message if the user supplies an empty conditional expression. */ ! 81: static char *cond_stmt_keyword; ! 82: ! 83: /* Nonzero if we have an `extern "C"' acting as an extern specifier. */ ! 84: int have_extern_spec; ! 85: int used_extern_spec; ! 86: ! 87: void yyhook (); ! 88: ! 89: /* Cons up an empty parameter list. */ ! 90: #ifdef __GNUC__ ! 91: __inline ! 92: #endif ! 93: static tree ! 94: empty_parms () ! 95: { ! 96: tree parms; ! 97: ! 98: if (strict_prototype) ! 99: parms = void_list_node; ! 100: else ! 101: parms = NULL_TREE; ! 102: return parms; ! 103: } ! 104: %} ! 105: ! 106: %start program ! 107: ! 108: %union {long itype; tree ttype; char *strtype; enum tree_code code; } ! 109: ! 110: /* All identifiers that are not reserved words ! 111: and are not declared typedefs in the current block */ ! 112: %token IDENTIFIER ! 113: ! 114: /* All identifiers that are declared typedefs in the current block. ! 115: In some contexts, they are treated just like IDENTIFIER, ! 116: but they can also serve as typespecs in declarations. */ ! 117: %token TYPENAME ! 118: ! 119: /* Reserved words that specify storage class. ! 120: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 121: %token SCSPEC ! 122: ! 123: /* Reserved words that specify type. ! 124: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 125: %token TYPESPEC ! 126: ! 127: /* Reserved words that qualify type: "const" or "volatile". ! 128: yylval contains an IDENTIFIER_NODE which indicates which one. */ ! 129: %token TYPE_QUAL ! 130: ! 131: /* Character or numeric constants. ! 132: yylval is the node for the constant. */ ! 133: %token CONSTANT ! 134: ! 135: /* String constants in raw form. ! 136: yylval is a STRING_CST node. */ ! 137: %token STRING ! 138: ! 139: /* "...", used for functions with variable arglists. */ ! 140: %token ELLIPSIS ! 141: ! 142: /* the reserved words */ ! 143: /* SCO include files test "ASM", so use something else. */ ! 144: %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT ! 145: %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF ! 146: %token HEADOF CLASSOF SIGOF ! 147: %token ATTRIBUTE EXTENSION LABEL ! 148: ! 149: /* the reserved words... C++ extensions */ ! 150: %token <ttype> AGGR ! 151: %token <itype> VISSPEC ! 152: %token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE ! 153: %token LEFT_RIGHT TEMPLATE ! 154: %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST ! 155: %token <itype> SCOPE ! 156: ! 157: /* Define the operator tokens and their precedences. ! 158: The value is an integer because, if used, it is the tree code ! 159: to use in the expression made from the operator. */ ! 160: ! 161: %left EMPTY /* used to resolve s/r with epsilon */ ! 162: ! 163: %left error ! 164: ! 165: /* Add precedence rules to solve dangling else s/r conflict */ ! 166: %nonassoc IF ! 167: %nonassoc ELSE ! 168: ! 169: %left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR ! 170: ! 171: %left '{' ',' ';' ! 172: ! 173: %right <code> ASSIGN '=' ! 174: %right <code> '?' ':' ! 175: %left <code> OROR ! 176: %left <code> ANDAND ! 177: %left <code> '|' ! 178: %left <code> '^' ! 179: %left <code> '&' ! 180: %left <code> MIN_MAX ! 181: %left <code> EQCOMPARE ! 182: %left <code> ARITHCOMPARE '<' '>' ! 183: %left <code> LSHIFT RSHIFT ! 184: %left <code> '+' '-' ! 185: %left <code> '*' '/' '%' ! 186: %left <code> POINTSAT_STAR DOT_STAR ! 187: %right <code> UNARY PLUSPLUS MINUSMINUS '~' ! 188: %left HYPERUNARY ! 189: %left <ttype> PAREN_STAR_PAREN LEFT_RIGHT ! 190: %left <code> POINTSAT '.' '(' '[' ! 191: ! 192: %right SCOPE /* C++ extension */ ! 193: %nonassoc NEW DELETE TRY CATCH THROW ! 194: ! 195: %type <code> unop ! 196: ! 197: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist ! 198: %type <ttype> paren_expr_or_null nontrivial_exprlist ! 199: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING ! 200: %type <ttype> typed_declspecs reserved_declspecs boolean.literal ! 201: %type <ttype> typed_typespecs reserved_typespecquals ! 202: %type <ttype> declmods typespec typespecqual_reserved ! 203: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual ! 204: %type <itype> initdecls notype_initdecls initdcl /* C++ modification */ ! 205: %type <ttype> init initlist maybeasm ! 206: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers ! 207: %type <ttype> maybe_attribute attributes attribute attribute_list attrib ! 208: %type <ttype> any_word ! 209: ! 210: %type <ttype> compstmt implicitly_scoped_stmt ! 211: ! 212: %type <ttype> declarator notype_declarator after_type_declarator ! 213: %type <ttype> direct_notype_declarator direct_after_type_declarator ! 214: ! 215: %type <ttype> structsp opt.component_decl_list component_decl_list ! 216: %type <ttype> component_decl components component_declarator ! 217: %type <ttype> notype_components notype_component_declarator ! 218: %type <ttype> after_type_component_declarator after_type_component_declarator0 ! 219: %type <ttype> notype_component_declarator0 component_decl_1 ! 220: %type <ttype> enumlist enumerator ! 221: %type <ttype> type_id absdcl type_quals ! 222: %type <ttype> direct_abstract_declarator conversion_declarator ! 223: %type <ttype> new_type_id new_declarator direct_new_declarator ! 224: %type <ttype> xexpr parmlist parms parm bad_parm full_parm ! 225: %type <ttype> identifiers_or_typenames ! 226: %type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr ! 227: %type <ttype> expr_or_declarator complex_notype_declarator ! 228: %type <ttype> notype_unqualified_id unqualified_id qualified_id ! 229: %type <ttype> overqualified_id notype_qualified_id ! 230: %type <ttype> complex_direct_notype_declarator functional_cast ! 231: %type <ttype> named_parm complex_parmlist typed_declspecs1 parms_comma ! 232: ! 233: /* C++ extensions */ ! 234: %token <ttype> TYPENAME_ELLIPSIS PTYPENAME ! 235: %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL ! 236: %token <ttype> PRE_PARSED_CLASS_DECL ! 237: %type <ttype> fn.def1 /* Not really! */ ! 238: %type <ttype> fn.def2 return_id ! 239: %type <ttype> named_class_head named_class_head_sans_basetype ! 240: %type <ttype> unnamed_class_head ! 241: %type <ttype> class_head base_class_list ! 242: %type <itype> base_class_access_list ! 243: %type <ttype> base_class maybe_base_class_list base_class.1 ! 244: %type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers ! 245: %type <ttype> component_declarator0 ! 246: %type <ttype> forhead.1 operator_name ! 247: %type <ttype> object aggr ! 248: %type <itype> new delete ! 249: /* %type <ttype> primary_no_id */ ! 250: %type <ttype> nonmomentary_expr ! 251: %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list ! 252: %type <ttype> template_header template_parm_list template_parm ! 253: %type <ttype> template_type_parm ! 254: %type <ttype> template_type template_arg_list template_arg ! 255: %type <ttype> template_instantiation template_type_name tmpl.2 ! 256: %type <ttype> template_instantiate_once template_instantiate_some ! 257: %type <itype> fn_tmpl_end ! 258: /* %type <itype> try_for_typename */ ! 259: %type <ttype> condition xcond paren_cond_or_null ! 260: %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem ! 261: %type <ttype> qualified_type_name complete_type_name notype_identifier ! 262: %type <ttype> complex_type_name nested_name_specifier_1 ! 263: %type <itype> nomods_initdecls nomods_initdcl0 ! 264: %type <ttype> new_initializer new_placement specialization type_specifier_seq ! 265: ! 266: /* in order to recognize aggr tags as defining and thus shadowing. */ ! 267: %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN ! 268: %type <ttype> named_class_head_sans_basetype_defn ! 269: %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN ! 270: ! 271: %type <strtype> .pushlevel ! 272: ! 273: /* spew.c depends on this being the last token. Define ! 274: any new tokens before this one! */ ! 275: %token END_OF_SAVED_INPUT ! 276: ! 277: %{ ! 278: /* List of types and structure classes of the current declaration. */ ! 279: static tree current_declspecs; ! 280: ! 281: /* When defining an aggregate, this is the most recent one being defined. */ ! 282: static tree current_aggr; ! 283: ! 284: /* Tell yyparse how to print a token's value, if yydebug is set. */ ! 285: ! 286: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) ! 287: extern void yyprint (); ! 288: extern tree combine_strings PROTO((tree)); ! 289: %} ! 290: ! 291: %% ! 292: program: /* empty */ ! 293: | extdefs ! 294: { ! 295: /* In case there were missing closebraces, ! 296: get us back to the global binding level. */ ! 297: while (! global_bindings_p ()) ! 298: poplevel (0, 0, 0); ! 299: finish_file (); ! 300: } ! 301: ; ! 302: ! 303: /* the reason for the strange actions in this rule ! 304: is so that notype_initdecls when reached via datadef ! 305: can find a valid list of type and sc specs in $0. */ ! 306: ! 307: extdefs: ! 308: { $<ttype>$ = NULL_TREE; } lang_extdef ! 309: { $<ttype>$ = NULL_TREE; } ! 310: | extdefs lang_extdef ! 311: { $<ttype>$ = NULL_TREE; } ! 312: ; ! 313: ! 314: .hush_warning: ! 315: { have_extern_spec = 1; ! 316: used_extern_spec = 0; ! 317: $<ttype>$ = NULL_TREE; } ! 318: ; ! 319: .warning_ok: ! 320: { have_extern_spec = 0; } ! 321: ; ! 322: ! 323: asm_keyword: ! 324: ASM_KEYWORD ! 325: | GCC_ASM_KEYWORD ! 326: ; ! 327: ! 328: lang_extdef: ! 329: { if (pending_lang_change) do_pending_lang_change(); } ! 330: extdef ! 331: { if (! global_bindings_p () && ! pseudo_global_level_p()) ! 332: pop_everything (); } ! 333: ; ! 334: ! 335: extdef: ! 336: fndef ! 337: { if (pending_inlines) do_pending_inlines (); } ! 338: | datadef ! 339: { if (pending_inlines) do_pending_inlines (); } ! 340: | template_def ! 341: { if (pending_inlines) do_pending_inlines (); } ! 342: | overloaddef ! 343: | asm_keyword '(' string ')' ';' ! 344: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); ! 345: assemble_asm ($3); } ! 346: | extern_lang_string '{' extdefs '}' ! 347: { pop_lang_context (); } ! 348: | extern_lang_string '{' '}' ! 349: { pop_lang_context (); } ! 350: | extern_lang_string .hush_warning fndef .warning_ok ! 351: { if (pending_inlines) do_pending_inlines (); ! 352: pop_lang_context (); } ! 353: | extern_lang_string .hush_warning datadef .warning_ok ! 354: { if (pending_inlines) do_pending_inlines (); ! 355: pop_lang_context (); } ! 356: ; ! 357: ! 358: extern_lang_string: ! 359: EXTERN_LANG_STRING ! 360: { push_lang_context ($1); } ! 361: ; ! 362: ! 363: template_header: ! 364: TEMPLATE '<' ! 365: { begin_template_parm_list (); } ! 366: template_parm_list '>' ! 367: { $$ = end_template_parm_list ($4); } ! 368: ; ! 369: ! 370: template_parm_list: ! 371: template_parm ! 372: { $$ = process_template_parm (NULL_TREE, $1); } ! 373: | template_parm_list ',' template_parm ! 374: { $$ = process_template_parm ($1, $3); } ! 375: ; ! 376: ! 377: template_type_parm: ! 378: aggr ! 379: { ! 380: $$ = build_tree_list ($1, NULL_TREE); ! 381: ttpa: ! 382: if (TREE_PURPOSE ($$) == signature_type_node) ! 383: sorry ("signature as template type parameter"); ! 384: else if (TREE_PURPOSE ($$) != class_type_node) ! 385: pedwarn ("template type parameters must use the keyword `class'"); ! 386: } ! 387: | aggr identifier ! 388: { $$ = build_tree_list ($1, $2); goto ttpa; } ! 389: ; ! 390: ! 391: template_parm: ! 392: /* The following rules introduce a new reduce/reduce ! 393: conflict on the ',' and '>' input tokens: they are valid ! 394: prefixes for a `structsp', which means they could match a ! 395: nameless parameter. See 14.6, paragraph 3. ! 396: By putting them before the `parm' rule, we get ! 397: their match before considering them nameless parameter ! 398: declarations. */ ! 399: template_type_parm ! 400: { $$ = build_tree_list (NULL_TREE, $$); } ! 401: | template_type_parm '=' typespec ! 402: { $$ = build_tree_list ($3, $$); } ! 403: | full_parm ! 404: ; ! 405: ! 406: overloaddef: ! 407: OVERLOAD ov_identifiers ';' ! 408: { warning ("use of `overload' is an anachronism"); } ! 409: ; ! 410: ! 411: ov_identifiers: IDENTIFIER ! 412: { declare_overloaded ($1); } ! 413: | ov_identifiers ',' IDENTIFIER ! 414: { declare_overloaded ($3); } ! 415: ; ! 416: ! 417: template_def: ! 418: /* Class template declarations go here; they aren't normal class ! 419: declarations, because we can't process the bodies yet. */ ! 420: template_header named_class_head_sans_basetype '{' ! 421: { yychar = '{'; goto template1; } ! 422: ';' ! 423: | template_header named_class_head_sans_basetype_defn '{' ! 424: { yychar = '{'; goto template1; } ! 425: ';' ! 426: | template_header named_class_head_sans_basetype ':' ! 427: { yychar = ':'; goto template1; } ! 428: ';' ! 429: | template_header named_class_head_sans_basetype_defn ':' ! 430: { ! 431: yychar = ':'; ! 432: template1: ! 433: if (current_aggr == exception_type_node) ! 434: error ("template type must define an aggregate or union"); ! 435: else if (current_aggr == signature_type_node) ! 436: sorry ("template type defining a signature"); ! 437: /* Maybe pedantic warning for union? ! 438: How about an enum? :-) */ ! 439: end_template_decl ($1, $2, current_aggr, 1); ! 440: reinit_parse_for_template (yychar, $1, $2); ! 441: yychar = YYEMPTY; ! 442: } ! 443: ';' ! 444: | template_header named_class_head_sans_basetype ';' ! 445: { ! 446: end_template_decl ($1, $2, current_aggr, 0); ! 447: /* declare $2 as template name with $1 parm list */ ! 448: } ! 449: | template_header named_class_head_sans_basetype_defn ';' ! 450: { ! 451: end_template_decl ($1, $2, current_aggr, 0); ! 452: /* declare $2 as template name with $1 parm list */ ! 453: } ! 454: | template_header /* notype_initdcl0 ';' */ ! 455: notype_declarator maybe_raises maybeasm maybe_attribute ! 456: fn_tmpl_end ! 457: { ! 458: tree d; ! 459: int momentary; ! 460: int def = ($6 != ';'); ! 461: momentary = suspend_momentary (); ! 462: d = start_decl ($<ttype>2, /*current_declspecs*/NULL_TREE, 0, ! 463: $3); ! 464: cplus_decl_attributes (d, $5); ! 465: finish_decl (d, NULL_TREE, $4, 0); ! 466: end_template_decl ($1, d, 0, def); ! 467: if (def) ! 468: reinit_parse_for_template ((int) $6, $1, d); ! 469: resume_momentary (momentary); ! 470: } ! 471: | template_header typed_declspecs /*initdcl0*/ ! 472: declarator maybe_raises maybeasm maybe_attribute ! 473: fn_tmpl_end ! 474: { ! 475: tree d; ! 476: int momentary; ! 477: int def = ($7 != ';'); ! 478: ! 479: current_declspecs = $2; ! 480: momentary = suspend_momentary (); ! 481: d = start_decl ($<ttype>3, current_declspecs, ! 482: 0, $<ttype>4); ! 483: cplus_decl_attributes (d, $6); ! 484: finish_decl (d, NULL_TREE, $5, 0); ! 485: end_template_decl ($1, d, 0, def); ! 486: if (def) ! 487: { ! 488: reinit_parse_for_template ((int) $7, $1, d); ! 489: yychar = YYEMPTY; ! 490: } ! 491: note_list_got_semicolon ($<ttype>2); ! 492: resume_momentary (momentary); ! 493: } ! 494: | template_header declmods notype_declarator fn_tmpl_end ! 495: { ! 496: int def = ($4 != ';'); ! 497: tree d = start_decl ($<ttype>3, $<ttype>2, 0, NULL_TREE); ! 498: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 499: end_template_decl ($1, d, 0, def); ! 500: if (def) ! 501: reinit_parse_for_template ((int) $4, $1, d); ! 502: } ! 503: /* Try to recover from syntax errors in templates. */ ! 504: | template_header error '}' { end_template_decl ($1, 0, 0, 0); } ! 505: | template_header error ';' { end_template_decl ($1, 0, 0, 0); } ! 506: ; ! 507: ! 508: fn_tmpl_end: '{' { $$ = '{'; } ! 509: | ':' { $$ = ':'; } ! 510: | ';' { $$ = ';'; } ! 511: | '=' { $$ = '='; } ! 512: | RETURN { $$ = RETURN; } ! 513: ; ! 514: ! 515: datadef: ! 516: nomods_initdecls ';' ! 517: {} ! 518: | declmods notype_initdecls ';' ! 519: {} ! 520: /* Normal case to make fast: "const i;". */ ! 521: | declmods notype_declarator ';' ! 522: { tree d; ! 523: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE); ! 524: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 525: } ! 526: | typed_declspecs initdecls ';' ! 527: { ! 528: note_list_got_semicolon ($<ttype>$); ! 529: } ! 530: /* Normal case: make this fast. */ ! 531: | typed_declspecs declarator ';' ! 532: { tree d; ! 533: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE); ! 534: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 535: note_list_got_semicolon ($<ttype>$); ! 536: } ! 537: | declmods ';' ! 538: { pedwarn ("empty declaration"); } ! 539: | explicit_instantiation ';' ! 540: | typed_declspecs ';' ! 541: { ! 542: tree t = $<ttype>$; ! 543: shadow_tag (t); ! 544: if (TREE_CODE (t) == TREE_LIST ! 545: && TREE_PURPOSE (t) == NULL_TREE) ! 546: { ! 547: t = TREE_VALUE (t); ! 548: if (IS_AGGR_TYPE (t) ! 549: && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (t))) ! 550: { ! 551: if (CLASSTYPE_USE_TEMPLATE (t) == 0) ! 552: SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t); ! 553: else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t)) ! 554: error ("override declaration for already-expanded template"); ! 555: } ! 556: } ! 557: note_list_got_semicolon ($<ttype>$); ! 558: } ! 559: | error ';' ! 560: | error '}' ! 561: | ';' ! 562: ; ! 563: ! 564: fndef: ! 565: fn.def1 base_init compstmt_or_error ! 566: { ! 567: finish_function (lineno, 1); ! 568: /* finish_function performs these three statements: ! 569: ! 570: expand_end_bindings (getdecls (), 1, 0); ! 571: poplevel (1, 1, 0); ! 572: ! 573: expand_end_bindings (0, 0, 0); ! 574: poplevel (0, 0, 1); ! 575: */ ! 576: if ($<ttype>$) process_next_inline ($<ttype>$); ! 577: } ! 578: | fn.def1 return_init base_init compstmt_or_error ! 579: { ! 580: finish_function (lineno, 1); ! 581: /* finish_function performs these three statements: ! 582: ! 583: expand_end_bindings (getdecls (), 1, 0); ! 584: poplevel (1, 1, 0); ! 585: ! 586: expand_end_bindings (0, 0, 0); ! 587: poplevel (0, 0, 1); ! 588: */ ! 589: if ($<ttype>$) process_next_inline ($<ttype>$); ! 590: } ! 591: | fn.def1 nodecls compstmt_or_error ! 592: { finish_function (lineno, 0); ! 593: if ($<ttype>$) process_next_inline ($<ttype>$); } ! 594: | fn.def1 return_init ';' nodecls compstmt_or_error ! 595: { finish_function (lineno, 0); ! 596: if ($<ttype>$) process_next_inline ($<ttype>$); } ! 597: | fn.def1 return_init nodecls compstmt_or_error ! 598: { finish_function (lineno, 0); ! 599: if ($<ttype>$) process_next_inline ($<ttype>$); } ! 600: | typed_declspecs declarator error ! 601: {} ! 602: | declmods notype_declarator error ! 603: {} ! 604: | notype_declarator error ! 605: {} ! 606: ; ! 607: ! 608: fn.def1: ! 609: typed_declspecs declarator maybe_raises ! 610: { if (! start_function ($$, $2, $3, 0)) ! 611: YYERROR1; ! 612: reinit_parse_for_function (); ! 613: $$ = NULL_TREE; } ! 614: | declmods notype_declarator maybe_raises ! 615: { if (! start_function ($$, $2, $3, 0)) ! 616: YYERROR1; ! 617: reinit_parse_for_function (); ! 618: $$ = NULL_TREE; } ! 619: | notype_declarator maybe_raises ! 620: { if (! start_function (NULL_TREE, $$, $2, 0)) ! 621: YYERROR1; ! 622: reinit_parse_for_function (); ! 623: $$ = NULL_TREE; } ! 624: | PRE_PARSED_FUNCTION_DECL ! 625: { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1); ! 626: reinit_parse_for_function (); } ! 627: ; ! 628: ! 629: /* more C++ complexity. See component_decl for a comment on the ! 630: reduce/reduce conflict introduced by these rules. */ ! 631: fn.def2: ! 632: typed_declspecs '(' parmlist ')' type_quals maybe_raises ! 633: { ! 634: $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5); ! 635: $$ = start_method (TREE_CHAIN ($1), $$, $6); ! 636: rest_of_mdef: ! 637: if (! $$) ! 638: YYERROR1; ! 639: if (yychar == YYEMPTY) ! 640: yychar = YYLEX; ! 641: reinit_parse_for_method (yychar, $$); } ! 642: | typed_declspecs LEFT_RIGHT type_quals maybe_raises ! 643: { ! 644: $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), ! 645: empty_parms (), $3); ! 646: $$ = start_method (TREE_CHAIN ($1), $$, $4); ! 647: goto rest_of_mdef; ! 648: } ! 649: | typed_declspecs declarator maybe_raises ! 650: { $$ = start_method ($$, $2, $3); goto rest_of_mdef; } ! 651: | declmods notype_declarator maybe_raises ! 652: { $$ = start_method ($$, $2, $3); goto rest_of_mdef; } ! 653: | notype_declarator maybe_raises ! 654: { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; } ! 655: ; ! 656: ! 657: return_id: RETURN IDENTIFIER ! 658: { ! 659: if (! current_function_parms_stored) ! 660: store_parm_decls (); ! 661: $$ = $2; ! 662: } ! 663: ; ! 664: ! 665: return_init: return_id ! 666: { store_return_init ($<ttype>$, NULL_TREE); } ! 667: | return_id '=' init ! 668: { store_return_init ($<ttype>$, $3); } ! 669: | return_id '(' nonnull_exprlist ')' ! 670: { store_return_init ($<ttype>$, $3); } ! 671: | return_id LEFT_RIGHT ! 672: { store_return_init ($<ttype>$, NULL_TREE); } ! 673: ; ! 674: ! 675: base_init: ! 676: ':' .set_base_init member_init_list ! 677: { ! 678: if ($3 == 0) ! 679: error ("no base initializers given following ':'"); ! 680: setup_vtbl_ptr (); ! 681: /* Always keep the BLOCK node associated with the outermost ! 682: pair of curley braces of a function. These are needed ! 683: for correct operation of dwarfout.c. */ ! 684: keep_next_level (); ! 685: } ! 686: ; ! 687: ! 688: .set_base_init: ! 689: /* empty */ ! 690: { ! 691: if (! current_function_parms_stored) ! 692: store_parm_decls (); ! 693: ! 694: /* Flag that we are processing base and member initializers. */ ! 695: current_vtable_decl = error_mark_node; ! 696: ! 697: if (DECL_CONSTRUCTOR_P (current_function_decl)) ! 698: { ! 699: /* Make a contour for the initializer list. */ ! 700: pushlevel (0); ! 701: clear_last_expr (); ! 702: expand_start_bindings (0); ! 703: } ! 704: else if (current_class_type == NULL_TREE) ! 705: error ("base initializers not allowed for non-member functions"); ! 706: else if (! DECL_CONSTRUCTOR_P (current_function_decl)) ! 707: error ("only constructors take base initializers"); ! 708: } ! 709: ; ! 710: ! 711: member_init_list: ! 712: /* empty */ ! 713: { $$ = 0; } ! 714: | member_init ! 715: { $$ = 1; } ! 716: | member_init_list ',' member_init ! 717: | member_init_list error ! 718: ; ! 719: ! 720: member_init: '(' nonnull_exprlist ')' ! 721: { ! 722: if (current_class_name && !flag_traditional) ! 723: pedwarn ("anachronistic old style base class initializer"); ! 724: expand_member_init (C_C_D, NULL_TREE, $2); ! 725: } ! 726: | LEFT_RIGHT ! 727: { ! 728: if (current_class_name && !flag_traditional) ! 729: pedwarn ("anachronistic old style base class initializer"); ! 730: expand_member_init (C_C_D, NULL_TREE, void_type_node); ! 731: } ! 732: | notype_identifier '(' nonnull_exprlist ')' ! 733: { expand_member_init (C_C_D, $<ttype>$, $3); } ! 734: | notype_identifier LEFT_RIGHT ! 735: { expand_member_init (C_C_D, $<ttype>$, void_type_node); } ! 736: | complete_type_name '(' nonnull_exprlist ')' ! 737: { expand_member_init (C_C_D, $<ttype>$, $3); } ! 738: | complete_type_name LEFT_RIGHT ! 739: { expand_member_init (C_C_D, $<ttype>$, void_type_node); } ! 740: /* GNU extension */ ! 741: | notype_qualified_id '(' nonnull_exprlist ')' ! 742: { ! 743: do_member_init (OP0 ($1), OP1 ($1), $3); ! 744: } ! 745: | notype_qualified_id LEFT_RIGHT ! 746: { ! 747: do_member_init (OP0 ($1), OP1 ($1), void_type_node); ! 748: } ! 749: ; ! 750: ! 751: identifier: ! 752: IDENTIFIER ! 753: | TYPENAME ! 754: | PTYPENAME ! 755: ; ! 756: ! 757: notype_identifier: ! 758: IDENTIFIER ! 759: | PTYPENAME %prec EMPTY ! 760: ; ! 761: ! 762: identifier_defn: ! 763: IDENTIFIER_DEFN ! 764: | TYPENAME_DEFN ! 765: | PTYPENAME_DEFN ! 766: ; ! 767: ! 768: explicit_instantiation: ! 769: TEMPLATE specialization template_instantiation ! 770: { do_type_instantiation ($3 ? $3 : $2, NULL_TREE); } ! 771: | TEMPLATE typed_declspecs declarator ! 772: { do_function_instantiation ($2, $3, NULL_TREE); } ! 773: | SCSPEC TEMPLATE specialization template_instantiation ! 774: { do_type_instantiation ($4 ? $4 : $3, $1); } ! 775: | SCSPEC TEMPLATE typed_declspecs declarator ! 776: { do_function_instantiation ($3, $4, $1); } ! 777: ; ! 778: ! 779: template_type: ! 780: template_type_name tmpl.2 template_instantiation ! 781: { if ($3) $$ = $3; } ! 782: ; ! 783: ! 784: template_type_name: ! 785: PTYPENAME '<' template_arg_list '>' ! 786: { $$ = lookup_template_class ($$, $3, NULL_TREE); } ! 787: | PTYPENAME '<' '>' ! 788: { $$ = lookup_template_class ($$, NULL_TREE, NULL_TREE); } ! 789: | TYPENAME '<' template_arg_list '>' ! 790: { $$ = lookup_template_class ($$, $3, NULL_TREE); } ! 791: ; ! 792: ! 793: tmpl.2: ! 794: /* empty */ %prec EMPTY ! 795: { $$ = instantiate_class_template ($<ttype>0, 1); } ! 796: ; ! 797: ! 798: template_arg_list: ! 799: template_arg ! 800: { $$ = build_tree_list (NULL_TREE, $$); } ! 801: | template_arg_list ',' template_arg ! 802: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } ! 803: ; ! 804: ! 805: template_arg: ! 806: type_id ! 807: { $$ = groktypename ($$); } ! 808: | expr_no_commas %prec UNARY ! 809: ; ! 810: ! 811: template_instantiate_once: ! 812: PRE_PARSED_CLASS_DECL maybe_base_class_list ! 813: { ! 814: tree t, decl, tmpl; ! 815: ! 816: tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE ($1)); ! 817: t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, $1, $2, 0); ! 818: set_current_level_tags_transparency (1); ! 819: my_friendly_assert (TREE_CODE (t) == RECORD_TYPE ! 820: || TREE_CODE (t) == UNION_TYPE, 257); ! 821: $<ttype>$ = t; ! 822: ! 823: /* Now, put a copy of the decl in global scope, to avoid ! 824: recursive expansion. */ ! 825: decl = IDENTIFIER_LOCAL_VALUE ($1); ! 826: if (!decl) ! 827: decl = IDENTIFIER_CLASS_VALUE ($1); ! 828: /* Now, put a copy of the decl in global scope, to avoid ! 829: recursive expansion. */ ! 830: if (decl) ! 831: { ! 832: /* Need to copy it to clear the chain pointer, ! 833: and need to get it into permanent storage. */ ! 834: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 258); ! 835: push_obstacks (&permanent_obstack, &permanent_obstack); ! 836: decl = copy_node (decl); ! 837: if (DECL_LANG_SPECIFIC (decl)) ! 838: copy_lang_decl (decl); ! 839: pop_obstacks (); ! 840: pushdecl_top_level (decl); ! 841: } ! 842: /* Kludge; see instantiate_class_template. */ ! 843: TYPE_BEING_DEFINED (t) = 0; ! 844: } ! 845: left_curly opt.component_decl_list '}' ! 846: { ! 847: tree t = finish_struct ($<ttype>3, $5, 0); ! 848: ! 849: pop_obstacks (); ! 850: end_template_instantiation ($1); ! 851: ! 852: /* Now go after the methods & class data. */ ! 853: instantiate_member_templates ($1); ! 854: ! 855: pop_tinst_level(); ! 856: ! 857: CLASSTYPE_GOT_SEMICOLON (t) = 1; ! 858: } ! 859: ; ! 860: ! 861: template_instantiation: ! 862: /* empty */ ! 863: { $$ = NULL_TREE; } ! 864: | template_instantiate_once ! 865: { $$ = $1; } ! 866: ; ! 867: ! 868: template_instantiate_some: ! 869: /* empty */ ! 870: { $$ = NULL_TREE; /* never used from here... */} ! 871: | template_instantiate_once template_instantiate_some ! 872: { $$ = $1; /*???*/ } ! 873: ; ! 874: ! 875: unop: '-' ! 876: { $$ = NEGATE_EXPR; } ! 877: | '+' ! 878: { $$ = CONVERT_EXPR; } ! 879: | PLUSPLUS ! 880: { $$ = PREINCREMENT_EXPR; } ! 881: | MINUSMINUS ! 882: { $$ = PREDECREMENT_EXPR; } ! 883: | '!' ! 884: { $$ = TRUTH_NOT_EXPR; } ! 885: ; ! 886: ! 887: expr: nontrivial_exprlist ! 888: { $$ = build_x_compound_expr ($$); } ! 889: | expr_no_commas ! 890: ; ! 891: ! 892: paren_expr_or_null: ! 893: LEFT_RIGHT ! 894: { error ("ANSI C++ forbids an empty condition for `%s'", ! 895: cond_stmt_keyword); ! 896: $$ = integer_zero_node; } ! 897: | '(' expr ')' ! 898: { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, ! 899: bool_truthvalue_conversion ($2)); } ! 900: ; ! 901: ! 902: paren_cond_or_null: ! 903: LEFT_RIGHT ! 904: { error ("ANSI C++ forbids an empty condition for `%s'", ! 905: cond_stmt_keyword); ! 906: $$ = integer_zero_node; } ! 907: | '(' condition ')' ! 908: { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, ! 909: bool_truthvalue_conversion ($2)); } ! 910: ; ! 911: ! 912: xcond: ! 913: /* empty */ ! 914: { $$ = NULL_TREE; } ! 915: | condition ! 916: { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, ! 917: bool_truthvalue_conversion ($$)); } ! 918: | error ! 919: { $$ = NULL_TREE; } ! 920: ; ! 921: ! 922: condition: ! 923: type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '=' ! 924: { { ! 925: tree d; ! 926: for (d = getdecls (); d; d = TREE_CHAIN (d)) ! 927: if (TREE_CODE (d) == TYPE_DECL) { ! 928: tree s = TREE_TYPE (d); ! 929: if (TREE_CODE (s) == RECORD_TYPE) ! 930: cp_error ("definition of class `%T' in condition", s); ! 931: else if (TREE_CODE (s) == ENUMERAL_TYPE) ! 932: cp_error ("definition of enum `%T' in condition", s); ! 933: } ! 934: } ! 935: current_declspecs = $1; ! 936: $<itype>6 = suspend_momentary (); ! 937: $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, $3); ! 938: cplus_decl_attributes ($<ttype>$, $5); ! 939: } ! 940: init ! 941: { ! 942: finish_decl ($<ttype>7, $8, $5, 0); ! 943: resume_momentary ($<itype>6); ! 944: $$ = $<ttype>7; ! 945: if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) ! 946: cp_error ("definition of array `%#D' in condition", $$); ! 947: } ! 948: | expr ! 949: ; ! 950: ! 951: already_scoped_stmt: ! 952: '{' '}' ! 953: { finish_stmt (); } ! 954: | '{' maybe_label_decls stmts '}' ! 955: { finish_stmt (); } ! 956: | '{' maybe_label_decls error '}' ! 957: { finish_stmt (); } ! 958: | simple_stmt ! 959: ; ! 960: ! 961: ! 962: nontrivial_exprlist: ! 963: expr_no_commas ',' expr_no_commas ! 964: { $$ = tree_cons (NULL_TREE, $$, ! 965: build_tree_list (NULL_TREE, $3)); } ! 966: | expr_no_commas ',' error ! 967: { $$ = tree_cons (NULL_TREE, $$, ! 968: build_tree_list (NULL_TREE, error_mark_node)); } ! 969: | nontrivial_exprlist ',' expr_no_commas ! 970: { chainon ($$, build_tree_list (NULL_TREE, $3)); } ! 971: | nontrivial_exprlist ',' error ! 972: { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); } ! 973: ; ! 974: ! 975: nonnull_exprlist: ! 976: expr_no_commas ! 977: { $$ = build_tree_list (NULL_TREE, $$); } ! 978: | nontrivial_exprlist ! 979: ; ! 980: ! 981: unary_expr: ! 982: primary %prec UNARY ! 983: { ! 984: #if 0 ! 985: if (TREE_CODE ($$) == TYPE_EXPR) ! 986: $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1); ! 987: #endif ! 988: } ! 989: /* __extension__ turns off -pedantic for following primary. */ ! 990: | EXTENSION ! 991: { $<itype>1 = pedantic; ! 992: pedantic = 0; } ! 993: cast_expr %prec UNARY ! 994: { $$ = $3; ! 995: pedantic = $<itype>1; } ! 996: | '*' cast_expr %prec UNARY ! 997: { $$ = build_x_indirect_ref ($2, "unary *"); } ! 998: | '&' cast_expr %prec UNARY ! 999: { $$ = build_x_unary_op (ADDR_EXPR, $2); } ! 1000: | '~' cast_expr ! 1001: { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } ! 1002: | unop cast_expr %prec UNARY ! 1003: { $$ = build_x_unary_op ($1, $2); ! 1004: if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST) ! 1005: TREE_NEGATED_INT ($$) = 1; ! 1006: overflow_warning ($$); ! 1007: } ! 1008: /* Refer to the address of a label as a pointer. */ ! 1009: | ANDAND identifier ! 1010: { tree label = lookup_label ($2); ! 1011: if (label == NULL_TREE) ! 1012: $$ = null_pointer_node; ! 1013: else ! 1014: { ! 1015: TREE_USED (label) = 1; ! 1016: $$ = build1 (ADDR_EXPR, ptr_type_node, label); ! 1017: TREE_CONSTANT ($$) = 1; ! 1018: } ! 1019: } ! 1020: | SIZEOF unary_expr %prec UNARY ! 1021: { if (TREE_CODE ($2) == COMPONENT_REF ! 1022: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1))) ! 1023: error ("sizeof applied to a bit-field"); ! 1024: /* ANSI says arrays and functions are converted inside comma. ! 1025: But we can't really convert them in build_compound_expr ! 1026: because that would break commas in lvalues. ! 1027: So do the conversion here if operand was a comma. */ ! 1028: if (TREE_CODE ($2) == COMPOUND_EXPR ! 1029: && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE ! 1030: || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE)) ! 1031: $2 = default_conversion ($2); ! 1032: else if (TREE_CODE ($2) == TREE_LIST) ! 1033: { ! 1034: tree t = TREE_VALUE ($2); ! 1035: if (t != NULL_TREE ! 1036: && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) ! 1037: pedwarn ("ANSI C++ forbids using sizeof() on a function"); ! 1038: } ! 1039: $$ = c_sizeof (TREE_TYPE ($2)); } ! 1040: | SIZEOF '(' type_id ')' %prec HYPERUNARY ! 1041: { $$ = c_sizeof (groktypename ($3)); } ! 1042: | ALIGNOF unary_expr %prec UNARY ! 1043: { $$ = grok_alignof ($2); } ! 1044: | ALIGNOF '(' type_id ')' %prec HYPERUNARY ! 1045: { $$ = c_alignof (groktypename ($3)); } ! 1046: ! 1047: /* The %prec EMPTY's here are required by the = init initializer ! 1048: syntax extension; see below. */ ! 1049: | new new_type_id %prec EMPTY ! 1050: { $$ = build_new (NULL_TREE, $2, NULL_TREE, $1); } ! 1051: | new new_type_id new_initializer ! 1052: { $$ = build_new (NULL_TREE, $2, $3, $1); } ! 1053: | new new_placement new_type_id %prec EMPTY ! 1054: { $$ = build_new ($2, $3, NULL_TREE, $1); } ! 1055: | new new_placement new_type_id new_initializer ! 1056: { $$ = build_new ($2, $3, $4, $1); } ! 1057: | new '(' type_id ')' %prec EMPTY ! 1058: { $$ = build_new (NULL_TREE, groktypename($3), ! 1059: NULL_TREE, $1); } ! 1060: | new '(' type_id ')' new_initializer ! 1061: { $$ = build_new (NULL_TREE, groktypename($3), $5, $1); } ! 1062: | new new_placement '(' type_id ')' %prec EMPTY ! 1063: { $$ = build_new ($2, groktypename($4), NULL_TREE, $1); } ! 1064: | new new_placement '(' type_id ')' new_initializer ! 1065: { $$ = build_new ($2, groktypename($4), $6, $1); } ! 1066: ! 1067: | delete cast_expr %prec UNARY ! 1068: { $$ = delete_sanity ($2, NULL_TREE, 0, $1); } ! 1069: | delete '[' ']' cast_expr %prec UNARY ! 1070: { $$ = delete_sanity ($4, NULL_TREE, 1, $1); ! 1071: if (yychar == YYEMPTY) ! 1072: yychar = YYLEX; } ! 1073: | delete '[' expr ']' cast_expr %prec UNARY ! 1074: { $$ = delete_sanity ($5, $3, 2, $1); ! 1075: if (yychar == YYEMPTY) ! 1076: yychar = YYLEX; } ! 1077: ; ! 1078: ! 1079: new_placement: ! 1080: '(' nonnull_exprlist ')' ! 1081: { $$ = $2; } ! 1082: | '{' nonnull_exprlist '}' ! 1083: { ! 1084: $$ = $2; ! 1085: pedwarn ("old style placement syntax, use () instead"); ! 1086: } ! 1087: ; ! 1088: ! 1089: new_initializer: ! 1090: '(' nonnull_exprlist ')' ! 1091: { $$ = $2; } ! 1092: | LEFT_RIGHT ! 1093: { $$ = NULL_TREE; } ! 1094: | '(' typespec ')' ! 1095: { ! 1096: cp_error ("`%T' is not a valid expression", $2); ! 1097: $$ = error_mark_node; ! 1098: } ! 1099: /* GNU extension so people can use initializer lists. Note that ! 1100: this alters the meaning of `new int = 1', which was previously ! 1101: syntactically valid but semantically invalid. */ ! 1102: | '=' init ! 1103: { ! 1104: if (flag_ansi) ! 1105: pedwarn ("ANSI C++ forbids initialization of new expression with `='"); ! 1106: $$ = $2; ! 1107: } ! 1108: ; ! 1109: ! 1110: /* This is necessary to postpone reduction of `int ((int)(int)(int))'. */ ! 1111: regcast_or_absdcl: ! 1112: '(' type_id ')' %prec EMPTY ! 1113: { $2 = tree_cons (NULL_TREE, $2, void_list_node); ! 1114: TREE_PARMLIST ($2) = 1; ! 1115: $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, ! 1116: NULL_TREE); } ! 1117: | regcast_or_absdcl '(' type_id ')' %prec EMPTY ! 1118: { $3 = tree_cons (NULL_TREE, $3, void_list_node); ! 1119: TREE_PARMLIST ($3) = 1; ! 1120: $$ = build_parse_node (CALL_EXPR, $$, $3, NULL_TREE); } ! 1121: ; ! 1122: ! 1123: cast_expr: ! 1124: sub_cast_expr ! 1125: | regcast_or_absdcl sub_cast_expr %prec UNARY ! 1126: { $$ = reparse_absdcl_as_casts ($$, $2); } ! 1127: | regcast_or_absdcl '{' initlist maybecomma '}' %prec UNARY ! 1128: { ! 1129: tree init = build_nt (CONSTRUCTOR, NULL_TREE, ! 1130: nreverse ($3)); ! 1131: if (flag_ansi) ! 1132: pedwarn ("ANSI C++ forbids constructor-expressions"); ! 1133: /* Indicate that this was a GNU C constructor expression. */ ! 1134: TREE_HAS_CONSTRUCTOR (init) = 1; ! 1135: ! 1136: $$ = reparse_absdcl_as_casts ($$, init); ! 1137: } ! 1138: ; ! 1139: ! 1140: sub_cast_expr: ! 1141: unary_expr ! 1142: | HEADOF '(' expr ')' ! 1143: { $$ = build_headof ($3); } ! 1144: | CLASSOF '(' expr ')' ! 1145: { $$ = build_classof ($3); } ! 1146: | CLASSOF '(' TYPENAME ')' ! 1147: { if (is_aggr_typedef ($3, 1)) ! 1148: { ! 1149: tree type = IDENTIFIER_TYPE_VALUE ($3); ! 1150: if (! IS_SIGNATURE(type)) ! 1151: $$ = CLASSTYPE_DOSSIER (type); ! 1152: else ! 1153: { ! 1154: sorry ("signature name as argument of `classof'"); ! 1155: $$ = error_mark_node; ! 1156: } ! 1157: } ! 1158: else ! 1159: $$ = error_mark_node; ! 1160: } ! 1161: ; ! 1162: ! 1163: expr_no_commas: ! 1164: cast_expr ! 1165: /* Handle general members. */ ! 1166: | expr_no_commas POINTSAT_STAR expr_no_commas ! 1167: { $$ = build_x_binary_op (MEMBER_REF, $$, $3); } ! 1168: | expr_no_commas DOT_STAR expr_no_commas ! 1169: { $$ = build_m_component_ref ($$, $3); } ! 1170: | expr_no_commas '+' expr_no_commas ! 1171: { $$ = build_x_binary_op ($2, $$, $3); } ! 1172: | expr_no_commas '-' expr_no_commas ! 1173: { $$ = build_x_binary_op ($2, $$, $3); } ! 1174: | expr_no_commas '*' expr_no_commas ! 1175: { $$ = build_x_binary_op ($2, $$, $3); } ! 1176: | expr_no_commas '/' expr_no_commas ! 1177: { $$ = build_x_binary_op ($2, $$, $3); } ! 1178: | expr_no_commas '%' expr_no_commas ! 1179: { $$ = build_x_binary_op ($2, $$, $3); } ! 1180: | expr_no_commas LSHIFT expr_no_commas ! 1181: { $$ = build_x_binary_op ($2, $$, $3); } ! 1182: | expr_no_commas RSHIFT expr_no_commas ! 1183: { $$ = build_x_binary_op ($2, $$, $3); } ! 1184: | expr_no_commas ARITHCOMPARE expr_no_commas ! 1185: { $$ = build_x_binary_op ($2, $$, $3); } ! 1186: | expr_no_commas '<' expr_no_commas ! 1187: { $$ = build_x_binary_op (LT_EXPR, $$, $3); } ! 1188: | expr_no_commas '>' expr_no_commas ! 1189: { $$ = build_x_binary_op (GT_EXPR, $$, $3); } ! 1190: | expr_no_commas EQCOMPARE expr_no_commas ! 1191: { $$ = build_x_binary_op ($2, $$, $3); } ! 1192: | expr_no_commas MIN_MAX expr_no_commas ! 1193: { $$ = build_x_binary_op ($2, $$, $3); } ! 1194: | expr_no_commas '&' expr_no_commas ! 1195: { $$ = build_x_binary_op ($2, $$, $3); } ! 1196: | expr_no_commas '|' expr_no_commas ! 1197: { $$ = build_x_binary_op ($2, $$, $3); } ! 1198: | expr_no_commas '^' expr_no_commas ! 1199: { $$ = build_x_binary_op ($2, $$, $3); } ! 1200: | expr_no_commas ANDAND expr_no_commas ! 1201: { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } ! 1202: | expr_no_commas OROR expr_no_commas ! 1203: { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } ! 1204: | expr_no_commas '?' xexpr ':' expr_no_commas ! 1205: { $$ = build_x_conditional_expr ($$, $3, $5); } ! 1206: | expr_no_commas '=' expr_no_commas ! 1207: { $$ = build_modify_expr ($$, NOP_EXPR, $3); } ! 1208: | expr_no_commas ASSIGN expr_no_commas ! 1209: { register tree rval; ! 1210: if ((rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3, ! 1211: make_node ($2)))) ! 1212: $$ = rval; ! 1213: else ! 1214: $$ = build_modify_expr ($$, $2, $3); } ! 1215: | THROW ! 1216: { $$ = build_throw (NULL_TREE); } ! 1217: | THROW expr_no_commas ! 1218: { $$ = build_throw ($2); } ! 1219: /* These extensions are not defined. The second arg to build_m_component_ref ! 1220: is old, build_m_component_ref now does an implicit ! 1221: build_indirect_ref (x, NULL_PTR) on the second argument. ! 1222: | object '&' expr_no_commas %prec UNARY ! 1223: { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); } ! 1224: | object unop expr_no_commas %prec UNARY ! 1225: { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); } ! 1226: | object '(' type_id ')' expr_no_commas %prec UNARY ! 1227: { tree type = groktypename ($3); ! 1228: $$ = build_m_component_ref ($$, build_c_cast (type, $5)); } ! 1229: | object primary_no_id %prec UNARY ! 1230: { $$ = build_m_component_ref ($$, $2); } ! 1231: */ ! 1232: ; ! 1233: ! 1234: notype_unqualified_id: ! 1235: '~' see_typename identifier ! 1236: { $$ = build_parse_node (BIT_NOT_EXPR, $3); } ! 1237: | operator_name ! 1238: | IDENTIFIER ! 1239: | PTYPENAME %prec EMPTY ! 1240: ; ! 1241: ! 1242: unqualified_id: ! 1243: notype_unqualified_id ! 1244: | TYPENAME ! 1245: ; ! 1246: ! 1247: expr_or_declarator: ! 1248: notype_unqualified_id ! 1249: | notype_qualified_id ! 1250: | '*' expr_or_declarator %prec UNARY ! 1251: { $$ = build_parse_node (INDIRECT_REF, $2); } ! 1252: | '&' expr_or_declarator %prec UNARY ! 1253: { $$ = build_parse_node (ADDR_EXPR, $2); } ! 1254: ; ! 1255: ! 1256: direct_notype_declarator: ! 1257: complex_direct_notype_declarator ! 1258: | notype_unqualified_id ! 1259: | notype_qualified_id ! 1260: { push_nested_class (TREE_TYPE (OP0 ($$)), 3); ! 1261: TREE_COMPLEXITY ($$) = current_class_depth; } ! 1262: ; ! 1263: ! 1264: primary: ! 1265: notype_unqualified_id ! 1266: { ! 1267: if (TREE_CODE ($$) == BIT_NOT_EXPR) ! 1268: $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($$, 0)); ! 1269: else if (IDENTIFIER_OPNAME_P ($$)) ! 1270: { ! 1271: tree op = $$; ! 1272: $$ = lookup_name (op, 0); ! 1273: if ($$ == NULL_TREE) ! 1274: { ! 1275: if (op != ansi_opname[ERROR_MARK]) ! 1276: error ("operator %s not defined", ! 1277: operator_name_string (op)); ! 1278: $$ = error_mark_node; ! 1279: } ! 1280: } ! 1281: else ! 1282: $$ = do_identifier ($$); ! 1283: } ! 1284: | CONSTANT ! 1285: | boolean.literal ! 1286: | string ! 1287: { $$ = combine_strings ($$); } ! 1288: | '(' expr ')' ! 1289: { $$ = $2; } ! 1290: | '(' error ')' ! 1291: { $$ = error_mark_node; } ! 1292: | '(' ! 1293: { if (current_function_decl == 0) ! 1294: { ! 1295: error ("braced-group within expression allowed only inside a function"); ! 1296: YYERROR; ! 1297: } ! 1298: keep_next_level (); ! 1299: $<ttype>$ = expand_start_stmt_expr (); } ! 1300: compstmt ')' ! 1301: { tree rtl_exp; ! 1302: if (flag_ansi) ! 1303: pedwarn ("ANSI C++ forbids braced-groups within expressions"); ! 1304: rtl_exp = expand_end_stmt_expr ($<ttype>2); ! 1305: /* The statements have side effects, so the group does. */ ! 1306: TREE_SIDE_EFFECTS (rtl_exp) = 1; ! 1307: ! 1308: if (TREE_CODE ($3) == BLOCK) ! 1309: { ! 1310: /* Make a BIND_EXPR for the BLOCK already made. */ ! 1311: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp), ! 1312: NULL_TREE, rtl_exp, $3); ! 1313: /* Remove the block from the tree at this point. ! 1314: It gets put back at the proper place ! 1315: when the BIND_EXPR is expanded. */ ! 1316: delete_block ($3); ! 1317: } ! 1318: else ! 1319: $$ = $3; ! 1320: } ! 1321: | primary '(' nonnull_exprlist ')' ! 1322: { /* [eichin:19911016.1902EST] */ ! 1323: $<ttype>$ = build_x_function_call ($1, $3, current_class_decl); ! 1324: /* here we instantiate_class_template as needed... */ ! 1325: do_pending_templates (); ! 1326: } template_instantiate_some { ! 1327: if (TREE_CODE ($<ttype>5) == CALL_EXPR ! 1328: && TREE_TYPE ($<ttype>5) != void_type_node) ! 1329: $$ = require_complete_type ($<ttype>5); ! 1330: else ! 1331: $$ = $<ttype>5; ! 1332: } ! 1333: | primary LEFT_RIGHT ! 1334: { ! 1335: $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); ! 1336: if (TREE_CODE ($$) == CALL_EXPR ! 1337: && TREE_TYPE ($$) != void_type_node) ! 1338: $$ = require_complete_type ($$); ! 1339: } ! 1340: | primary '[' expr ']' ! 1341: { $$ = grok_array_decl ($$, $3); } ! 1342: | primary PLUSPLUS ! 1343: { /* If we get an OFFSET_REF, turn it into what it really ! 1344: means (e.g., a COMPONENT_REF). This way if we've got, ! 1345: say, a reference to a static member that's being operated ! 1346: on, we don't end up trying to find a member operator for ! 1347: the class it's in. */ ! 1348: if (TREE_CODE ($$) == OFFSET_REF) ! 1349: $$ = resolve_offset_ref ($$); ! 1350: $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } ! 1351: | primary MINUSMINUS ! 1352: { if (TREE_CODE ($$) == OFFSET_REF) ! 1353: $$ = resolve_offset_ref ($$); ! 1354: $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } ! 1355: /* C++ extensions */ ! 1356: | THIS ! 1357: { if (current_class_decl) ! 1358: { ! 1359: #ifdef WARNING_ABOUT_CCD ! 1360: TREE_USED (current_class_decl) = 1; ! 1361: #endif ! 1362: $$ = current_class_decl; ! 1363: } ! 1364: else if (current_function_decl ! 1365: && DECL_STATIC_FUNCTION_P (current_function_decl)) ! 1366: { ! 1367: error ("`this' is unavailable for static member functions"); ! 1368: $$ = error_mark_node; ! 1369: } ! 1370: else ! 1371: { ! 1372: if (current_function_decl) ! 1373: error ("invalid use of `this' in non-member function"); ! 1374: else ! 1375: error ("invalid use of `this' at top level"); ! 1376: $$ = error_mark_node; ! 1377: } ! 1378: } ! 1379: | TYPE_QUAL '(' nonnull_exprlist ')' ! 1380: { ! 1381: tree type; ! 1382: tree id = $$; ! 1383: ! 1384: /* This is a C cast in C++'s `functional' notation. */ ! 1385: if ($3 == error_mark_node) ! 1386: { ! 1387: $$ = error_mark_node; ! 1388: break; ! 1389: } ! 1390: #if 0 ! 1391: if ($3 == NULL_TREE) ! 1392: { ! 1393: error ("cannot cast null list to type `%s'", ! 1394: IDENTIFIER_POINTER (TYPE_NAME (id))); ! 1395: $$ = error_mark_node; ! 1396: break; ! 1397: } ! 1398: #endif ! 1399: #if 0 ! 1400: /* type is not set! (mrs) */ ! 1401: if (type == error_mark_node) ! 1402: $$ = error_mark_node; ! 1403: else ! 1404: #endif ! 1405: { ! 1406: if (id == ridpointers[(int) RID_CONST]) ! 1407: type = build_type_variant (integer_type_node, 1, 0); ! 1408: else if (id == ridpointers[(int) RID_VOLATILE]) ! 1409: type = build_type_variant (integer_type_node, 0, 1); ! 1410: #if 0 ! 1411: /* should not be able to get here (mrs) */ ! 1412: else if (id == ridpointers[(int) RID_FRIEND]) ! 1413: { ! 1414: error ("cannot cast expression to `friend' type"); ! 1415: $$ = error_mark_node; ! 1416: break; ! 1417: } ! 1418: #endif ! 1419: else my_friendly_abort (79); ! 1420: $$ = build_c_cast (type, build_compound_expr ($3)); ! 1421: } ! 1422: } ! 1423: | functional_cast ! 1424: | DYNAMIC_CAST '<' type_id '>' '(' expr ')' ! 1425: { tree type = groktypename ($3); ! 1426: $$ = build_dynamic_cast (type, $6); } ! 1427: | STATIC_CAST '<' type_id '>' '(' expr ')' ! 1428: { tree type = groktypename ($3); ! 1429: $$ = build_static_cast (type, $6); } ! 1430: | REINTERPRET_CAST '<' type_id '>' '(' expr ')' ! 1431: { tree type = groktypename ($3); ! 1432: $$ = build_reinterpret_cast (type, $6); } ! 1433: | CONST_CAST '<' type_id '>' '(' expr ')' ! 1434: { tree type = groktypename ($3); ! 1435: $$ = build_const_cast (type, $6); } ! 1436: | TYPEID '(' expr ')' ! 1437: { $$ = build_typeid ($3); } ! 1438: | TYPEID '(' type_id ')' ! 1439: { tree type = groktypename ($3); ! 1440: $$ = get_typeid (type); } ! 1441: | global_scope IDENTIFIER ! 1442: { ! 1443: do_scoped_id: ! 1444: $$ = IDENTIFIER_GLOBAL_VALUE ($2); ! 1445: if (yychar == YYEMPTY) ! 1446: yychar = YYLEX; ! 1447: if (! $$) ! 1448: { ! 1449: if (yychar == '(' || yychar == LEFT_RIGHT) ! 1450: $$ = implicitly_declare ($2); ! 1451: else ! 1452: { ! 1453: if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node) ! 1454: error ("undeclared variable `%s' (first use here)", ! 1455: IDENTIFIER_POINTER ($2)); ! 1456: $$ = error_mark_node; ! 1457: /* Prevent repeated error messages. */ ! 1458: IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node; ! 1459: } ! 1460: } ! 1461: else ! 1462: { ! 1463: if (TREE_CODE ($$) == ADDR_EXPR) ! 1464: assemble_external (TREE_OPERAND ($$, 0)); ! 1465: else ! 1466: assemble_external ($$); ! 1467: TREE_USED ($$) = 1; ! 1468: } ! 1469: if (TREE_CODE ($$) == CONST_DECL) ! 1470: { ! 1471: /* XXX CHS - should we set TREE_USED of the constant? */ ! 1472: $$ = DECL_INITIAL ($$); ! 1473: /* This is to prevent an enum whose value is 0 ! 1474: from being considered a null pointer constant. */ ! 1475: $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$); ! 1476: TREE_CONSTANT ($$) = 1; ! 1477: } ! 1478: ! 1479: } ! 1480: | global_scope operator_name ! 1481: { ! 1482: got_scope = NULL_TREE; ! 1483: if (TREE_CODE ($2) == IDENTIFIER_NODE) ! 1484: goto do_scoped_id; ! 1485: $$ = $2; ! 1486: } ! 1487: | overqualified_id %prec HYPERUNARY ! 1488: { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } ! 1489: | overqualified_id '(' nonnull_exprlist ')' ! 1490: { $$ = build_member_call (OP0 ($$), OP1 ($$), $3); } ! 1491: | overqualified_id LEFT_RIGHT ! 1492: { $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); } ! 1493: | object unqualified_id %prec UNARY ! 1494: { $$ = build_component_ref ($$, $2, NULL_TREE, 1); } ! 1495: | object qualified_id %prec UNARY ! 1496: { $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } ! 1497: | object unqualified_id '(' nonnull_exprlist ')' ! 1498: { ! 1499: #if 0 ! 1500: /* This is a future direction of this code, but because ! 1501: build_x_function_call cannot always undo what is done ! 1502: in build_component_ref entirely yet, we cannot do this. */ ! 1503: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, $$); ! 1504: if (TREE_CODE ($$) == CALL_EXPR ! 1505: && TREE_TYPE ($$) != void_type_node) ! 1506: $$ = require_complete_type ($$); ! 1507: #else ! 1508: $$ = build_method_call ($$, $2, $4, NULL_TREE, ! 1509: (LOOKUP_NORMAL|LOOKUP_AGGR)); ! 1510: #endif ! 1511: } ! 1512: | object unqualified_id LEFT_RIGHT ! 1513: { ! 1514: #if 0 ! 1515: /* This is a future direction of this code, but because ! 1516: build_x_function_call cannot always undo what is done ! 1517: in build_component_ref entirely yet, we cannot do this. */ ! 1518: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, $$); ! 1519: if (TREE_CODE ($$) == CALL_EXPR ! 1520: && TREE_TYPE ($$) != void_type_node) ! 1521: $$ = require_complete_type ($$); ! 1522: #else ! 1523: $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE, ! 1524: (LOOKUP_NORMAL|LOOKUP_AGGR)); ! 1525: #endif ! 1526: } ! 1527: | object qualified_id '(' nonnull_exprlist ')' ! 1528: { ! 1529: if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) ! 1530: { ! 1531: warning ("signature name in scope resolution ignored"); ! 1532: $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE, ! 1533: (LOOKUP_NORMAL|LOOKUP_AGGR)); ! 1534: } ! 1535: else ! 1536: $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4); ! 1537: } ! 1538: | object qualified_id LEFT_RIGHT ! 1539: { ! 1540: if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) ! 1541: { ! 1542: warning ("signature name in scope resolution ignored"); ! 1543: $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE, ! 1544: (LOOKUP_NORMAL|LOOKUP_AGGR)); ! 1545: } ! 1546: else ! 1547: $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE); ! 1548: } ! 1549: /* p->int::~int() is valid -- 12.4 */ ! 1550: | object '~' TYPESPEC LEFT_RIGHT ! 1551: { ! 1552: if (TREE_CODE (TREE_TYPE ($1)) ! 1553: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))) ! 1554: cp_error ("`%E' is not of type `%T'", $1, $3); ! 1555: $$ = convert (void_type_node, $1); ! 1556: } ! 1557: | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT ! 1558: { ! 1559: if ($2 != $5) ! 1560: cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5); ! 1561: if (TREE_CODE (TREE_TYPE ($1)) ! 1562: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2)))) ! 1563: cp_error ("`%E' is not of type `%T'", $1, $2); ! 1564: $$ = convert (void_type_node, $1); ! 1565: } ! 1566: ; ! 1567: ! 1568: /* Not needed for now. ! 1569: ! 1570: primary_no_id: ! 1571: '(' expr ')' ! 1572: { $$ = $2; } ! 1573: | '(' error ')' ! 1574: { $$ = error_mark_node; } ! 1575: | '(' ! 1576: { if (current_function_decl == 0) ! 1577: { ! 1578: error ("braced-group within expression allowed only inside a function"); ! 1579: YYERROR; ! 1580: } ! 1581: $<ttype>$ = expand_start_stmt_expr (); } ! 1582: compstmt ')' ! 1583: { if (flag_ansi) ! 1584: pedwarn ("ANSI C++ forbids braced-groups within expressions"); ! 1585: $$ = expand_end_stmt_expr ($<ttype>2); } ! 1586: | primary_no_id '(' nonnull_exprlist ')' ! 1587: { $$ = build_x_function_call ($$, $3, current_class_decl); } ! 1588: | primary_no_id LEFT_RIGHT ! 1589: { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); } ! 1590: | primary_no_id '[' expr ']' ! 1591: { goto do_array; } ! 1592: | primary_no_id PLUSPLUS ! 1593: { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } ! 1594: | primary_no_id MINUSMINUS ! 1595: { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } ! 1596: | SCOPE IDENTIFIER ! 1597: { goto do_scoped_id; } ! 1598: | SCOPE operator_name ! 1599: { if (TREE_CODE ($2) == IDENTIFIER_NODE) ! 1600: goto do_scoped_id; ! 1601: goto do_scoped_operator; ! 1602: } ! 1603: ; ! 1604: */ ! 1605: ! 1606: new: NEW ! 1607: { $$ = 0; } ! 1608: | global_scope NEW ! 1609: { got_scope = NULL_TREE; $$ = 1; } ! 1610: ; ! 1611: ! 1612: delete: DELETE ! 1613: { $$ = 0; } ! 1614: | global_scope delete ! 1615: { got_scope = NULL_TREE; $$ = 1; } ! 1616: ; ! 1617: ! 1618: boolean.literal: ! 1619: CXX_TRUE ! 1620: { $$ = true_node; } ! 1621: | CXX_FALSE ! 1622: { $$ = false_node; } ! 1623: ; ! 1624: ! 1625: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ ! 1626: string: ! 1627: STRING ! 1628: | string STRING ! 1629: { $$ = chainon ($$, $2); } ! 1630: ; ! 1631: ! 1632: nodecls: ! 1633: /* empty */ ! 1634: { ! 1635: if (! current_function_parms_stored) ! 1636: store_parm_decls (); ! 1637: setup_vtbl_ptr (); ! 1638: /* Always keep the BLOCK node associated with the outermost ! 1639: pair of curley braces of a function. These are needed ! 1640: for correct operation of dwarfout.c. */ ! 1641: keep_next_level (); ! 1642: } ! 1643: ; ! 1644: ! 1645: object: primary '.' ! 1646: | primary POINTSAT ! 1647: { ! 1648: $$ = build_x_arrow ($$); ! 1649: } ! 1650: ; ! 1651: ! 1652: decl: ! 1653: /* Normal case: make this fast. */ ! 1654: typespec declarator ';' ! 1655: { tree d = get_decl_list ($1); ! 1656: int yes = suspend_momentary (); ! 1657: d = start_decl ($2, d, 0, NULL_TREE); ! 1658: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 1659: resume_momentary (yes); ! 1660: if (IS_AGGR_TYPE_CODE (TREE_CODE ($1))) ! 1661: note_got_semicolon ($1); ! 1662: } ! 1663: | typed_declspecs declarator ';' ! 1664: { tree d = $1; ! 1665: int yes = suspend_momentary (); ! 1666: d = start_decl ($2, d, 0, NULL_TREE); ! 1667: finish_decl (d, NULL_TREE, NULL_TREE, 0); ! 1668: resume_momentary (yes); ! 1669: note_list_got_semicolon ($1); ! 1670: } ! 1671: | typespec initdecls ';' ! 1672: { ! 1673: resume_momentary ($2); ! 1674: if (IS_AGGR_TYPE_CODE (TREE_CODE ($1))) ! 1675: note_got_semicolon ($1); ! 1676: } ! 1677: | typed_declspecs initdecls ';' ! 1678: { ! 1679: resume_momentary ($2); ! 1680: note_list_got_semicolon ($1); ! 1681: } ! 1682: | declmods notype_initdecls ';' ! 1683: { resume_momentary ($2); } ! 1684: | typed_declspecs ';' ! 1685: { ! 1686: shadow_tag ($1); ! 1687: note_list_got_semicolon ($1); ! 1688: } ! 1689: | declmods ';' ! 1690: { warning ("empty declaration"); } ! 1691: ; ! 1692: ! 1693: /* Any kind of declarator (thus, all declarators allowed ! 1694: after an explicit typespec). */ ! 1695: ! 1696: declarator: ! 1697: after_type_declarator %prec EMPTY ! 1698: | notype_declarator %prec EMPTY ! 1699: ; ! 1700: ! 1701: /* This is necessary to postpone reduction of `int()()()()'. */ ! 1702: fcast_or_absdcl: ! 1703: LEFT_RIGHT %prec EMPTY ! 1704: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (), ! 1705: NULL_TREE); } ! 1706: | fcast_or_absdcl LEFT_RIGHT %prec EMPTY ! 1707: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), ! 1708: NULL_TREE); } ! 1709: ; ! 1710: ! 1711: /* ANSI type-id (8.1) */ ! 1712: type_id: ! 1713: typed_typespecs absdcl ! 1714: { $$ = build_decl_list ($$, $2); } ! 1715: | nonempty_type_quals absdcl ! 1716: { $$ = build_decl_list ($$, $2); } ! 1717: | typespec absdcl ! 1718: { $$ = build_decl_list (get_decl_list ($$), $2); } ! 1719: | typed_typespecs %prec EMPTY ! 1720: { $$ = build_decl_list ($$, NULL_TREE); } ! 1721: | nonempty_type_quals %prec EMPTY ! 1722: { $$ = build_decl_list ($$, NULL_TREE); } ! 1723: ; ! 1724: ! 1725: /* Declspecs which contain at least one type specifier or typedef name. ! 1726: (Just `const' or `volatile' is not enough.) ! 1727: A typedef'd name following these is taken as a name to be declared. */ ! 1728: ! 1729: typed_declspecs: ! 1730: typed_typespecs %prec EMPTY ! 1731: | typed_declspecs1 ! 1732: ! 1733: typed_declspecs1: ! 1734: declmods typespec ! 1735: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1736: | typespec reserved_declspecs %prec HYPERUNARY ! 1737: { $$ = decl_tree_cons (NULL_TREE, $$, $2); } ! 1738: | declmods typespec reserved_declspecs ! 1739: { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); } ! 1740: | declmods typespec reserved_typespecquals ! 1741: { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); } ! 1742: | declmods typespec reserved_typespecquals reserved_declspecs ! 1743: { $$ = decl_tree_cons (NULL_TREE, $2, ! 1744: chainon ($3, chainon ($4, $$))); } ! 1745: ; ! 1746: ! 1747: reserved_declspecs: ! 1748: SCSPEC ! 1749: { if (extra_warnings) ! 1750: warning ("`%s' is not at beginning of declaration", ! 1751: IDENTIFIER_POINTER ($$)); ! 1752: $$ = build_decl_list (NULL_TREE, $$); } ! 1753: | reserved_declspecs typespecqual_reserved ! 1754: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1755: | reserved_declspecs SCSPEC ! 1756: { if (extra_warnings) ! 1757: warning ("`%s' is not at beginning of declaration", ! 1758: IDENTIFIER_POINTER ($2)); ! 1759: $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1760: ; ! 1761: ! 1762: /* List of just storage classes and type modifiers. ! 1763: A declaration can start with just this, but then it cannot be used ! 1764: to redeclare a typedef-name. */ ! 1765: ! 1766: declmods: ! 1767: nonempty_type_quals %prec EMPTY ! 1768: { TREE_STATIC ($$) = 1; } ! 1769: | SCSPEC ! 1770: { $$ = IDENTIFIER_AS_LIST ($$); } ! 1771: | declmods TYPE_QUAL ! 1772: { $$ = decl_tree_cons (NULL_TREE, $2, $$); ! 1773: TREE_STATIC ($$) = 1; } ! 1774: | declmods SCSPEC ! 1775: { if (extra_warnings && TREE_STATIC ($$)) ! 1776: warning ("`%s' is not at beginning of declaration", ! 1777: IDENTIFIER_POINTER ($2)); ! 1778: $$ = decl_tree_cons (NULL_TREE, $2, $$); ! 1779: TREE_STATIC ($$) = TREE_STATIC ($1); } ! 1780: ; ! 1781: ! 1782: ! 1783: /* Used instead of declspecs where storage classes are not allowed ! 1784: (that is, for typenames and structure components). ! 1785: ! 1786: C++ can takes storage classes for structure components. ! 1787: Don't accept a typedef-name if anything but a modifier precedes it. */ ! 1788: ! 1789: typed_typespecs: ! 1790: typespec %prec EMPTY ! 1791: { $$ = get_decl_list ($$); } ! 1792: | nonempty_type_quals typespec ! 1793: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1794: | typespec reserved_typespecquals ! 1795: { $$ = decl_tree_cons (NULL_TREE, $$, $2); } ! 1796: | nonempty_type_quals typespec reserved_typespecquals ! 1797: { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); } ! 1798: ; ! 1799: ! 1800: reserved_typespecquals: ! 1801: typespecqual_reserved ! 1802: { $$ = build_decl_list (NULL_TREE, $$); } ! 1803: | reserved_typespecquals typespecqual_reserved ! 1804: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 1805: ; ! 1806: ! 1807: /* A typespec (but not a type qualifier). ! 1808: Once we have seen one of these in a declaration, ! 1809: if a typedef name appears then it is being redeclared. */ ! 1810: ! 1811: typespec: structsp ! 1812: | TYPESPEC %prec EMPTY ! 1813: | complete_type_name ! 1814: | TYPEOF '(' expr ')' ! 1815: { $$ = TREE_TYPE ($3); ! 1816: if (flag_ansi) ! 1817: pedwarn ("ANSI C++ forbids `typeof'"); } ! 1818: | TYPEOF '(' type_id ')' ! 1819: { $$ = groktypename ($3); ! 1820: if (flag_ansi) ! 1821: pedwarn ("ANSI C++ forbids `typeof'"); } ! 1822: | SIGOF '(' expr ')' ! 1823: { tree type = TREE_TYPE ($3); ! 1824: ! 1825: if (IS_AGGR_TYPE (type)) ! 1826: { ! 1827: sorry ("sigof type specifier"); ! 1828: $$ = type; ! 1829: } ! 1830: else ! 1831: { ! 1832: error ("`sigof' applied to non-aggregate expression"); ! 1833: $$ = error_mark_node; ! 1834: } ! 1835: } ! 1836: | SIGOF '(' type_id ')' ! 1837: { tree type = groktypename ($3); ! 1838: ! 1839: if (IS_AGGR_TYPE (type)) ! 1840: { ! 1841: sorry ("sigof type specifier"); ! 1842: $$ = type; ! 1843: } ! 1844: else ! 1845: { ! 1846: error("`sigof' applied to non-aggregate type"); ! 1847: $$ = error_mark_node; ! 1848: } ! 1849: } ! 1850: ; ! 1851: ! 1852: /* A typespec that is a reserved word, or a type qualifier. */ ! 1853: ! 1854: typespecqual_reserved: TYPESPEC ! 1855: | TYPE_QUAL ! 1856: | structsp ! 1857: ; ! 1858: ! 1859: initdecls: ! 1860: initdcl0 ! 1861: | initdecls ',' initdcl ! 1862: ; ! 1863: ! 1864: notype_initdecls: ! 1865: notype_initdcl0 ! 1866: | notype_initdecls ',' initdcl ! 1867: ; ! 1868: ! 1869: nomods_initdecls: ! 1870: nomods_initdcl0 ! 1871: | nomods_initdecls ',' initdcl ! 1872: ; ! 1873: ! 1874: maybeasm: ! 1875: /* empty */ ! 1876: { $$ = NULL_TREE; } ! 1877: | asm_keyword '(' string ')' ! 1878: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } ! 1879: ; ! 1880: ! 1881: initdcl0: ! 1882: declarator maybe_raises maybeasm maybe_attribute '=' ! 1883: { current_declspecs = $<ttype>0; ! 1884: if (TREE_CODE (current_declspecs) != TREE_LIST) ! 1885: current_declspecs = get_decl_list (current_declspecs); ! 1886: if (have_extern_spec && !used_extern_spec) ! 1887: { ! 1888: current_declspecs = decl_tree_cons ! 1889: (NULL_TREE, get_identifier ("extern"), ! 1890: current_declspecs); ! 1891: used_extern_spec = 1; ! 1892: } ! 1893: $<itype>5 = suspend_momentary (); ! 1894: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); ! 1895: cplus_decl_attributes ($<ttype>$, $4); } ! 1896: init ! 1897: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1898: { finish_decl ($<ttype>6, $7, $3, 0); ! 1899: $$ = $<itype>5; } ! 1900: | declarator maybe_raises maybeasm maybe_attribute ! 1901: { tree d; ! 1902: current_declspecs = $<ttype>0; ! 1903: if (TREE_CODE (current_declspecs) != TREE_LIST) ! 1904: current_declspecs = get_decl_list (current_declspecs); ! 1905: if (have_extern_spec && !used_extern_spec) ! 1906: { ! 1907: current_declspecs = decl_tree_cons ! 1908: (NULL_TREE, get_identifier ("extern"), ! 1909: current_declspecs); ! 1910: used_extern_spec = 1; ! 1911: } ! 1912: $$ = suspend_momentary (); ! 1913: d = start_decl ($<ttype>1, current_declspecs, 0, $2); ! 1914: cplus_decl_attributes (d, $4); ! 1915: finish_decl (d, NULL_TREE, $3, 0); } ! 1916: ; ! 1917: ! 1918: initdcl: ! 1919: declarator maybe_raises maybeasm maybe_attribute '=' ! 1920: { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); ! 1921: cplus_decl_attributes ($<ttype>$, $4); } ! 1922: init ! 1923: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1924: { finish_decl ($<ttype>6, $7, $3, 0); } ! 1925: | declarator maybe_raises maybeasm maybe_attribute ! 1926: { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2); ! 1927: cplus_decl_attributes ($<ttype>$, $4); ! 1928: finish_decl ($<ttype>$, NULL_TREE, $3, 0); } ! 1929: ; ! 1930: ! 1931: notype_initdcl0: ! 1932: notype_declarator maybe_raises maybeasm maybe_attribute '=' ! 1933: { current_declspecs = $<ttype>0; ! 1934: $<itype>5 = suspend_momentary (); ! 1935: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); ! 1936: cplus_decl_attributes ($<ttype>$, $4); } ! 1937: init ! 1938: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1939: { finish_decl ($<ttype>6, $7, $3, 0); ! 1940: $$ = $<itype>5; } ! 1941: | notype_declarator maybe_raises maybeasm maybe_attribute ! 1942: { tree d; ! 1943: current_declspecs = $<ttype>0; ! 1944: $$ = suspend_momentary (); ! 1945: d = start_decl ($<ttype>1, current_declspecs, 0, $2); ! 1946: cplus_decl_attributes (d, $4); ! 1947: finish_decl (d, NULL_TREE, $3, 0); } ! 1948: ; ! 1949: ! 1950: nomods_initdcl0: ! 1951: notype_declarator maybe_raises maybeasm maybe_attribute '=' ! 1952: { current_declspecs = NULL_TREE; ! 1953: $<itype>5 = suspend_momentary (); ! 1954: $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); ! 1955: cplus_decl_attributes ($<ttype>$, $4); } ! 1956: init ! 1957: /* Note how the declaration of the variable is in effect while its init is parsed! */ ! 1958: { finish_decl ($<ttype>6, $7, $3, 0); ! 1959: $$ = $<itype>5; } ! 1960: | notype_declarator maybe_raises maybeasm maybe_attribute ! 1961: { tree d; ! 1962: current_declspecs = NULL_TREE; ! 1963: $$ = suspend_momentary (); ! 1964: d = start_decl ($1, current_declspecs, 0, $2); ! 1965: cplus_decl_attributes (d, $4); ! 1966: finish_decl (d, NULL_TREE, $3, 0); } ! 1967: ; ! 1968: ! 1969: /* the * rules are dummies to accept the Apollo extended syntax ! 1970: so that the header files compile. */ ! 1971: maybe_attribute: ! 1972: /* empty */ ! 1973: { $$ = NULL_TREE; } ! 1974: | attributes ! 1975: { $$ = $1; } ! 1976: ; ! 1977: ! 1978: attributes: ! 1979: attribute ! 1980: { $$ = $1; } ! 1981: | attributes attribute ! 1982: { $$ = chainon ($1, $2); } ! 1983: ; ! 1984: ! 1985: attribute: ! 1986: ATTRIBUTE '(' '(' attribute_list ')' ')' ! 1987: { $$ = $4; } ! 1988: ; ! 1989: ! 1990: attribute_list: ! 1991: attrib ! 1992: { $$ = build_tree_list (NULL_TREE, $1); } ! 1993: | attribute_list ',' attrib ! 1994: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 1995: ; ! 1996: ! 1997: attrib: ! 1998: /* empty */ ! 1999: { $$ = NULL_TREE; } ! 2000: | any_word ! 2001: { $$ = $1; } ! 2002: | any_word '(' IDENTIFIER ')' ! 2003: { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); } ! 2004: | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' ! 2005: { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); } ! 2006: | any_word '(' nonnull_exprlist ')' ! 2007: { $$ = tree_cons ($1, NULL_TREE, $3); } ! 2008: ; ! 2009: ! 2010: /* This still leaves out most reserved keywords, ! 2011: shouldn't we include them? */ ! 2012: ! 2013: any_word: ! 2014: identifier ! 2015: | SCSPEC ! 2016: | TYPESPEC ! 2017: | TYPE_QUAL ! 2018: ; ! 2019: ! 2020: /* A nonempty list of identifiers, including typenames. */ ! 2021: identifiers_or_typenames: ! 2022: identifier ! 2023: { $$ = build_tree_list (NULL_TREE, $1); } ! 2024: | identifiers_or_typenames ',' identifier ! 2025: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ! 2026: ; ! 2027: ! 2028: init: ! 2029: expr_no_commas %prec '=' ! 2030: | '{' '}' ! 2031: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); ! 2032: TREE_HAS_CONSTRUCTOR ($$) = 1; } ! 2033: | '{' initlist '}' ! 2034: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); ! 2035: TREE_HAS_CONSTRUCTOR ($$) = 1; } ! 2036: | '{' initlist ',' '}' ! 2037: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); ! 2038: TREE_HAS_CONSTRUCTOR ($$) = 1; } ! 2039: | error ! 2040: { $$ = NULL_TREE; } ! 2041: ; ! 2042: ! 2043: /* This chain is built in reverse order, ! 2044: and put in forward order where initlist is used. */ ! 2045: initlist: ! 2046: init ! 2047: { $$ = build_tree_list (NULL_TREE, $$); } ! 2048: | initlist ',' init ! 2049: { $$ = tree_cons (NULL_TREE, $3, $$); } ! 2050: /* These are for labeled elements. */ ! 2051: | '[' expr_no_commas ']' init ! 2052: { $$ = build_tree_list ($2, $4); } ! 2053: | initlist ',' CASE expr_no_commas ':' init ! 2054: { $$ = tree_cons ($4, $6, $$); } ! 2055: | identifier ':' init ! 2056: { $$ = build_tree_list ($$, $3); } ! 2057: | initlist ',' identifier ':' init ! 2058: { $$ = tree_cons ($3, $5, $$); } ! 2059: ; ! 2060: ! 2061: structsp: ! 2062: ENUM identifier '{' ! 2063: { $<itype>3 = suspend_momentary (); ! 2064: $$ = start_enum ($2); } ! 2065: enumlist maybecomma_warn '}' ! 2066: { $$ = finish_enum ($<ttype>4, $5); ! 2067: resume_momentary ((int) $<itype>3); ! 2068: check_for_missing_semicolon ($<ttype>4); } ! 2069: | ENUM identifier '{' '}' ! 2070: { $$ = finish_enum (start_enum ($2), NULL_TREE); ! 2071: check_for_missing_semicolon ($$); } ! 2072: | ENUM '{' ! 2073: { $<itype>2 = suspend_momentary (); ! 2074: $$ = start_enum (make_anon_name ()); } ! 2075: enumlist maybecomma_warn '}' ! 2076: { $$ = finish_enum ($<ttype>3, $4); ! 2077: resume_momentary ((int) $<itype>1); ! 2078: check_for_missing_semicolon ($<ttype>3); } ! 2079: | ENUM '{' '}' ! 2080: { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE); ! 2081: check_for_missing_semicolon ($$); } ! 2082: | ENUM identifier ! 2083: { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); } ! 2084: | ENUM complex_type_name ! 2085: { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); } ! 2086: ! 2087: /* C++ extensions, merged with C to avoid shift/reduce conflicts */ ! 2088: | class_head left_curly opt.component_decl_list '}' ! 2089: { ! 2090: int semi; ! 2091: tree id; ! 2092: ! 2093: #if 0 ! 2094: /* Need to rework class nesting in the ! 2095: presence of nested classes, etc. */ ! 2096: shadow_tag (CLASSTYPE_AS_LIST ($$)); */ ! 2097: #endif ! 2098: if (yychar == YYEMPTY) ! 2099: yychar = YYLEX; ! 2100: semi = yychar == ';'; ! 2101: /* finish_struct nukes this anyway; if ! 2102: finish_exception does too, then it can go. */ ! 2103: if (semi) ! 2104: note_got_semicolon ($$); ! 2105: ! 2106: if (TREE_CODE ($$) == ENUMERAL_TYPE) ! 2107: /* $$ = $1 from default rule. */; ! 2108: else if (CLASSTYPE_DECLARED_EXCEPTION ($$)) ! 2109: { ! 2110: } ! 2111: else ! 2112: { ! 2113: $$ = finish_struct ($$, $3, semi); ! 2114: if (semi) note_got_semicolon ($$); ! 2115: } ! 2116: ! 2117: pop_obstacks (); ! 2118: ! 2119: id = TYPE_IDENTIFIER ($$); ! 2120: if (id && IDENTIFIER_TEMPLATE (id)) ! 2121: { ! 2122: tree decl; ! 2123: ! 2124: /* I don't know if the copying of this TYPE_DECL is ! 2125: * really needed. However, it's such a small per- ! 2126: * formance penalty that the extra safety is a bargain. ! 2127: * - [email protected] ! 2128: */ ! 2129: push_obstacks (&permanent_obstack, &permanent_obstack); ! 2130: decl = copy_node (lookup_name (id, 0)); ! 2131: if (DECL_LANG_SPECIFIC (decl)) ! 2132: copy_lang_decl (decl); ! 2133: pop_obstacks (); ! 2134: undo_template_name_overload (id, 0); ! 2135: pushdecl_top_level (decl); ! 2136: } ! 2137: if (! semi) ! 2138: check_for_missing_semicolon ($$); } ! 2139: | class_head %prec EMPTY ! 2140: { ! 2141: #if 0 ! 2142: /* It's no longer clear what the following error is supposed to ! 2143: accomplish. If it turns out to be needed, add a comment why. */ ! 2144: if (TYPE_BINFO_BASETYPES ($$) && !TYPE_SIZE ($$)) ! 2145: { ! 2146: error ("incomplete definition of type `%s'", ! 2147: TYPE_NAME_STRING ($$)); ! 2148: $$ = error_mark_node; ! 2149: } ! 2150: #endif ! 2151: } ! 2152: ; ! 2153: ! 2154: maybecomma: ! 2155: /* empty */ ! 2156: | ',' ! 2157: ; ! 2158: ! 2159: maybecomma_warn: ! 2160: /* empty */ ! 2161: | ',' ! 2162: { if (pedantic) pedwarn ("comma at end of enumerator list"); } ! 2163: ; ! 2164: ! 2165: aggr: AGGR ! 2166: | aggr SCSPEC ! 2167: { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } ! 2168: | aggr TYPESPEC ! 2169: { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } ! 2170: | aggr TYPE_QUAL ! 2171: { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } ! 2172: | aggr AGGR ! 2173: { error ("no body nor ';' separates two class, struct or union declarations"); } ! 2174: ; ! 2175: ! 2176: specialization: ! 2177: aggr template_type_name ';' ! 2178: { ! 2179: yyungetc (';', 1); current_aggr = $$; $$ = $2; ! 2180: if ($<ttype>0 == ridpointers[(int) RID_TEMPLATE]) ! 2181: instantiate_class_template ($$, 2); ! 2182: } ! 2183: ; ! 2184: ! 2185: named_class_head_sans_basetype: ! 2186: aggr identifier ! 2187: { current_aggr = $$; $$ = $2; } ! 2188: | aggr complex_type_name ! 2189: { current_aggr = $$; $$ = $2; } ! 2190: | aggr template_type %prec EMPTY ! 2191: { current_aggr = $$; $$ = $2; } ! 2192: | aggr template_type_name '{' ! 2193: { yyungetc ('{', 1); ! 2194: aggr2: ! 2195: current_aggr = $$; ! 2196: $$ = $2; ! 2197: overload_template_name ($$, 0); } ! 2198: | aggr template_type_name ':' ! 2199: { yyungetc (':', 1); goto aggr2; } ! 2200: | specialization ! 2201: ; ! 2202: ! 2203: named_class_head_sans_basetype_defn: ! 2204: aggr identifier_defn %prec EMPTY ! 2205: { current_aggr = $$; $$ = $2; } ! 2206: ; ! 2207: ! 2208: do_xref: /* empty */ %prec EMPTY ! 2209: { $<ttype>$ = xref_tag (current_aggr, $<ttype>0, NULL_TREE, 1); } ! 2210: ! 2211: do_xref_defn: /* empty */ %prec EMPTY ! 2212: { $<ttype>$ = xref_defn_tag (current_aggr, $<ttype>0, NULL_TREE); } ! 2213: ! 2214: named_class_head: ! 2215: named_class_head_sans_basetype do_xref ! 2216: maybe_base_class_list %prec EMPTY ! 2217: { ! 2218: if ($3) ! 2219: $$ = xref_tag (current_aggr, $1, $3, 1); ! 2220: else ! 2221: $$ = $<ttype>2; ! 2222: } ! 2223: | ! 2224: named_class_head_sans_basetype_defn do_xref_defn ! 2225: maybe_base_class_list %prec EMPTY ! 2226: { ! 2227: if ($3) ! 2228: $$ = xref_defn_tag (current_aggr, $1, $3); ! 2229: else ! 2230: $$ = $<ttype>2; ! 2231: } ! 2232: ; ! 2233: ! 2234: unnamed_class_head: aggr '{' ! 2235: { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0); ! 2236: yyungetc ('{', 1); } ! 2237: ; ! 2238: ! 2239: class_head: unnamed_class_head | named_class_head ; ! 2240: ! 2241: maybe_base_class_list: ! 2242: %prec EMPTY /* empty */ ! 2243: { $$ = NULL_TREE; } ! 2244: | ':' %prec EMPTY ! 2245: { yyungetc(':', 1); $$ = NULL_TREE; } ! 2246: | ':' base_class_list %prec EMPTY ! 2247: { $$ = $2; } ! 2248: ; ! 2249: ! 2250: base_class_list: ! 2251: base_class ! 2252: | base_class_list ',' base_class ! 2253: { $$ = chainon ($$, $3); } ! 2254: ; ! 2255: ! 2256: base_class: ! 2257: base_class.1 ! 2258: { ! 2259: tree type; ! 2260: do_base_class1: ! 2261: type = IDENTIFIER_TYPE_VALUE ($$); ! 2262: if (! is_aggr_typedef ($$, 1)) ! 2263: $$ = NULL_TREE; ! 2264: else if (current_aggr == signature_type_node ! 2265: && (! type) && (! IS_SIGNATURE (type))) ! 2266: { ! 2267: error ("class name not allowed as base signature"); ! 2268: $$ = NULL_TREE; ! 2269: } ! 2270: else if (current_aggr == signature_type_node) ! 2271: { ! 2272: sorry ("signature inheritance, base type `%s' ignored", ! 2273: IDENTIFIER_POINTER ($$)); ! 2274: $$ = build_tree_list ((tree)access_public, $$); ! 2275: } ! 2276: else if (type && IS_SIGNATURE (type)) ! 2277: { ! 2278: error ("signature name not allowed as base class"); ! 2279: $$ = NULL_TREE; ! 2280: } ! 2281: else ! 2282: $$ = build_tree_list ((tree)access_default, $$); ! 2283: } ! 2284: | base_class_access_list base_class.1 ! 2285: { ! 2286: tree type; ! 2287: do_base_class2: ! 2288: type = IDENTIFIER_TYPE_VALUE ($2); ! 2289: if (current_aggr == signature_type_node) ! 2290: error ("access and source specifiers not allowed in signature"); ! 2291: if (! is_aggr_typedef ($2, 1)) ! 2292: $$ = NULL_TREE; ! 2293: else if (current_aggr == signature_type_node ! 2294: && (! type) && (! IS_SIGNATURE (type))) ! 2295: { ! 2296: error ("class name not allowed as base signature"); ! 2297: $$ = NULL_TREE; ! 2298: } ! 2299: else if (current_aggr == signature_type_node) ! 2300: { ! 2301: sorry ("signature inheritance, base type `%s' ignored", ! 2302: IDENTIFIER_POINTER ($$)); ! 2303: $$ = build_tree_list ((tree)access_public, $2); ! 2304: } ! 2305: else if (type && IS_SIGNATURE (type)) ! 2306: { ! 2307: error ("signature name not allowed as base class"); ! 2308: $$ = NULL_TREE; ! 2309: } ! 2310: else ! 2311: $$ = build_tree_list ((tree) $$, $2); ! 2312: } ! 2313: ; ! 2314: ! 2315: base_class.1: ! 2316: complete_type_name ! 2317: | SIGOF '(' expr ')' ! 2318: { ! 2319: if (current_aggr == signature_type_node) ! 2320: { ! 2321: if (IS_AGGR_TYPE (TREE_TYPE ($3))) ! 2322: { ! 2323: sorry ("`sigof' as base signature specifier"); ! 2324: /* need to return some dummy signature identifier */ ! 2325: $$ = $3; ! 2326: } ! 2327: else ! 2328: { ! 2329: error ("`sigof' applied to non-aggregate expression"); ! 2330: $$ = error_mark_node; ! 2331: } ! 2332: } ! 2333: else ! 2334: { ! 2335: error ("`sigof' in struct or class declaration"); ! 2336: $$ = error_mark_node; ! 2337: } ! 2338: } ! 2339: | SIGOF '(' type_id ')' ! 2340: { ! 2341: if (current_aggr == signature_type_node) ! 2342: { ! 2343: if (IS_AGGR_TYPE (groktypename ($3))) ! 2344: { ! 2345: sorry ("`sigof' as base signature specifier"); ! 2346: /* need to return some dummy signature identifier */ ! 2347: $$ = $3; ! 2348: } ! 2349: else ! 2350: { ! 2351: error ("`sigof' applied to non-aggregate expression"); ! 2352: $$ = error_mark_node; ! 2353: } ! 2354: } ! 2355: else ! 2356: { ! 2357: error ("`sigof' in struct or class declaration"); ! 2358: $$ = error_mark_node; ! 2359: } ! 2360: } ! 2361: ; ! 2362: ! 2363: base_class_access_list: ! 2364: VISSPEC ! 2365: | SCSPEC ! 2366: { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL]) ! 2367: sorry ("non-virtual access"); ! 2368: $$ = access_default_virtual; } ! 2369: | base_class_access_list VISSPEC ! 2370: { int err = 0; ! 2371: if ($2 == access_protected) ! 2372: { ! 2373: warning ("`protected' access not implemented"); ! 2374: $2 = access_public; ! 2375: err++; ! 2376: } ! 2377: else if ($2 == access_public) ! 2378: { ! 2379: if ($1 == access_private) ! 2380: { ! 2381: mixed: ! 2382: error ("base class cannot be public and private"); ! 2383: } ! 2384: else if ($1 == access_default_virtual) ! 2385: $$ = access_public_virtual; ! 2386: } ! 2387: else /* $2 == access_private */ ! 2388: { ! 2389: if ($1 == access_public) ! 2390: goto mixed; ! 2391: else if ($1 == access_default_virtual) ! 2392: $$ = access_private_virtual; ! 2393: } ! 2394: } ! 2395: | base_class_access_list SCSPEC ! 2396: { if ($2 != ridpointers[(int)RID_VIRTUAL]) ! 2397: sorry ("non-virtual access"); ! 2398: if ($$ == access_public) ! 2399: $$ = access_public_virtual; ! 2400: else if ($$ == access_private) ! 2401: $$ = access_private_virtual; } ! 2402: ; ! 2403: ! 2404: left_curly: '{' ! 2405: { tree t = $<ttype>0; ! 2406: push_obstacks_nochange (); ! 2407: end_temporary_allocation (); ! 2408: ! 2409: if (! IS_AGGR_TYPE (t)) ! 2410: { ! 2411: t = $<ttype>0 = make_lang_type (RECORD_TYPE); ! 2412: TYPE_NAME (t) = get_identifier ("erroneous type"); ! 2413: } ! 2414: if (TYPE_SIZE (t)) ! 2415: duplicate_tag_error (t); ! 2416: if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t)) ! 2417: { ! 2418: t = make_lang_type (TREE_CODE (t)); ! 2419: pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0); ! 2420: $<ttype>0 = t; ! 2421: } ! 2422: pushclass (t, 0); ! 2423: TYPE_BEING_DEFINED (t) = 1; ! 2424: /* Reset the interface data, at the earliest possible ! 2425: moment, as it might have been set via a class foo; ! 2426: before. */ ! 2427: /* Don't change signatures. */ ! 2428: if (! IS_SIGNATURE (t)) ! 2429: { ! 2430: extern tree pending_vtables; ! 2431: int needs_writing; ! 2432: tree name = TYPE_IDENTIFIER (t); ! 2433: ! 2434: CLASSTYPE_INTERFACE_ONLY (t) = interface_only; ! 2435: SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); ! 2436: ! 2437: /* Record how to set the access of this class's ! 2438: virtual functions. If write_virtuals == 2 or 3, then ! 2439: inline virtuals are ``extern inline''. */ ! 2440: switch (write_virtuals) ! 2441: { ! 2442: case 0: ! 2443: case 1: ! 2444: needs_writing = 1; ! 2445: break; ! 2446: case 2: ! 2447: needs_writing = !! value_member (name, pending_vtables); ! 2448: break; ! 2449: case 3: ! 2450: needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t) ! 2451: && CLASSTYPE_INTERFACE_KNOWN (t); ! 2452: break; ! 2453: default: ! 2454: needs_writing = 0; ! 2455: } ! 2456: CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing; ! 2457: } ! 2458: #if 0 ! 2459: t = TYPE_IDENTIFIER ($<ttype>0); ! 2460: if (t && IDENTIFIER_TEMPLATE (t)) ! 2461: overload_template_name (t, 1); ! 2462: #endif ! 2463: } ! 2464: ; ! 2465: ! 2466: opt.component_decl_list: ! 2467: /* empty */ ! 2468: { $$ = NULL_TREE; } ! 2469: | component_decl_list ! 2470: { ! 2471: if (current_aggr == signature_type_node) ! 2472: $$ = build_tree_list ((tree) access_public, $$); ! 2473: else ! 2474: $$ = build_tree_list ((tree) access_default, $$); ! 2475: } ! 2476: | opt.component_decl_list VISSPEC ':' component_decl_list ! 2477: { ! 2478: tree visspec = (tree) $2; ! 2479: ! 2480: if (current_aggr == signature_type_node) ! 2481: { ! 2482: error ("access specifier not allowed in signature"); ! 2483: visspec = (tree) access_public; ! 2484: } ! 2485: $$ = chainon ($$, build_tree_list (visspec, $4)); ! 2486: } ! 2487: | opt.component_decl_list VISSPEC ':' ! 2488: { ! 2489: if (current_aggr == signature_type_node) ! 2490: error ("access specifier not allowed in signature"); ! 2491: } ! 2492: ; ! 2493: ! 2494: /* Note: we no longer warn about the semicolon after a component_decl_list. ! 2495: ARM $9.2 says that the semicolon is optional, and therefore allowed. */ ! 2496: component_decl_list: ! 2497: component_decl ! 2498: { if ($$ == void_type_node) $$ = NULL_TREE; ! 2499: } ! 2500: | component_decl_list component_decl ! 2501: { /* In pushdecl, we created a reverse list of names ! 2502: in this binding level. Make sure that the chain ! 2503: of what we're trying to add isn't the item itself ! 2504: (which can happen with what pushdecl's doing). */ ! 2505: if ($2 != NULL_TREE && $2 != void_type_node) ! 2506: { ! 2507: if (TREE_CHAIN ($2) != $$) ! 2508: $$ = chainon ($$, $2); ! 2509: else ! 2510: $$ = $2; ! 2511: } ! 2512: } ! 2513: | component_decl_list ';' ! 2514: ; ! 2515: ! 2516: component_decl: ! 2517: component_decl_1 ';' ! 2518: | component_decl_1 '}' ! 2519: { error ("missing ';' before right brace"); ! 2520: yyungetc ('}', 0); } ! 2521: /* C++: handle constructors, destructors and inline functions */ ! 2522: /* note that INLINE is like a TYPESPEC */ ! 2523: | fn.def2 ':' /* base_init compstmt */ ! 2524: { $$ = finish_method ($$); } ! 2525: | fn.def2 '{' /* nodecls compstmt */ ! 2526: { $$ = finish_method ($$); } ! 2527: ; ! 2528: ! 2529: component_decl_1: ! 2530: /* Do not add a "typed_declspecs declarator" rule here for ! 2531: speed; we need to call grok_x_components for enums, so the ! 2532: speedup would be insignificant. */ ! 2533: typed_declspecs components ! 2534: { ! 2535: $$ = grok_x_components ($$, $2); ! 2536: } ! 2537: | declmods notype_components ! 2538: { ! 2539: $$ = grok_x_components ($$, $2); ! 2540: } ! 2541: | notype_declarator maybe_raises maybeasm maybe_attribute ! 2542: { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3); ! 2543: cplus_decl_attributes ($$, $4); } ! 2544: | ':' expr_no_commas ! 2545: { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } ! 2546: | error ! 2547: { $$ = NULL_TREE; } ! 2548: ! 2549: /* These rules introduce a reduce/reduce conflict; in ! 2550: typedef int foo, bar; ! 2551: class A { ! 2552: foo (bar); ! 2553: }; ! 2554: should "A::foo" be declared as a function or "A::bar" as a data ! 2555: member? In other words, is "bar" an after_type_declarator or a ! 2556: parmlist? */ ! 2557: | typed_declspecs '(' parmlist ')' type_quals ! 2558: { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), ! 2559: $3, $5); ! 2560: $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, ! 2561: NULL_TREE); } ! 2562: | typed_declspecs LEFT_RIGHT type_quals ! 2563: { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), ! 2564: empty_parms (), $3); ! 2565: $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, ! 2566: NULL_TREE); } ! 2567: ; ! 2568: ! 2569: /* The case of exactly one component is handled directly by component_decl. */ ! 2570: components: ! 2571: /* empty: possibly anonymous */ ! 2572: { $$ = NULL_TREE; } ! 2573: | component_declarator0 ! 2574: | components ',' component_declarator ! 2575: { ! 2576: /* In this context, void_type_node encodes ! 2577: friends. They have been recorded elsewhere. */ ! 2578: if ($$ == void_type_node) ! 2579: $$ = $3; ! 2580: else ! 2581: $$ = chainon ($$, $3); ! 2582: } ! 2583: ; ! 2584: ! 2585: notype_components: ! 2586: /* empty: possibly anonymous */ ! 2587: { $$ = NULL_TREE; } ! 2588: | notype_component_declarator0 ! 2589: | notype_components ',' notype_component_declarator ! 2590: { ! 2591: /* In this context, void_type_node encodes ! 2592: friends. They have been recorded elsewhere. */ ! 2593: if ($$ == void_type_node) ! 2594: $$ = $3; ! 2595: else ! 2596: $$ = chainon ($$, $3); ! 2597: } ! 2598: ; ! 2599: ! 2600: component_declarator0: ! 2601: after_type_component_declarator0 ! 2602: | notype_component_declarator0 ! 2603: ; ! 2604: ! 2605: component_declarator: ! 2606: after_type_component_declarator ! 2607: | notype_component_declarator ! 2608: ; ! 2609: ! 2610: after_type_component_declarator0: ! 2611: after_type_declarator maybe_raises maybeasm maybe_attribute ! 2612: { current_declspecs = $<ttype>0; ! 2613: $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); ! 2614: cplus_decl_attributes ($$, $4); } ! 2615: | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init ! 2616: { current_declspecs = $<ttype>0; ! 2617: $$ = grokfield ($$, current_declspecs, $2, $6, $3); ! 2618: cplus_decl_attributes ($$, $4); } ! 2619: | TYPENAME ':' expr_no_commas maybe_attribute ! 2620: { current_declspecs = $<ttype>0; ! 2621: $$ = grokbitfield ($$, current_declspecs, $3); ! 2622: cplus_decl_attributes ($$, $4); } ! 2623: ; ! 2624: ! 2625: notype_component_declarator0: ! 2626: notype_declarator maybe_raises maybeasm maybe_attribute ! 2627: { current_declspecs = $<ttype>0; ! 2628: $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); ! 2629: cplus_decl_attributes ($$, $4); } ! 2630: | notype_declarator maybe_raises maybeasm maybe_attribute '=' init ! 2631: { current_declspecs = $<ttype>0; ! 2632: $$ = grokfield ($$, current_declspecs, $2, $6, $3); ! 2633: cplus_decl_attributes ($$, $4); } ! 2634: | IDENTIFIER ':' expr_no_commas maybe_attribute ! 2635: { current_declspecs = $<ttype>0; ! 2636: $$ = grokbitfield ($$, current_declspecs, $3); ! 2637: cplus_decl_attributes ($$, $4); } ! 2638: | ':' expr_no_commas maybe_attribute ! 2639: { current_declspecs = $<ttype>0; ! 2640: $$ = grokbitfield (NULL_TREE, current_declspecs, $2); ! 2641: cplus_decl_attributes ($$, $3); } ! 2642: ; ! 2643: ! 2644: after_type_component_declarator: ! 2645: after_type_declarator maybe_raises maybeasm maybe_attribute ! 2646: { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); ! 2647: cplus_decl_attributes ($$, $4); } ! 2648: | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init ! 2649: { $$ = grokfield ($$, current_declspecs, $2, $6, $3); ! 2650: cplus_decl_attributes ($$, $4); } ! 2651: | TYPENAME ':' expr_no_commas maybe_attribute ! 2652: { $$ = grokbitfield ($$, current_declspecs, $3); ! 2653: cplus_decl_attributes ($$, $4); } ! 2654: ; ! 2655: ! 2656: notype_component_declarator: ! 2657: notype_declarator maybe_raises maybeasm maybe_attribute ! 2658: { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); ! 2659: cplus_decl_attributes ($$, $4); } ! 2660: | notype_declarator maybe_raises maybeasm maybe_attribute '=' init ! 2661: { $$ = grokfield ($$, current_declspecs, $2, $6, $3); ! 2662: cplus_decl_attributes ($$, $4); } ! 2663: | IDENTIFIER ':' expr_no_commas maybe_attribute ! 2664: { $$ = grokbitfield ($$, current_declspecs, $3); ! 2665: cplus_decl_attributes ($$, $4); } ! 2666: | ':' expr_no_commas maybe_attribute ! 2667: { $$ = grokbitfield (NULL_TREE, current_declspecs, $2); ! 2668: cplus_decl_attributes ($$, $3); } ! 2669: ; ! 2670: ! 2671: /* We chain the enumerators in reverse order. ! 2672: Because of the way enums are built, the order is ! 2673: insignificant. Take advantage of this fact. */ ! 2674: ! 2675: enumlist: ! 2676: enumerator ! 2677: | enumlist ',' enumerator ! 2678: { TREE_CHAIN ($3) = $$; $$ = $3; } ! 2679: ; ! 2680: ! 2681: enumerator: ! 2682: identifier ! 2683: { $$ = build_enumerator ($$, NULL_TREE); } ! 2684: | identifier '=' expr_no_commas ! 2685: { $$ = build_enumerator ($$, $3); } ! 2686: ; ! 2687: ! 2688: /* ANSI new-type-id (5.3.4) */ ! 2689: new_type_id: ! 2690: type_specifier_seq new_declarator ! 2691: { $$ = build_decl_list ($$, $2); } ! 2692: | type_specifier_seq %prec EMPTY ! 2693: { $$ = build_decl_list ($$, NULL_TREE); } ! 2694: /* GNU extension to allow arrays of arbitrary types with ! 2695: non-constant dimension. */ ! 2696: | '(' type_id ')' '[' expr ']' ! 2697: { ! 2698: if (flag_ansi) ! 2699: pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new"); ! 2700: $$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5); ! 2701: $$ = build_decl_list (TREE_PURPOSE ($2), $$); ! 2702: } ! 2703: ; ! 2704: ! 2705: type_quals: ! 2706: /* empty */ %prec EMPTY ! 2707: { $$ = NULL_TREE; } ! 2708: | type_quals TYPE_QUAL ! 2709: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 2710: ; ! 2711: ! 2712: nonempty_type_quals: ! 2713: TYPE_QUAL ! 2714: { $$ = IDENTIFIER_AS_LIST ($$); } ! 2715: | nonempty_type_quals TYPE_QUAL ! 2716: { $$ = decl_tree_cons (NULL_TREE, $2, $$); } ! 2717: ; ! 2718: ! 2719: /* These rules must follow the rules for function declarations ! 2720: and component declarations. That way, longer rules are preferred. */ ! 2721: ! 2722: /* An expression which will not live on the momentary obstack. */ ! 2723: nonmomentary_expr: ! 2724: { $<itype>$ = suspend_momentary (); } expr ! 2725: { resume_momentary ((int) $<itype>1); $$ = $2; } ! 2726: ; ! 2727: ! 2728: /* A declarator that is allowed only after an explicit typespec. */ ! 2729: /* may all be followed by prec '.' */ ! 2730: after_type_declarator: ! 2731: '*' nonempty_type_quals after_type_declarator %prec UNARY ! 2732: { $$ = make_pointer_declarator ($2, $3); } ! 2733: | '&' nonempty_type_quals after_type_declarator %prec UNARY ! 2734: { $$ = make_reference_declarator ($2, $3); } ! 2735: | '*' after_type_declarator %prec UNARY ! 2736: { $$ = make_pointer_declarator (NULL_TREE, $2); } ! 2737: | '&' after_type_declarator %prec UNARY ! 2738: { $$ = make_reference_declarator (NULL_TREE, $2); } ! 2739: | ptr_to_mem type_quals after_type_declarator ! 2740: { tree arg = make_pointer_declarator ($2, $3); ! 2741: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2742: } ! 2743: | direct_after_type_declarator ! 2744: ; ! 2745: ! 2746: qualified_type_name: ! 2747: type_name %prec EMPTY ! 2748: { ! 2749: /* Remember that this name has been used in the class ! 2750: definition, as per [class.scope0] */ ! 2751: if (current_class_type ! 2752: && TYPE_BEING_DEFINED (current_class_type) ! 2753: && ! IDENTIFIER_CLASS_VALUE ($$)) ! 2754: { ! 2755: tree t = lookup_name ($$, -2); ! 2756: if (t) ! 2757: pushdecl_class_level (t); ! 2758: } ! 2759: } ! 2760: | nested_type ! 2761: ; ! 2762: ! 2763: nested_type: ! 2764: nested_name_specifier type_name %prec EMPTY ! 2765: { $$ = $2; } ! 2766: ; ! 2767: ! 2768: direct_after_type_declarator: ! 2769: direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.' ! 2770: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2771: | direct_after_type_declarator '(' parmlist ')' type_quals %prec '.' ! 2772: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2773: | direct_after_type_declarator LEFT_RIGHT type_quals %prec '.' ! 2774: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2775: | direct_after_type_declarator '(' error ')' type_quals %prec '.' ! 2776: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } ! 2777: | direct_after_type_declarator '[' nonmomentary_expr ']' ! 2778: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2779: | direct_after_type_declarator '[' ']' ! 2780: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2781: | '(' after_type_declarator ')' ! 2782: { $$ = $2; } ! 2783: | nested_name_specifier type_name %prec EMPTY ! 2784: { push_nested_class (TREE_TYPE ($$), 3); ! 2785: $$ = build_parse_node (SCOPE_REF, $$, $2); ! 2786: TREE_COMPLEXITY ($$) = current_class_depth; } ! 2787: | type_name %prec EMPTY ! 2788: ; ! 2789: ! 2790: /* A declarator allowed whether or not there has been ! 2791: an explicit typespec. These cannot redeclare a typedef-name. */ ! 2792: ! 2793: notype_declarator: ! 2794: '*' nonempty_type_quals notype_declarator %prec UNARY ! 2795: { $$ = make_pointer_declarator ($2, $3); } ! 2796: | '&' nonempty_type_quals notype_declarator %prec UNARY ! 2797: { $$ = make_reference_declarator ($2, $3); } ! 2798: | '*' notype_declarator %prec UNARY ! 2799: { $$ = make_pointer_declarator (NULL_TREE, $2); } ! 2800: | '&' notype_declarator %prec UNARY ! 2801: { $$ = make_reference_declarator (NULL_TREE, $2); } ! 2802: | ptr_to_mem type_quals notype_declarator ! 2803: { tree arg = make_pointer_declarator ($2, $3); ! 2804: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2805: } ! 2806: | direct_notype_declarator ! 2807: ; ! 2808: ! 2809: complex_notype_declarator: ! 2810: '*' nonempty_type_quals notype_declarator %prec UNARY ! 2811: { $$ = make_pointer_declarator ($2, $3); } ! 2812: | '&' nonempty_type_quals notype_declarator %prec UNARY ! 2813: { $$ = make_reference_declarator ($2, $3); } ! 2814: | '*' complex_notype_declarator %prec UNARY ! 2815: { $$ = make_pointer_declarator (NULL_TREE, $2); } ! 2816: | '&' complex_notype_declarator %prec UNARY ! 2817: { $$ = make_reference_declarator (NULL_TREE, $2); } ! 2818: | ptr_to_mem type_quals notype_declarator ! 2819: { tree arg = make_pointer_declarator ($2, $3); ! 2820: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2821: } ! 2822: | complex_direct_notype_declarator ! 2823: ; ! 2824: ! 2825: complex_direct_notype_declarator: ! 2826: direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.' ! 2827: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2828: | direct_notype_declarator '(' parmlist ')' type_quals %prec '.' ! 2829: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2830: | direct_notype_declarator LEFT_RIGHT type_quals %prec '.' ! 2831: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2832: | direct_notype_declarator '(' error ')' type_quals %prec '.' ! 2833: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } ! 2834: | '(' expr_or_declarator ')' ! 2835: { $$ = finish_decl_parsing ($2); } ! 2836: | '(' complex_notype_declarator ')' ! 2837: { $$ = $2; } ! 2838: | direct_notype_declarator '[' nonmomentary_expr ']' ! 2839: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2840: | direct_notype_declarator '[' ']' ! 2841: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2842: ; ! 2843: ! 2844: qualified_id: ! 2845: nested_name_specifier unqualified_id ! 2846: { got_scope = NULL_TREE; ! 2847: $$ = build_parse_node (SCOPE_REF, $$, $2); } ! 2848: ; ! 2849: ! 2850: notype_qualified_id: ! 2851: nested_name_specifier notype_unqualified_id ! 2852: { got_scope = NULL_TREE; ! 2853: $$ = build_parse_node (SCOPE_REF, $$, $2); } ! 2854: ; ! 2855: ! 2856: overqualified_id: ! 2857: notype_qualified_id ! 2858: | global_scope notype_qualified_id ! 2859: { $$ = $2; } ! 2860: ; ! 2861: ! 2862: functional_cast: ! 2863: typespec '(' nonnull_exprlist ')' ! 2864: { $$ = build_functional_cast ($$, $3); } ! 2865: | typespec '(' expr_or_declarator ')' ! 2866: { $$ = reparse_decl_as_expr ($$, $3); } ! 2867: | typespec fcast_or_absdcl %prec EMPTY ! 2868: { $$ = reparse_absdcl_as_expr ($$, $2); } ! 2869: ; ! 2870: ! 2871: type_name: ! 2872: TYPENAME ! 2873: | template_type %prec EMPTY ! 2874: ; ! 2875: ! 2876: nested_name_specifier: ! 2877: nested_name_specifier_1 ! 2878: | nested_name_specifier nested_name_specifier_1 ! 2879: { $$ = $2; } ! 2880: ; ! 2881: ! 2882: /* Why the @#$%^& do type_name and notype_identifier need to be expanded ! 2883: inline here?!? (jason) */ ! 2884: nested_name_specifier_1: ! 2885: TYPENAME SCOPE ! 2886: { got_scope = TREE_TYPE ($$); } ! 2887: | template_type SCOPE ! 2888: { got_scope = TREE_TYPE ($$); } ! 2889: /* These break 'const i;' ! 2890: | IDENTIFIER SCOPE ! 2891: { ! 2892: failed_scope: ! 2893: cp_error ("`%D' is not an aggregate typedef", ! 2894: lastiddecl ? lastiddecl : $$); ! 2895: $$ = error_mark_node; ! 2896: } ! 2897: | PTYPENAME SCOPE ! 2898: { goto failed_scope; } */ ! 2899: ; ! 2900: ! 2901: complete_type_name: ! 2902: qualified_type_name ! 2903: | global_scope qualified_type_name ! 2904: { $$ = $2; } ! 2905: ; ! 2906: ! 2907: complex_type_name: ! 2908: nested_type ! 2909: | global_scope qualified_type_name ! 2910: { $$ = $2; } ! 2911: ; ! 2912: ! 2913: ptr_to_mem: ! 2914: nested_name_specifier '*' ! 2915: { got_scope = NULL_TREE; } ! 2916: | global_scope nested_name_specifier '*' ! 2917: { $$ = $2; got_scope = NULL_TREE; } ! 2918: ; ! 2919: ! 2920: /* All uses of explicit global scope must go through this nonterminal so ! 2921: that got_scope will be set before yylex is called to get the next token. */ ! 2922: global_scope: ! 2923: SCOPE ! 2924: { got_scope = void_type_node; } ! 2925: ; ! 2926: ! 2927: /* ANSI new-declarator (5.3.4) */ ! 2928: new_declarator: ! 2929: '*' type_quals new_declarator ! 2930: { $$ = make_pointer_declarator ($2, $3); } ! 2931: | '*' type_quals %prec EMPTY ! 2932: { $$ = make_pointer_declarator ($2, NULL_TREE); } ! 2933: | '&' type_quals new_declarator %prec EMPTY ! 2934: { $$ = make_reference_declarator ($2, $3); } ! 2935: | '&' type_quals %prec EMPTY ! 2936: { $$ = make_reference_declarator ($2, NULL_TREE); } ! 2937: | ptr_to_mem type_quals %prec EMPTY ! 2938: { tree arg = make_pointer_declarator ($2, NULL_TREE); ! 2939: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2940: } ! 2941: | ptr_to_mem type_quals new_declarator ! 2942: { tree arg = make_pointer_declarator ($2, $3); ! 2943: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2944: } ! 2945: | direct_new_declarator %prec EMPTY ! 2946: ; ! 2947: ! 2948: /* ANSI direct-new-declarator (5.3.4) */ ! 2949: direct_new_declarator: ! 2950: '[' expr ']' ! 2951: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } ! 2952: | direct_new_declarator '[' nonmomentary_expr ']' ! 2953: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2954: ; ! 2955: ! 2956: /* ANSI abstract-declarator (8.1) */ ! 2957: absdcl: ! 2958: '*' nonempty_type_quals absdcl ! 2959: { $$ = make_pointer_declarator ($2, $3); } ! 2960: | '*' absdcl ! 2961: { $$ = make_pointer_declarator (NULL_TREE, $2); } ! 2962: | '*' nonempty_type_quals %prec EMPTY ! 2963: { $$ = make_pointer_declarator ($2, NULL_TREE); } ! 2964: | '*' %prec EMPTY ! 2965: { $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); } ! 2966: | '&' nonempty_type_quals absdcl ! 2967: { $$ = make_reference_declarator ($2, $3); } ! 2968: | '&' absdcl ! 2969: { $$ = make_reference_declarator (NULL_TREE, $2); } ! 2970: | '&' nonempty_type_quals %prec EMPTY ! 2971: { $$ = make_reference_declarator ($2, NULL_TREE); } ! 2972: | '&' %prec EMPTY ! 2973: { $$ = make_reference_declarator (NULL_TREE, NULL_TREE); } ! 2974: | ptr_to_mem type_quals %prec EMPTY ! 2975: { tree arg = make_pointer_declarator ($2, NULL_TREE); ! 2976: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2977: } ! 2978: | ptr_to_mem type_quals absdcl ! 2979: { tree arg = make_pointer_declarator ($2, $3); ! 2980: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 2981: } ! 2982: | direct_abstract_declarator %prec EMPTY ! 2983: ; ! 2984: ! 2985: /* ANSI direct-abstract-declarator (8.1) */ ! 2986: direct_abstract_declarator: ! 2987: '(' absdcl ')' ! 2988: { $$ = $2; } ! 2989: /* `(typedef)1' is `int'. */ ! 2990: | PAREN_STAR_PAREN ! 2991: | direct_abstract_declarator '(' parmlist ')' type_quals %prec '.' ! 2992: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } ! 2993: | direct_abstract_declarator LEFT_RIGHT type_quals %prec '.' ! 2994: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } ! 2995: | direct_abstract_declarator '[' nonmomentary_expr ']' %prec '.' ! 2996: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ! 2997: | direct_abstract_declarator '[' ']' %prec '.' ! 2998: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } ! 2999: | '(' complex_parmlist ')' type_quals %prec '.' ! 3000: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); } ! 3001: | regcast_or_absdcl type_quals %prec '.' ! 3002: { TREE_OPERAND ($$, 2) = $2; } ! 3003: | fcast_or_absdcl type_quals %prec '.' ! 3004: { TREE_OPERAND ($$, 2) = $2; } ! 3005: | '[' nonmomentary_expr ']' %prec '.' ! 3006: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } ! 3007: | '[' ']' %prec '.' ! 3008: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); } ! 3009: ; ! 3010: ! 3011: /* For C++, decls and stmts can be intermixed, so we don't need to ! 3012: have a special rule that won't start parsing the stmt section ! 3013: until we have a stmt that parses without errors. */ ! 3014: ! 3015: stmts: ! 3016: stmt ! 3017: | errstmt ! 3018: | stmts stmt ! 3019: | stmts errstmt ! 3020: ; ! 3021: ! 3022: errstmt: error ';' ! 3023: ; ! 3024: ! 3025: /* build the LET_STMT node before parsing its contents, ! 3026: so that any LET_STMTs within the context can have their display pointers ! 3027: set up to point at this one. */ ! 3028: ! 3029: .pushlevel: /* empty */ ! 3030: { emit_line_note (input_filename, lineno); ! 3031: pushlevel (0); ! 3032: clear_last_expr (); ! 3033: push_momentary (); ! 3034: expand_start_bindings (0); } ! 3035: ; ! 3036: ! 3037: /* Read zero or more forward-declarations for labels ! 3038: that nested functions can jump to. */ ! 3039: maybe_label_decls: ! 3040: /* empty */ ! 3041: | label_decls ! 3042: { if (flag_ansi) ! 3043: pedwarn ("ANSI C++ forbids label declarations"); } ! 3044: ; ! 3045: ! 3046: label_decls: ! 3047: label_decl ! 3048: | label_decls label_decl ! 3049: ; ! 3050: ! 3051: label_decl: ! 3052: LABEL identifiers_or_typenames ';' ! 3053: { tree link; ! 3054: for (link = $2; link; link = TREE_CHAIN (link)) ! 3055: { ! 3056: tree label = shadow_label (TREE_VALUE (link)); ! 3057: C_DECLARED_LABEL_FLAG (label) = 1; ! 3058: declare_nonlocal_label (label); ! 3059: } ! 3060: } ! 3061: ; ! 3062: ! 3063: /* This is the body of a function definition. ! 3064: It causes syntax errors to ignore to the next openbrace. */ ! 3065: compstmt_or_error: ! 3066: compstmt ! 3067: {} ! 3068: | error compstmt ! 3069: ; ! 3070: ! 3071: compstmt: '{' .pushlevel '}' ! 3072: { expand_end_bindings (getdecls (), kept_level_p(), 1); ! 3073: $$ = poplevel (kept_level_p (), 1, 0); ! 3074: pop_momentary (); } ! 3075: | '{' .pushlevel maybe_label_decls stmts '}' ! 3076: { expand_end_bindings (getdecls (), kept_level_p(), 1); ! 3077: $$ = poplevel (kept_level_p (), 1, 0); ! 3078: pop_momentary (); } ! 3079: | '{' .pushlevel maybe_label_decls stmts error '}' ! 3080: { expand_end_bindings (getdecls (), kept_level_p(), 1); ! 3081: $$ = poplevel (kept_level_p (), 0, 0); ! 3082: pop_momentary (); } ! 3083: | '{' .pushlevel maybe_label_decls error '}' ! 3084: { expand_end_bindings (getdecls (), kept_level_p(), 1); ! 3085: $$ = poplevel (kept_level_p (), 0, 0); ! 3086: pop_momentary (); } ! 3087: ; ! 3088: ! 3089: simple_if: ! 3090: IF ! 3091: { cond_stmt_keyword = "if"; } ! 3092: .pushlevel paren_cond_or_null ! 3093: { emit_line_note (input_filename, lineno); ! 3094: expand_start_cond ($4, 0); } ! 3095: implicitly_scoped_stmt ! 3096: ; ! 3097: ! 3098: implicitly_scoped_stmt: ! 3099: compstmt ! 3100: { finish_stmt (); } ! 3101: | .pushlevel simple_stmt ! 3102: { expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3103: $$ = poplevel (kept_level_p (), 1, 0); ! 3104: pop_momentary (); } ! 3105: ; ! 3106: ! 3107: stmt: ! 3108: compstmt ! 3109: { finish_stmt (); } ! 3110: | simple_stmt ! 3111: ; ! 3112: ! 3113: simple_stmt: ! 3114: decl ! 3115: { finish_stmt (); } ! 3116: | expr ';' ! 3117: { ! 3118: tree expr = $1; ! 3119: emit_line_note (input_filename, lineno); ! 3120: /* Do default conversion if safe and possibly important, ! 3121: in case within ({...}). */ ! 3122: if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE ! 3123: && lvalue_p (expr)) ! 3124: || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) ! 3125: expr = default_conversion (expr); ! 3126: cplus_expand_expr_stmt (expr); ! 3127: clear_momentary (); ! 3128: finish_stmt (); } ! 3129: | simple_if ELSE ! 3130: { expand_start_else (); } ! 3131: implicitly_scoped_stmt ! 3132: { expand_end_cond (); ! 3133: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3134: poplevel (kept_level_p (), 1, 0); ! 3135: pop_momentary (); ! 3136: finish_stmt (); } ! 3137: | simple_if %prec IF ! 3138: { expand_end_cond (); ! 3139: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3140: poplevel (kept_level_p (), 1, 0); ! 3141: pop_momentary (); ! 3142: finish_stmt (); } ! 3143: | WHILE ! 3144: { emit_nop (); ! 3145: emit_line_note (input_filename, lineno); ! 3146: expand_start_loop (1); ! 3147: cond_stmt_keyword = "while"; } ! 3148: .pushlevel paren_cond_or_null ! 3149: { expand_exit_loop_if_false (0, $4); } ! 3150: already_scoped_stmt ! 3151: { expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3152: poplevel (kept_level_p (), 1, 0); ! 3153: pop_momentary (); ! 3154: expand_end_loop (); ! 3155: finish_stmt (); } ! 3156: | DO ! 3157: { emit_nop (); ! 3158: emit_line_note (input_filename, lineno); ! 3159: expand_start_loop_continue_elsewhere (1); } ! 3160: implicitly_scoped_stmt WHILE ! 3161: { expand_loop_continue_here (); ! 3162: cond_stmt_keyword = "do"; } ! 3163: paren_expr_or_null ';' ! 3164: { emit_line_note (input_filename, lineno); ! 3165: expand_exit_loop_if_false (0, $6); ! 3166: expand_end_loop (); ! 3167: clear_momentary (); ! 3168: finish_stmt (); } ! 3169: | forhead.1 ! 3170: { emit_nop (); ! 3171: emit_line_note (input_filename, lineno); ! 3172: if ($1) cplus_expand_expr_stmt ($1); ! 3173: expand_start_loop_continue_elsewhere (1); } ! 3174: .pushlevel xcond ';' ! 3175: { emit_line_note (input_filename, lineno); ! 3176: if ($4) expand_exit_loop_if_false (0, $4); } ! 3177: xexpr ')' ! 3178: /* Don't let the tree nodes for $7 be discarded ! 3179: by clear_momentary during the parsing of the next stmt. */ ! 3180: { push_momentary (); } ! 3181: already_scoped_stmt ! 3182: { emit_line_note (input_filename, lineno); ! 3183: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3184: poplevel (kept_level_p (), 1, 0); ! 3185: pop_momentary (); ! 3186: expand_loop_continue_here (); ! 3187: if ($7) cplus_expand_expr_stmt ($7); ! 3188: pop_momentary (); ! 3189: expand_end_loop (); ! 3190: finish_stmt (); } ! 3191: | forhead.2 ! 3192: { emit_nop (); ! 3193: emit_line_note (input_filename, lineno); ! 3194: expand_start_loop_continue_elsewhere (1); } ! 3195: .pushlevel xcond ';' ! 3196: { emit_line_note (input_filename, lineno); ! 3197: if ($4) expand_exit_loop_if_false (0, $4); } ! 3198: xexpr ')' ! 3199: /* Don't let the tree nodes for $7 be discarded ! 3200: by clear_momentary during the parsing of the next stmt. */ ! 3201: { push_momentary (); ! 3202: $<itype>8 = lineno; } ! 3203: already_scoped_stmt ! 3204: { emit_line_note (input_filename, (int) $<itype>8); ! 3205: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3206: poplevel (kept_level_p (), 1, 0); ! 3207: pop_momentary (); ! 3208: expand_loop_continue_here (); ! 3209: if ($7) cplus_expand_expr_stmt ($7); ! 3210: pop_momentary (); ! 3211: expand_end_loop (); ! 3212: finish_stmt (); ! 3213: } ! 3214: | SWITCH .pushlevel '(' condition ')' ! 3215: { emit_line_note (input_filename, lineno); ! 3216: c_expand_start_case ($4); ! 3217: /* Don't let the tree nodes for $4 be discarded by ! 3218: clear_momentary during the parsing of the next stmt. */ ! 3219: push_momentary (); } ! 3220: implicitly_scoped_stmt ! 3221: { expand_end_case ($4); ! 3222: pop_momentary (); ! 3223: expand_end_bindings (getdecls (), kept_level_p (), 1); ! 3224: poplevel (kept_level_p (), 1, 0); ! 3225: pop_momentary (); ! 3226: finish_stmt (); } ! 3227: | CASE expr_no_commas ':' ! 3228: { register tree value = check_cp_case_value ($2); ! 3229: register tree label ! 3230: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 3231: ! 3232: if (value != error_mark_node) ! 3233: { ! 3234: tree duplicate; ! 3235: int success = pushcase (value, convert_and_check, ! 3236: label, &duplicate); ! 3237: if (success == 1) ! 3238: cp_error ("case label `%E' not within a switch statement", $2); ! 3239: else if (success == 2) ! 3240: { ! 3241: cp_error ("duplicate case value `%E'", $2); ! 3242: cp_error_at ("`%E' previously used here", duplicate); ! 3243: } ! 3244: else if (success == 3) ! 3245: warning ("case value out of range"); ! 3246: else if (success == 5) ! 3247: cp_error ("case label `%E' within scope of cleanup or variable array", $2); ! 3248: } ! 3249: define_case_label (label); ! 3250: } ! 3251: stmt ! 3252: | CASE expr_no_commas ELLIPSIS expr_no_commas ':' ! 3253: { register tree value1 = check_cp_case_value ($2); ! 3254: register tree value2 = check_cp_case_value ($4); ! 3255: register tree label ! 3256: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 3257: ! 3258: if (flag_ansi) ! 3259: pedwarn ("ANSI C++ forbids range expressions in switch statement"); ! 3260: if (value1 != error_mark_node ! 3261: && value2 != error_mark_node) ! 3262: { ! 3263: tree duplicate; ! 3264: int success = pushcase_range (value1, value2, ! 3265: convert_and_check, label, ! 3266: &duplicate); ! 3267: if (success == 1) ! 3268: error ("case label not within a switch statement"); ! 3269: else if (success == 2) ! 3270: { ! 3271: error ("duplicate (or overlapping) case value"); ! 3272: error_with_decl (duplicate, "this is the first entry overlapping that value"); ! 3273: } ! 3274: else if (success == 3) ! 3275: warning ("case value out of range"); ! 3276: else if (success == 4) ! 3277: warning ("empty range specified"); ! 3278: else if (success == 5) ! 3279: error ("case label within scope of cleanup or variable array"); ! 3280: } ! 3281: define_case_label (label); ! 3282: } ! 3283: stmt ! 3284: | DEFAULT ':' ! 3285: { ! 3286: tree duplicate; ! 3287: register tree label ! 3288: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); ! 3289: int success = pushcase (NULL_TREE, 0, label, &duplicate); ! 3290: if (success == 1) ! 3291: error ("default label not within a switch statement"); ! 3292: else if (success == 2) ! 3293: { ! 3294: error ("multiple default labels in one switch"); ! 3295: error_with_decl (duplicate, "this is the first default label"); ! 3296: } ! 3297: define_case_label (NULL_TREE); ! 3298: } ! 3299: stmt ! 3300: | BREAK ';' ! 3301: { emit_line_note (input_filename, lineno); ! 3302: if ( ! expand_exit_something ()) ! 3303: error ("break statement not within loop or switch"); } ! 3304: | CONTINUE ';' ! 3305: { emit_line_note (input_filename, lineno); ! 3306: if (! expand_continue_loop (0)) ! 3307: error ("continue statement not within a loop"); } ! 3308: | RETURN ';' ! 3309: { emit_line_note (input_filename, lineno); ! 3310: c_expand_return (NULL_TREE); } ! 3311: | RETURN expr ';' ! 3312: { emit_line_note (input_filename, lineno); ! 3313: c_expand_return ($2); ! 3314: finish_stmt (); ! 3315: } ! 3316: | asm_keyword maybe_type_qual '(' string ')' ';' ! 3317: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3318: emit_line_note (input_filename, lineno); ! 3319: expand_asm ($4); ! 3320: finish_stmt (); ! 3321: } ! 3322: /* This is the case with just output operands. */ ! 3323: | asm_keyword maybe_type_qual '(' string ':' asm_operands ')' ';' ! 3324: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3325: emit_line_note (input_filename, lineno); ! 3326: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE, ! 3327: $2 == ridpointers[(int)RID_VOLATILE], ! 3328: input_filename, lineno); ! 3329: finish_stmt (); ! 3330: } ! 3331: /* This is the case with input operands as well. */ ! 3332: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';' ! 3333: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3334: emit_line_note (input_filename, lineno); ! 3335: c_expand_asm_operands ($4, $6, $8, NULL_TREE, ! 3336: $2 == ridpointers[(int)RID_VOLATILE], ! 3337: input_filename, lineno); ! 3338: finish_stmt (); ! 3339: } ! 3340: /* This is the case with clobbered registers as well. */ ! 3341: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':' ! 3342: asm_operands ':' asm_clobbers ')' ';' ! 3343: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4); ! 3344: emit_line_note (input_filename, lineno); ! 3345: c_expand_asm_operands ($4, $6, $8, $10, ! 3346: $2 == ridpointers[(int)RID_VOLATILE], ! 3347: input_filename, lineno); ! 3348: finish_stmt (); ! 3349: } ! 3350: | GOTO '*' expr ';' ! 3351: { emit_line_note (input_filename, lineno); ! 3352: expand_computed_goto ($3); } ! 3353: | GOTO identifier ';' ! 3354: { tree decl; ! 3355: emit_line_note (input_filename, lineno); ! 3356: decl = lookup_label ($2); ! 3357: TREE_USED (decl) = 1; ! 3358: expand_goto (decl); } ! 3359: | label_colon stmt ! 3360: { finish_stmt (); } ! 3361: | label_colon '}' ! 3362: { error ("label must be followed by statement"); ! 3363: yyungetc ('}', 0); ! 3364: finish_stmt (); } ! 3365: | ';' ! 3366: { finish_stmt (); } ! 3367: | try_block ! 3368: ; ! 3369: ! 3370: try_block: ! 3371: TRY '{' .pushlevel ! 3372: { expand_start_try_stmts (); } ! 3373: ansi_try_stmts ! 3374: { expand_end_try_stmts (); ! 3375: expand_start_all_catch (); } ! 3376: handler_seq ! 3377: { expand_end_all_catch (); } ! 3378: ; ! 3379: ! 3380: ansi_try_stmts: ! 3381: '}' ! 3382: /* An empty try block is degenerate, but it's better to ! 3383: do extra work here than to do all the special-case work ! 3384: everywhere else. */ ! 3385: { expand_end_bindings (0,1,1); ! 3386: poplevel (2,0,0); ! 3387: } ! 3388: | stmts '}' ! 3389: { expand_end_bindings (0,1,1); ! 3390: poplevel (2,0,0); ! 3391: } ! 3392: | error '}' ! 3393: { expand_end_bindings (0,1,1); ! 3394: poplevel (2,0,0); ! 3395: } ! 3396: ; ! 3397: ! 3398: handler_seq: ! 3399: /* empty */ ! 3400: | handler_seq CATCH ! 3401: { emit_line_note (input_filename, lineno); } ! 3402: handler_args compstmt ! 3403: { expand_end_catch_block (); } ! 3404: ; ! 3405: ! 3406: type_specifier_seq: ! 3407: typed_typespecs %prec EMPTY ! 3408: | nonempty_type_quals %prec EMPTY ! 3409: ; ! 3410: ! 3411: handler_args: ! 3412: '(' ELLIPSIS ')' ! 3413: { expand_start_catch_block (NULL_TREE, NULL_TREE); } ! 3414: /* This doesn't allow reference parameters, the below does. ! 3415: | '(' type_specifier_seq absdcl ')' ! 3416: { expand_start_catch_block ($2, $3); } ! 3417: | '(' type_specifier_seq ')' ! 3418: { expand_start_catch_block ($2, NULL_TREE); } ! 3419: | '(' type_specifier_seq notype_declarator ')' ! 3420: { expand_start_catch_block ($2, $3); } ! 3421: | '(' typed_typespecs after_type_declarator ')' ! 3422: { expand_start_catch_block ($2, $3); } ! 3423: */ ! 3424: | '(' parm ')' ! 3425: { expand_start_catch_block (TREE_PURPOSE ($2), ! 3426: TREE_VALUE ($2)); } ! 3427: ; ! 3428: ! 3429: label_colon: ! 3430: IDENTIFIER ':' ! 3431: { tree label; ! 3432: do_label: ! 3433: label = define_label (input_filename, lineno, $1); ! 3434: if (label) ! 3435: expand_label (label); ! 3436: } ! 3437: | PTYPENAME ':' ! 3438: { goto do_label; } ! 3439: | TYPENAME ':' ! 3440: { goto do_label; } ! 3441: ; ! 3442: ! 3443: forhead.1: ! 3444: FOR '(' ';' ! 3445: { $$ = NULL_TREE; } ! 3446: | FOR '(' expr ';' ! 3447: { $$ = $3; } ! 3448: | FOR '(' '{' '}' ! 3449: { $$ = NULL_TREE; } ! 3450: ; ! 3451: ! 3452: forhead.2: ! 3453: FOR '(' decl ! 3454: { $$ = 0; } ! 3455: | FOR '(' error ';' ! 3456: { $$ = 0; } ! 3457: | FOR '(' '{' .pushlevel stmts '}' ! 3458: { $$ = 1; } ! 3459: | FOR '(' '{' .pushlevel error '}' ! 3460: { $$ = -1; } ! 3461: ; ! 3462: ! 3463: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ ! 3464: ! 3465: maybe_type_qual: ! 3466: /* empty */ ! 3467: { emit_line_note (input_filename, lineno); ! 3468: $$ = NULL_TREE; } ! 3469: | TYPE_QUAL ! 3470: { emit_line_note (input_filename, lineno); } ! 3471: ; ! 3472: ! 3473: xexpr: ! 3474: /* empty */ ! 3475: { $$ = NULL_TREE; } ! 3476: | expr ! 3477: | error ! 3478: { $$ = NULL_TREE; } ! 3479: ; ! 3480: ! 3481: /* These are the operands other than the first string and colon ! 3482: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ ! 3483: asm_operands: /* empty */ ! 3484: { $$ = NULL_TREE; } ! 3485: | nonnull_asm_operands ! 3486: ; ! 3487: ! 3488: nonnull_asm_operands: ! 3489: asm_operand ! 3490: | nonnull_asm_operands ',' asm_operand ! 3491: { $$ = chainon ($$, $3); } ! 3492: ; ! 3493: ! 3494: asm_operand: ! 3495: STRING '(' expr ')' ! 3496: { $$ = build_tree_list ($$, $3); } ! 3497: ; ! 3498: ! 3499: asm_clobbers: ! 3500: STRING ! 3501: { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); } ! 3502: | asm_clobbers ',' STRING ! 3503: { $$ = tree_cons (NULL_TREE, $3, $$); } ! 3504: ; ! 3505: ! 3506: /* This is what appears inside the parens in a function declarator. ! 3507: Its value is represented in the format that grokdeclarator expects. ! 3508: ! 3509: In C++, declaring a function with no parameters ! 3510: means that that function takes *no* parameters. */ ! 3511: ! 3512: parmlist: /* empty */ ! 3513: { ! 3514: if (strict_prototype) ! 3515: $$ = void_list_node; ! 3516: else ! 3517: $$ = NULL_TREE; ! 3518: } ! 3519: | complex_parmlist ! 3520: | type_id ! 3521: { $$ = tree_cons (NULL_TREE, $$, void_list_node); ! 3522: TREE_PARMLIST ($$) = 1; } ! 3523: ; ! 3524: ! 3525: /* This nonterminal does not include the common sequence '(' type_id ')', ! 3526: as it is ambiguous and must be disambiguated elsewhere. */ ! 3527: complex_parmlist: ! 3528: parms ! 3529: { ! 3530: $$ = chainon ($$, void_list_node); ! 3531: TREE_PARMLIST ($$) = 1; ! 3532: } ! 3533: | parms_comma ELLIPSIS ! 3534: { ! 3535: TREE_PARMLIST ($$) = 1; ! 3536: } ! 3537: /* C++ allows an ellipsis without a separating ',' */ ! 3538: | parms ELLIPSIS ! 3539: { ! 3540: TREE_PARMLIST ($$) = 1; ! 3541: } ! 3542: | type_id ELLIPSIS ! 3543: { ! 3544: $$ = build_tree_list (NULL_TREE, $$); ! 3545: TREE_PARMLIST ($$) = 1; ! 3546: } ! 3547: | ELLIPSIS ! 3548: { ! 3549: /* ARM $8.2.5 has this as a boxed-off comment. */ ! 3550: if (pedantic) ! 3551: warning ("use of `...' without a first argument is non-portable"); ! 3552: $$ = NULL_TREE; ! 3553: } ! 3554: | TYPENAME_ELLIPSIS ! 3555: { ! 3556: TREE_PARMLIST ($$) = 1; ! 3557: } ! 3558: | parms TYPENAME_ELLIPSIS ! 3559: { ! 3560: TREE_PARMLIST ($$) = 1; ! 3561: } ! 3562: | type_id TYPENAME_ELLIPSIS ! 3563: { ! 3564: $$ = build_tree_list (NULL_TREE, $$); ! 3565: TREE_PARMLIST ($$) = 1; ! 3566: } ! 3567: | parms ':' ! 3568: { ! 3569: /* This helps us recover from really nasty ! 3570: parse errors, for example, a missing right ! 3571: parenthesis. */ ! 3572: yyerror ("possibly missing ')'"); ! 3573: $$ = chainon ($$, void_list_node); ! 3574: TREE_PARMLIST ($$) = 1; ! 3575: yyungetc (':', 0); ! 3576: yychar = ')'; ! 3577: } ! 3578: | type_id ':' ! 3579: { ! 3580: /* This helps us recover from really nasty ! 3581: parse errors, for example, a missing right ! 3582: parenthesis. */ ! 3583: yyerror ("possibly missing ')'"); ! 3584: $$ = tree_cons (NULL_TREE, $$, void_list_node); ! 3585: TREE_PARMLIST ($$) = 1; ! 3586: yyungetc (':', 0); ! 3587: yychar = ')'; ! 3588: } ! 3589: ; ! 3590: ! 3591: /* A nonempty list of parameter declarations or type names. */ ! 3592: parms: ! 3593: named_parm ! 3594: { $$ = build_tree_list (NULL_TREE, $$); } ! 3595: | parm '=' init ! 3596: { $$ = build_tree_list ($3, $$); } ! 3597: | parms_comma full_parm ! 3598: { $$ = chainon ($$, $2); } ! 3599: | parms_comma bad_parm ! 3600: { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); } ! 3601: | parms_comma bad_parm '=' init ! 3602: { $$ = chainon ($$, build_tree_list ($4, $2)); } ! 3603: ; ! 3604: ! 3605: parms_comma: ! 3606: parms ',' ! 3607: | type_id ',' ! 3608: { $$ = build_tree_list (NULL_TREE, $$); } ! 3609: ; ! 3610: ! 3611: /* A single parameter declaration or parameter type name, ! 3612: as found in a parmlist. The first four cases make up for 10% ! 3613: of the time spent parsing C++. We cannot use them because ! 3614: of `int id[]' which won't get parsed properly. */ ! 3615: named_parm: ! 3616: /* ! 3617: typed_declspecs dont_see_typename '*' IDENTIFIER ! 3618: { $$ = build_tree_list ($$, build_parse_node (INDIRECT_REF, $4)); ! 3619: see_typename (); } ! 3620: | typed_declspecs dont_see_typename '&' IDENTIFIER ! 3621: { $$ = build_tree_list ($$, build_parse_node (ADDR_EXPR, $4)); ! 3622: see_typename (); } ! 3623: | TYPENAME IDENTIFIER ! 3624: { $$ = build_tree_list (get_decl_list ($$), $2); } ! 3625: | TYPESPEC IDENTIFIER ! 3626: { $$ = build_tree_list (get_decl_list ($$), $2); } ! 3627: | */ ! 3628: /* Here we expand typed_declspecs inline to avoid mis-parsing of ! 3629: TYPESPEC IDENTIFIER. */ ! 3630: typed_declspecs1 declarator ! 3631: { $$ = build_tree_list ($$, $2); } ! 3632: | typed_typespecs declarator ! 3633: { $$ = build_tree_list ($$, $2); } ! 3634: | typespec declarator ! 3635: { $$ = build_tree_list (get_decl_list ($$), $2); } ! 3636: | typed_declspecs1 absdcl ! 3637: { $$ = build_tree_list ($$, $2); } ! 3638: | typed_declspecs1 %prec EMPTY ! 3639: { $$ = build_tree_list ($$, NULL_TREE); } ! 3640: | declmods notype_declarator ! 3641: { $$ = build_tree_list ($$, $2); } ! 3642: ; ! 3643: ! 3644: full_parm: ! 3645: parm ! 3646: { $$ = build_tree_list (NULL_TREE, $$); } ! 3647: | parm '=' init ! 3648: { $$ = build_tree_list ($3, $$); } ! 3649: ; ! 3650: ! 3651: parm: ! 3652: named_parm ! 3653: | type_id ! 3654: ; ! 3655: ! 3656: see_typename: %prec EMPTY ! 3657: { see_typename (); } ! 3658: ; ! 3659: ! 3660: /* ! 3661: dont_see_typename: %prec EMPTY ! 3662: { dont_see_typename (); } ! 3663: ; ! 3664: ! 3665: try_for_typename: ! 3666: { ! 3667: if ($<ttype>-1 == error_mark_node) ! 3668: $$ = 0; ! 3669: else ! 3670: { ! 3671: $$ = 1; ! 3672: pushclass ($<ttype>-1, 1); ! 3673: } ! 3674: } ! 3675: ; ! 3676: */ ! 3677: ! 3678: bad_parm: ! 3679: /* empty */ %prec EMPTY ! 3680: { ! 3681: warning ("type specifier omitted for parameter"); ! 3682: $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), NULL_TREE); ! 3683: } ! 3684: | notype_declarator ! 3685: { ! 3686: warning ("type specifier omitted for parameter"); ! 3687: $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $$); ! 3688: } ! 3689: ; ! 3690: ! 3691: maybe_raises: ! 3692: %prec EMPTY /* empty */ ! 3693: { $$ = NULL_TREE; } ! 3694: | THROW '(' ansi_raise_identifiers ')' %prec EMPTY ! 3695: { $$ = $3; } ! 3696: ; ! 3697: ! 3698: ansi_raise_identifier: ! 3699: type_id ! 3700: { $$ = build_decl_list (NULL_TREE, $$); } ! 3701: ; ! 3702: ! 3703: ansi_raise_identifiers: ! 3704: ansi_raise_identifier ! 3705: | ansi_raise_identifiers ',' ansi_raise_identifier ! 3706: { ! 3707: TREE_CHAIN ($3) = $$; ! 3708: $$ = $3; ! 3709: } ! 3710: ; ! 3711: ! 3712: conversion_declarator: ! 3713: /* empty */ %prec EMPTY ! 3714: { $$ = NULL_TREE; } ! 3715: | '*' type_quals conversion_declarator ! 3716: { $$ = make_pointer_declarator ($2, $3); } ! 3717: | '&' type_quals conversion_declarator ! 3718: { $$ = make_reference_declarator ($2, $3); } ! 3719: | ptr_to_mem type_quals conversion_declarator ! 3720: { tree arg = make_pointer_declarator ($2, $3); ! 3721: $$ = build_parse_node (SCOPE_REF, $1, arg); ! 3722: } ! 3723: ; ! 3724: ! 3725: operator: OPERATOR ! 3726: { got_scope = NULL_TREE; } ! 3727: ; ! 3728: ! 3729: operator_name: ! 3730: operator '*' ! 3731: { $$ = ansi_opname[MULT_EXPR]; } ! 3732: | operator '/' ! 3733: { $$ = ansi_opname[TRUNC_DIV_EXPR]; } ! 3734: | operator '%' ! 3735: { $$ = ansi_opname[TRUNC_MOD_EXPR]; } ! 3736: | operator '+' ! 3737: { $$ = ansi_opname[PLUS_EXPR]; } ! 3738: | operator '-' ! 3739: { $$ = ansi_opname[MINUS_EXPR]; } ! 3740: | operator '&' ! 3741: { $$ = ansi_opname[BIT_AND_EXPR]; } ! 3742: | operator '|' ! 3743: { $$ = ansi_opname[BIT_IOR_EXPR]; } ! 3744: | operator '^' ! 3745: { $$ = ansi_opname[BIT_XOR_EXPR]; } ! 3746: | operator '~' ! 3747: { $$ = ansi_opname[BIT_NOT_EXPR]; } ! 3748: | operator ',' ! 3749: { $$ = ansi_opname[COMPOUND_EXPR]; } ! 3750: | operator ARITHCOMPARE ! 3751: { $$ = ansi_opname[$2]; } ! 3752: | operator '<' ! 3753: { $$ = ansi_opname[LT_EXPR]; } ! 3754: | operator '>' ! 3755: { $$ = ansi_opname[GT_EXPR]; } ! 3756: | operator EQCOMPARE ! 3757: { $$ = ansi_opname[$2]; } ! 3758: | operator ASSIGN ! 3759: { $$ = ansi_assopname[$2]; } ! 3760: | operator '=' ! 3761: { $$ = ansi_opname [MODIFY_EXPR]; } ! 3762: | operator LSHIFT ! 3763: { $$ = ansi_opname[$2]; } ! 3764: | operator RSHIFT ! 3765: { $$ = ansi_opname[$2]; } ! 3766: | operator PLUSPLUS ! 3767: { $$ = ansi_opname[POSTINCREMENT_EXPR]; } ! 3768: | operator MINUSMINUS ! 3769: { $$ = ansi_opname[PREDECREMENT_EXPR]; } ! 3770: | operator ANDAND ! 3771: { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; } ! 3772: | operator OROR ! 3773: { $$ = ansi_opname[TRUTH_ORIF_EXPR]; } ! 3774: | operator '!' ! 3775: { $$ = ansi_opname[TRUTH_NOT_EXPR]; } ! 3776: | operator '?' ':' ! 3777: { $$ = ansi_opname[COND_EXPR]; } ! 3778: | operator MIN_MAX ! 3779: { $$ = ansi_opname[$2]; } ! 3780: | operator POINTSAT %prec EMPTY ! 3781: { $$ = ansi_opname[COMPONENT_REF]; } ! 3782: | operator POINTSAT_STAR %prec EMPTY ! 3783: { $$ = ansi_opname[MEMBER_REF]; } ! 3784: | operator LEFT_RIGHT ! 3785: { $$ = ansi_opname[CALL_EXPR]; } ! 3786: | operator '[' ']' ! 3787: { $$ = ansi_opname[ARRAY_REF]; } ! 3788: | operator NEW %prec EMPTY ! 3789: { $$ = ansi_opname[NEW_EXPR]; } ! 3790: | operator DELETE %prec EMPTY ! 3791: { $$ = ansi_opname[DELETE_EXPR]; } ! 3792: | operator NEW '[' ']' ! 3793: { $$ = ansi_opname[VEC_NEW_EXPR]; } ! 3794: | operator DELETE '[' ']' ! 3795: { $$ = ansi_opname[VEC_DELETE_EXPR]; } ! 3796: /* Names here should be looked up in class scope ALSO. */ ! 3797: | operator type_specifier_seq conversion_declarator ! 3798: { $$ = grokoptypename ($2, $3); } ! 3799: | operator error ! 3800: { $$ = ansi_opname[ERROR_MARK]; } ! 3801: ; ! 3802: ! 3803: %% ! 3804: ! 3805: #ifdef SPEW_DEBUG ! 3806: const char * ! 3807: debug_yytranslate (value) ! 3808: int value; ! 3809: { ! 3810: return yytname[YYTRANSLATE (value)]; ! 3811: } ! 3812: ! 3813: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.