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