X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Fparse.y;h=ab6012fc1d4138827384d1dde1be254a2eb9420c;hb=b464c9a27e108516acae258ef36526de5ebbe824;hp=f08393cde58e9938f69899a1333a4bb7ed1f6fd5;hpb=a568aac932bd409be4c882bb50bf3556d3817bff;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index f08393cde58..ab6012fc1d4 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -1,5 +1,6 @@ /* YACC parser for C++ syntax. - Copyright (C) 1988, 89, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 1989, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -42,12 +43,12 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "except.h" #include "toplev.h" +#include "ggc.h" /* Since parsers are distinct for each language, put the language string definition here. (fnf) */ -char *language_string = "GNU C++"; +const char * const language_string = "GNU C++"; -extern tree void_list_node; extern struct obstack permanent_obstack; extern int end_of_file; @@ -60,19 +61,42 @@ extern int end_of_file; /* Contains the statement keyword (if/while/do) to include in an error message if the user supplies an empty conditional expression. */ -static char *cond_stmt_keyword; - -static tree empty_parms PROTO((void)); +static const char *cond_stmt_keyword; /* Nonzero if we have an `extern "C"' acting as an extern specifier. */ int have_extern_spec; int used_extern_spec; +/* List of types and structure classes of the current declaration. */ +static tree current_declspecs; + +/* List of prefix attributes in effect. + Prefix attributes are parsed by the reserved_declspecs and declmods + rules. They create a list that contains *both* declspecs and attrs. */ +/* ??? It is not clear yet that all cases where an attribute can now appear in + a declspec list have been updated. */ +static tree prefix_attributes; + +/* When defining an aggregate, this is the kind of the most recent one + being defined. (For example, this might be class_type_node.) */ +static tree current_aggr; + +/* When defining an enumeration, this is the type of the enumeration. */ +static tree current_enum_type; + +static tree empty_parms PARAMS ((void)); +static tree parse_decl0 PARAMS ((tree, tree, tree, tree, int)); +static tree parse_decl PARAMS ((tree, tree, int)); +static void parse_end_decl PARAMS ((tree, tree, tree)); +static tree parse_field0 PARAMS ((tree, tree, tree, tree, tree, tree)); +static tree parse_field PARAMS ((tree, tree, tree, tree)); +static tree parse_bitfield0 PARAMS ((tree, tree, tree, tree, tree)); +static tree parse_bitfield PARAMS ((tree, tree, tree)); +static tree parse_method PARAMS ((tree, tree, tree)); +static void frob_specs PARAMS ((tree, tree)); + /* Cons up an empty parameter list. */ -#ifdef __GNUC__ -__inline -#endif -static tree +static inline tree empty_parms () { tree parms; @@ -85,11 +109,123 @@ empty_parms () return parms; } +/* Record the decl-specifiers, attributes and type lookups from the + decl-specifier-seq in a declaration. */ + +static void +frob_specs (specs_attrs, lookups) + tree specs_attrs, lookups; +{ + save_type_access_control (lookups); + split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); + if (current_declspecs + && TREE_CODE (current_declspecs) != TREE_LIST) + current_declspecs = build_decl_list (NULL_TREE, current_declspecs); + if (have_extern_spec && !used_extern_spec) + { + current_declspecs = decl_tree_cons (NULL_TREE, + get_identifier ("extern"), + current_declspecs); + used_extern_spec = 1; + } +} + +static tree +parse_decl (declarator, attributes, initialized) + tree declarator, attributes; + int initialized; +{ + return start_decl (declarator, current_declspecs, initialized, + attributes, prefix_attributes); +} + +static tree +parse_decl0 (declarator, specs_attrs, lookups, attributes, initialized) + tree declarator, specs_attrs, lookups, attributes; + int initialized; +{ + frob_specs (specs_attrs, lookups); + return parse_decl (declarator, attributes, initialized); +} + +static void +parse_end_decl (decl, init, asmspec) + tree decl, init, asmspec; +{ + /* If decl is NULL_TREE, then this was a variable declaration using + () syntax for the initializer, so we handled it in grokdeclarator. */ + if (decl) + decl_type_access_control (decl); + cp_finish_decl (decl, init, asmspec, init ? LOOKUP_ONLYCONVERTING : 0); +} + +static tree +parse_field (declarator, attributes, asmspec, init) + tree declarator, attributes, asmspec, init; +{ + tree d = grokfield (declarator, current_declspecs, init, asmspec, + build_tree_list (attributes, prefix_attributes)); + decl_type_access_control (d); + return d; +} + +static tree +parse_field0 (declarator, specs_attrs, lookups, attributes, asmspec, init) + tree declarator, specs_attrs, lookups, attributes, asmspec, init; +{ + frob_specs (specs_attrs, lookups); + return parse_field (declarator, attributes, asmspec, init); +} + +static tree +parse_bitfield (declarator, attributes, width) + tree declarator, attributes, width; +{ + tree d = grokbitfield (declarator, current_declspecs, width); + cplus_decl_attributes (d, attributes, prefix_attributes); + decl_type_access_control (d); + return d; +} + +static tree +parse_bitfield0 (declarator, specs_attrs, lookups, attributes, width) + tree declarator, specs_attrs, lookups, attributes, width; +{ + frob_specs (specs_attrs, lookups); + return parse_bitfield (declarator, attributes, width); +} + +static tree +parse_method (declarator, specs_attrs, lookups) + tree declarator, specs_attrs, lookups; +{ + tree d; + frob_specs (specs_attrs, lookups); + d = start_method (current_declspecs, declarator, prefix_attributes); + decl_type_access_control (d); + return d; +} + +void +cp_parse_init () +{ + ggc_add_tree_root (¤t_declspecs, 1); + ggc_add_tree_root (&prefix_attributes, 1); + ggc_add_tree_root (¤t_aggr, 1); + ggc_add_tree_root (¤t_enum_type, 1); +} %} %start program -%union {long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; } +%union { + long itype; + tree ttype; + char *strtype; + enum tree_code code; + flagged_type_tree ftype; + struct pending_inline *pi; +} /* All identifiers that are not reserved words and are not declared typedefs in the current block */ @@ -130,10 +266,10 @@ empty_parms () /* the reserved words */ /* SCO include files test "ASM", so use something else. */ %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT -%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF +%token BREAK CONTINUE RETURN_KEYWORD GOTO ASM_KEYWORD TYPEOF ALIGNOF %token SIGOF %token ATTRIBUTE EXTENSION LABEL -%token REALPART IMAGPART +%token REALPART IMAGPART VA_ARG /* the reserved words... C++ extensions */ %token AGGR @@ -178,7 +314,7 @@ empty_parms () %left POINTSAT_STAR DOT_STAR %right UNARY PLUSPLUS MINUSMINUS '~' %left HYPERUNARY -%left PAREN_STAR_PAREN LEFT_RIGHT +%left LEFT_RIGHT %left POINTSAT '.' '(' '[' %right SCOPE /* C++ extension */ @@ -192,9 +328,7 @@ empty_parms () %type expr_no_commas cast_expr unary_expr primary string STRING %type reserved_declspecs boolean.literal %type reserved_typespecquals -%type declmods %type SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier -%type initdecls notype_initdecls initdcl /* C++ modification */ %type init initlist maybeasm maybe_init defarg defarg1 %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attributes attribute attribute_list attrib @@ -203,21 +337,22 @@ empty_parms () %type compstmt implicitly_scoped_stmt %type declarator notype_declarator after_type_declarator +%type notype_declarator_intern absdcl_intern +%type after_type_declarator_intern %type direct_notype_declarator direct_after_type_declarator - -%type opt.component_decl_list component_decl_list -%type component_decl component_decl_1 components notype_components -%type component_declarator component_declarator0 self_reference +%type components notype_components +%type component_decl component_decl_1 +%type component_declarator component_declarator0 %type notype_component_declarator notype_component_declarator0 %type after_type_component_declarator after_type_component_declarator0 -%type enumlist enumerator %type absdcl cv_qualifiers %type direct_abstract_declarator conversion_declarator %type new_declarator direct_new_declarator %type xexpr parmlist parms bad_parm %type identifiers_or_typenames %type fcast_or_absdcl regcast_or_absdcl -%type expr_or_declarator complex_notype_declarator +%type expr_or_declarator expr_or_declarator_intern +%type complex_notype_declarator %type notype_unqualified_id unqualified_id qualified_id %type template_id do_id object_template_id notype_template_declarator %type overqualified_id notype_qualified_id any_id @@ -228,30 +363,37 @@ empty_parms () %type type_id new_type_id typed_typespecs typespec typed_declspecs %type typed_declspecs1 type_specifier_seq nonempty_cv_qualifiers %type structsp typespecqual_reserved parm named_parm full_parm +%type declmods + +%type extension /* C++ extensions */ %token PTYPENAME -%token PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL +%token EXTERN_LANG_STRING ALL %token PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER +%token PRE_PARSED_FUNCTION_DECL %type component_constructor_declarator -%type fn.def2 return_id fn.defpen constructor_declarator -%type ctor_initializer_opt -%type named_class_head named_class_head_sans_basetype -%type named_complex_class_head_sans_basetype +%type fn.def2 return_id constructor_declarator +%type fn.defpen +%type ctor_initializer_opt function_try_block +%type named_class_head_sans_basetype +%type class_head named_class_head +%type named_complex_class_head_sans_basetype %type unnamed_class_head -%type class_head base_class_list +%type base_class_list %type base_class_access_list %type base_class maybe_base_class_list base_class.1 %type exception_specification_opt ansi_raise_identifier ansi_raise_identifiers %type operator_name %type object aggr -%type new delete .begin_new_placement +%type new delete /* %type primary_no_id */ -%type nonmomentary_expr maybe_parmlist -%type initdcl0 notype_initdcl0 member_init_list initdcl0_innards +%type maybe_parmlist +%type member_init_list %type template_header template_parm_list template_parm %type template_type_parm template_template_parm %type template_close_bracket +%type apparent_template_type %type template_type template_arg_list template_arg_list_opt %type template_arg %type condition xcond paren_cond_or_null @@ -266,8 +408,8 @@ empty_parms () %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN %type named_class_head_sans_basetype_defn %type identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN - -%type self_template_type +%type handler_args +%type self_template_type .finish_template_type %token NSNAME %type NSNAME @@ -280,51 +422,9 @@ empty_parms () %token END_OF_SAVED_INPUT %{ -/* List of types and structure classes of the current declaration. */ -static tree current_declspecs; - -/* List of prefix attributes in effect. - Prefix attributes are parsed by the reserved_declspecs and declmods - rules. They create a list that contains *both* declspecs and attrs. */ -/* ??? It is not clear yet that all cases where an attribute can now appear in - a declspec list have been updated. */ -static tree prefix_attributes; - -/* When defining an aggregate, this is the most recent one being defined. */ -static tree current_aggr; - /* Tell yyparse how to print a token's value, if yydebug is set. */ - #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern tree combine_strings PROTO((tree)); - -static int -parse_decl(declarator, specs_attrs, attributes, initialized, decl) - tree declarator; - tree specs_attrs; - tree attributes; - int initialized; - tree* decl; -{ - int sm; - - split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); - if (current_declspecs - && TREE_CODE (current_declspecs) != TREE_LIST) - current_declspecs = get_decl_list (current_declspecs); - if (have_extern_spec && !used_extern_spec) - { - current_declspecs = decl_tree_cons (NULL_TREE, - get_identifier ("extern"), - current_declspecs); - used_extern_spec = 1; - } - sm = suspend_momentary (); - *decl = start_decl (declarator, current_declspecs, initialized, - attributes, prefix_attributes); - return sm; -} +extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); %} %% @@ -341,9 +441,9 @@ program: extdefs: { $$ = NULL_TREE; } lang_extdef - { $$ = NULL_TREE; } + { $$ = NULL_TREE; ggc_collect (); } | extdefs lang_extdef - { $$ = NULL_TREE; } + { $$ = NULL_TREE; ggc_collect (); } ; extdefs_opt: @@ -362,7 +462,7 @@ extdefs_opt: extension: EXTENSION - { $$ = pedantic; + { $$ = pedantic; pedantic = 0; } ; @@ -371,9 +471,10 @@ asm_keyword: ; lang_extdef: - { if (pending_lang_change) do_pending_lang_change(); } + { if (pending_lang_change) do_pending_lang_change(); + type_lookups = NULL_TREE; } extdef - { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) + { if (! toplevel_bindings_p ()) pop_everything (); } ; @@ -403,7 +504,16 @@ extdef: { push_namespace (NULL_TREE); } extdefs_opt '}' { pop_namespace (); } - | NAMESPACE identifier '=' + | namespace_alias + | using_decl ';' + { do_toplevel_using_decl ($1); } + | using_directive + | extension extdef + { pedantic = $1; } + ; + +namespace_alias: + NAMESPACE identifier '=' { begin_only_namespace_names (); } any_id ';' { @@ -412,11 +522,6 @@ extdef: $5 = lastiddecl; do_namespace_alias ($2, $5); } - | using_decl ';' - { do_toplevel_using_decl ($1); } - | using_directive - | extension extdef - { pedantic = $1; } ; using_decl: @@ -552,22 +657,38 @@ template_parm: ; template_def: - template_header - extdef - { - if ($1) - end_template_decl (); - else - end_specialization (); - } - | template_header - error %prec EMPTY - { - if ($1) - end_template_decl (); - else - end_specialization (); - } + template_header template_extdef + { finish_template_decl ($1); } + | template_header error %prec EMPTY + { finish_template_decl ($1); } + ; + +template_extdef: + fndef eat_saved_input + { if (pending_inlines) do_pending_inlines (); } + | template_datadef + { if (pending_inlines) do_pending_inlines (); } + | template_def + { if (pending_inlines) do_pending_inlines (); } + | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input + { if (pending_inlines) do_pending_inlines (); + pop_lang_context (); } + | extern_lang_string .hush_warning template_datadef .warning_ok + { if (pending_inlines) do_pending_inlines (); + pop_lang_context (); } + | extension template_extdef + { pedantic = $1; } + ; + +template_datadef: + nomods_initdecls ';' + | declmods notype_initdecls ';' + {} + | typed_declspecs initdecls ';' + { note_list_got_semicolon ($1.t); } + | structsp ';' + { maybe_process_partial_specialization ($1.t); + note_got_semicolon ($1.t); } ; datadef: @@ -575,9 +696,7 @@ datadef: | declmods notype_initdecls ';' {} | typed_declspecs initdecls ';' - { - note_list_got_semicolon ($1.t); - } + { note_list_got_semicolon ($1.t); } | declmods ';' { pedwarn ("empty declaration"); } | explicit_instantiation ';' @@ -613,9 +732,9 @@ eat_saved_input: fndef: fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error - { finish_function (lineno, (int)$3, 0); } + { expand_body (finish_function (lineno, (int)$3)); } | fn.def1 maybe_return_init function_try_block - { } + { expand_body (finish_function (lineno, (int)$3)); } | fn.def1 maybe_return_init error { } ; @@ -660,13 +779,13 @@ fn.def1: { if (!begin_function_definition ($1.t, $2)) YYERROR1; } | declmods notype_declarator - { if (!begin_function_definition ($1, $2)) + { if (!begin_function_definition ($1.t, $2)) YYERROR1; } | notype_declarator { if (!begin_function_definition (NULL_TREE, $1)) YYERROR1; } | declmods constructor_declarator - { if (!begin_function_definition ($1, $2)) + { if (!begin_function_definition ($1.t, $2)) YYERROR1; } | constructor_declarator { if (!begin_function_definition (NULL_TREE, $1)) @@ -688,8 +807,7 @@ component_constructor_declarator: reduce/reduce conflict introduced by these rules. */ fn.def2: declmods component_constructor_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); + { $$ = parse_method ($2, $1.t, $1.lookups); rest_of_mdef: if (! $$) YYERROR1; @@ -697,24 +815,24 @@ fn.def2: yychar = YYLEX; reinit_parse_for_method (yychar, $$); } | component_constructor_declarator - { $$ = start_method (NULL_TREE, $1); goto rest_of_mdef; } + { $$ = parse_method ($1, NULL_TREE, NULL_TREE); + goto rest_of_mdef; } | typed_declspecs declarator - { tree specs = strip_attrs ($1.t); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;} | declmods notype_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;} | notype_declarator - { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } + { $$ = parse_method ($1, NULL_TREE, NULL_TREE); + goto rest_of_mdef; } | declmods constructor_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;} | constructor_declarator - { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } + { $$ = parse_method ($1, NULL_TREE, NULL_TREE); + goto rest_of_mdef; } ; return_id: - RETURN IDENTIFIER + RETURN_KEYWORD IDENTIFIER { if (! current_function_parms_stored) store_parm_decls (); @@ -724,11 +842,11 @@ return_id: return_init: return_id maybe_init - { store_return_init ($$, $2); } + { finish_named_return_value ($$, $2); } | return_id '(' nonnull_exprlist ')' - { store_return_init ($$, $3); } + { finish_named_return_value ($$, $3); } | return_id LEFT_RIGHT - { store_return_init ($$, NULL_TREE); } + { finish_named_return_value ($$, NULL_TREE); } ; base_init: @@ -737,10 +855,6 @@ base_init: if ($3 == 0) error ("no base initializers given following ':'"); setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); } ; @@ -751,12 +865,8 @@ base_init: store_parm_decls (); if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - /* Make a contour for the initializer list. */ - pushlevel (0); - clear_last_expr (); - expand_start_bindings (0); - } + /* Make a contour for the initializer list. */ + do_pushlevel (); else if (current_class_type == NULL_TREE) error ("base initializers not allowed for non-member functions"); else if (! DECL_CONSTRUCTOR_P (current_function_decl)) @@ -800,6 +910,7 @@ member_init: | typename_sub LEFT_RIGHT { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), void_type_node); } + | error ; identifier: @@ -866,29 +977,35 @@ end_explicit_instantiation: template_type: PTYPENAME '<' template_arg_list_opt template_close_bracket - { - $$ = lookup_template_class ($1, $3, NULL_TREE, NULL_TREE); - if ($$ != error_mark_node) - $$ = TYPE_STUB_DECL ($$); - } + .finish_template_type + { $$ = $5; } | TYPENAME '<' template_arg_list_opt template_close_bracket - { - $$ = lookup_template_class ($1, $3, NULL_TREE, NULL_TREE); - if ($$ != error_mark_node) - $$ = TYPE_STUB_DECL ($$); - } + .finish_template_type + { $$ = $5; } | self_template_type ; +apparent_template_type: + template_type + | identifier '<' template_arg_list_opt '>' + .finish_template_type + { $$ = $5; } + self_template_type: SELFNAME '<' template_arg_list_opt template_close_bracket - { - $$ = lookup_template_class ($1, $3, NULL_TREE, NULL_TREE); - if ($$ != error_mark_node) - $$ = TYPE_STUB_DECL ($$); - } + .finish_template_type + { $$ = $5; } ; +.finish_template_type: + { + if (yychar == YYEMPTY) + yychar = YYLEX; + + $$ = finish_template_type ($-3, $-1, + yychar == SCOPE); + } + template_close_bracket: '>' | RSHIFT @@ -941,7 +1058,7 @@ expr: paren_expr_or_null: LEFT_RIGHT - { error ("ANSI C++ forbids an empty condition for `%s'", + { error ("ISO C++ forbids an empty condition for `%s'", cond_stmt_keyword); $$ = integer_zero_node; } | '(' expr ')' @@ -950,7 +1067,7 @@ paren_expr_or_null: paren_cond_or_null: LEFT_RIGHT - { error ("ANSI C++ forbids an empty condition for `%s'", + { error ("ISO C++ forbids an empty condition for `%s'", cond_stmt_keyword); $$ = integer_zero_node; } | '(' condition ')' @@ -979,15 +1096,12 @@ condition: } } current_declspecs = $1.t; - $5 = suspend_momentary (); - $$ = start_decl ($2, current_declspecs, 1, - $4, /*prefix_attributes*/ NULL_TREE); + $$ = parse_decl ($2, $4, 1); } init { - cp_finish_decl ($6, $7, $4, 1, LOOKUP_ONLYCONVERTING); - resume_momentary ($5); - $$ = $6; + parse_end_decl ($6, $7, $4); + $$ = convert_from_reference ($6); if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) cp_error ("definition of array `%#D' in condition", $$); } @@ -1012,20 +1126,20 @@ already_scoped_stmt: nontrivial_exprlist: expr_no_commas ',' expr_no_commas - { $$ = expr_tree_cons (NULL_TREE, $$, - build_expr_list (NULL_TREE, $3)); } + { $$ = tree_cons (NULL_TREE, $$, + build_tree_list (NULL_TREE, $3)); } | expr_no_commas ',' error - { $$ = expr_tree_cons (NULL_TREE, $$, - build_expr_list (NULL_TREE, error_mark_node)); } + { $$ = tree_cons (NULL_TREE, $$, + build_tree_list (NULL_TREE, error_mark_node)); } | nontrivial_exprlist ',' expr_no_commas - { chainon ($$, build_expr_list (NULL_TREE, $3)); } + { chainon ($$, build_tree_list (NULL_TREE, $3)); } | nontrivial_exprlist ',' error - { chainon ($$, build_expr_list (NULL_TREE, error_mark_node)); } + { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); } ; nonnull_exprlist: expr_no_commas - { $$ = build_expr_list (NULL_TREE, $$); } + { $$ = build_tree_list (NULL_TREE, $$); } | nontrivial_exprlist ; @@ -1035,7 +1149,7 @@ unary_expr: /* __extension__ turns off -pedantic for following primary. */ | extension cast_expr %prec UNARY { $$ = $2; - pedantic = $1; } + pedantic = $1; } | '*' cast_expr %prec UNARY { $$ = build_x_indirect_ref ($2, "unary *"); } | '&' cast_expr %prec UNARY @@ -1047,12 +1161,13 @@ unary_expr: /* Refer to the address of a label as a pointer. */ | ANDAND identifier { if (pedantic) - pedwarn ("ANSI C++ forbids `&&'"); + pedwarn ("ISO C++ forbids `&&'"); $$ = finish_label_address_expr ($2); } | SIZEOF unary_expr %prec UNARY { $$ = expr_sizeof ($2); } | SIZEOF '(' type_id ')' %prec HYPERUNARY - { $$ = c_sizeof (groktypename ($3.t)); } + { $$ = c_sizeof (groktypename ($3.t)); + check_for_new_type ("sizeof", $3); } | ALIGNOF unary_expr %prec UNARY { $$ = grok_alignof ($2); } | ALIGNOF '(' type_id ')' %prec HYPERUNARY @@ -1073,32 +1188,20 @@ unary_expr: | new new_placement new_type_id new_initializer { $$ = build_new ($2, $3.t, $4, $1); check_for_new_type ("new", $3); } - /* The .begin_new_placement in the following rules is - necessary to avoid shift/reduce conflicts that lead to - mis-parsing some expressions. Of course, these constructs - are not really new-placement and it is bogus to call - begin_new_placement. But, the parser cannot always tell at this - point whether the next thing is an expression or a type-id, - so there is nothing we can do. Fortunately, - begin_new_placement does nothing harmful. When we rewrite - the parser, this lossage should be removed, of course. */ - | new '(' .begin_new_placement type_id .finish_new_placement + | new '(' type_id ')' %prec EMPTY - { $$ = build_new (NULL_TREE, groktypename($4.t), + { $$ = build_new (NULL_TREE, groktypename($3.t), NULL_TREE, $1); + check_for_new_type ("new", $3); } + | new '(' type_id ')' new_initializer + { $$ = build_new (NULL_TREE, groktypename($3.t), $5, $1); + check_for_new_type ("new", $3); } + | new new_placement '(' type_id ')' %prec EMPTY + { $$ = build_new ($2, groktypename($4.t), NULL_TREE, $1); check_for_new_type ("new", $4); } - | new '(' .begin_new_placement type_id .finish_new_placement - new_initializer - { $$ = build_new (NULL_TREE, groktypename($4.t), $6, $1); + | new new_placement '(' type_id ')' new_initializer + { $$ = build_new ($2, groktypename($4.t), $6, $1); check_for_new_type ("new", $4); } - | new new_placement '(' .begin_new_placement type_id - .finish_new_placement %prec EMPTY - { $$ = build_new ($2, groktypename($5.t), NULL_TREE, $1); - check_for_new_type ("new", $5); } - | new new_placement '(' .begin_new_placement type_id - .finish_new_placement new_initializer - { $$ = build_new ($2, groktypename($5.t), $7, $1); - check_for_new_type ("new", $5); } | delete cast_expr %prec UNARY { $$ = delete_sanity ($2, NULL_TREE, 0, $1); } @@ -1114,26 +1217,17 @@ unary_expr: { $$ = build_x_unary_op (REALPART_EXPR, $2); } | IMAGPART cast_expr %prec UNARY { $$ = build_x_unary_op (IMAGPART_EXPR, $2); } + | VA_ARG '(' expr_no_commas ',' type_id ')' + { $$ = build_x_va_arg ($3, groktypename ($5.t)); + check_for_new_type ("__builtin_va_arg", $5); } ; - /* Note this rule is not suitable for use in new_placement - since it uses NULL_TREE as the argument to - finish_new_placement. This rule serves only to avoid - reduce/reduce conflicts in unary_expr. See the comments - there on the use of begin/finish_new_placement. */ -.finish_new_placement: - ')' - { finish_new_placement (NULL_TREE, $-1); } - -.begin_new_placement: - { $$ = begin_new_placement (); } - new_placement: - '(' .begin_new_placement nonnull_exprlist ')' - { $$ = finish_new_placement ($3, $2); } - | '{' .begin_new_placement nonnull_exprlist '}' + '(' nonnull_exprlist ')' + { $$ = $2; } + | '{' nonnull_exprlist '}' { cp_pedwarn ("old style placement syntax, use () instead"); - $$ = finish_new_placement ($3, $2); } + $$ = $2; } ; new_initializer: @@ -1152,10 +1246,10 @@ new_initializer: | '=' init { if (pedantic) - pedwarn ("ANSI C++ forbids initialization of new expression with `='"); + pedwarn ("ISO C++ forbids initialization of new expression with `='"); if (TREE_CODE ($2) != TREE_LIST && TREE_CODE ($2) != CONSTRUCTOR) - $$ = build_expr_list (NULL_TREE, $2); + $$ = build_tree_list (NULL_TREE, $2); else $$ = $2; } @@ -1182,7 +1276,7 @@ cast_expr: tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($3)); if (pedantic) - pedwarn ("ANSI C++ forbids constructor-expressions"); + pedwarn ("ISO C++ forbids constructor-expressions"); /* Indicate that this was a GNU C constructor expression. */ TREE_HAS_CONSTRUCTOR (init) = 1; @@ -1261,6 +1355,8 @@ expr_no_commas: notype_unqualified_id: '~' see_typename identifier { $$ = build_parse_node (BIT_NOT_EXPR, $3); } + | '~' see_typename template_type + { $$ = build_parse_node (BIT_NOT_EXPR, $3); } | template_id | operator_name | IDENTIFIER @@ -1269,7 +1365,16 @@ notype_unqualified_id: ; do_id: - { $$ = do_identifier ($-1, 1, NULL_TREE); } + { + /* If lastiddecl is a TREE_LIST, it's a baselink, which + means that we're in an expression like S::f, so + don't do_identifier; we only do that for unqualified + identifiers. */ + if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST) + $$ = do_identifier ($-1, 1, NULL_TREE); + else + $$ = $-1; + } template_id: PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket @@ -1294,13 +1399,23 @@ unqualified_id: | SELFNAME ; +expr_or_declarator_intern: + expr_or_declarator + | attributes expr_or_declarator + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + expr_or_declarator: notype_unqualified_id - | '*' expr_or_declarator %prec UNARY + | '*' expr_or_declarator_intern %prec UNARY { $$ = build_parse_node (INDIRECT_REF, $2); } - | '&' expr_or_declarator %prec UNARY + | '&' expr_or_declarator_intern %prec UNARY { $$ = build_parse_node (ADDR_EXPR, $2); } - | '(' expr_or_declarator ')' + | '(' expr_or_declarator_intern ')' { $$ = $2; } ; @@ -1313,10 +1428,12 @@ notype_template_declarator: direct_notype_declarator: complex_direct_notype_declarator - | notype_unqualified_id + /* This precedence declaration is to prefer this reduce + to the Koenig lookup shift in primary, below. I hate yacc. */ + | notype_unqualified_id %prec '(' | notype_template_declarator - | '(' expr_or_declarator ')' - { $$ = finish_decl_parsing ($2); } + | '(' expr_or_declarator_intern ')' + { $$ = finish_decl_parsing ($2); } ; primary: @@ -1331,37 +1448,40 @@ primary: | boolean.literal | string { - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); $$ = combine_strings ($$); - if (processing_template_decl) - pop_obstacks (); + /* combine_strings doesn't set up TYPE_MAIN_VARIANT of + a const array the way we want, so fix it. */ + if (flag_const_strings) + TREE_TYPE ($$) = build_cplus_array_type + (TREE_TYPE (TREE_TYPE ($$)), + TYPE_DOMAIN (TREE_TYPE ($$))); } | '(' expr ')' { $$ = finish_parenthesized_expr ($2); } - | '(' expr_or_declarator ')' + | '(' expr_or_declarator_intern ')' { $2 = reparse_decl_as_expr (NULL_TREE, $2); $$ = finish_parenthesized_expr ($2); } | '(' error ')' { $$ = error_mark_node; } | '(' - { if (current_function_decl == 0) + { tree scope = current_scope (); + if (!scope || TREE_CODE (scope) != FUNCTION_DECL) { error ("braced-group within expression allowed only inside a function"); YYERROR; } if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); + pedwarn ("ISO C++ forbids braced-groups within expressions"); $$ = begin_stmt_expr (); } compstmt ')' - { $$ = finish_stmt_expr ($2, $3); } + { $$ = finish_stmt_expr ($2); } /* Koenig lookup support We could store lastiddecl in $1 to avoid another lookup, but that would result in many additional reduce/reduce conflicts. */ - | IDENTIFIER '(' nonnull_exprlist ')' + | notype_unqualified_id '(' nonnull_exprlist ')' { $$ = finish_call_expr ($1, $3, 1); } - | IDENTIFIER LEFT_RIGHT + | notype_unqualified_id LEFT_RIGHT { $$ = finish_call_expr ($1, NULL_TREE, 1); } | primary '(' nonnull_exprlist ')' { $$ = finish_call_expr ($1, $3, 0); } @@ -1378,47 +1498,14 @@ primary: { $$ = finish_this_expr (); } | CV_QUALIFIER '(' nonnull_exprlist ')' { - tree type = NULL_TREE; - tree id = $$; + /* This is a C cast in C++'s `functional' notation + using the "implicit int" extension so that: + `const (3)' is equivalent to `const int (3)'. */ + tree type; - /* This is a C cast in C++'s `functional' notation. */ - if ($3 == error_mark_node) - { - $$ = error_mark_node; - break; - } -#if 0 - if ($3 == NULL_TREE) - { - error ("cannot cast null list to type `%s'", - IDENTIFIER_POINTER (TYPE_NAME (id))); - $$ = error_mark_node; - break; - } -#endif -#if 0 - /* type is not set! (mrs) */ - if (type == error_mark_node) - $$ = error_mark_node; - else -#endif - { - if (id == ridpointers[(int) RID_CONST]) - type = build_type_variant (integer_type_node, 1, 0); - else if (id == ridpointers[(int) RID_VOLATILE]) - type = build_type_variant (integer_type_node, 0, 1); -#if 0 - /* should not be able to get here (mrs) */ - else if (id == ridpointers[(int) RID_FRIEND]) - { - error ("cannot cast expression to `friend' type"); - $$ = error_mark_node; - break; - } -#endif - else my_friendly_abort (79); - $$ = build_c_cast (type, build_compound_expr ($3)); - } + type = hash_tree_cons (NULL_TREE, $1, NULL_TREE); + type = groktypename (build_decl_list (type, NULL_TREE)); + $$ = build_functional_cast (type, $3); } | functional_cast | DYNAMIC_CAST '<' type_id '>' '(' expr ')' @@ -1438,7 +1525,7 @@ primary: check_for_new_type ("const_cast", $3); $$ = build_const_cast (type, $6); } | TYPEID '(' expr ')' - { $$ = build_x_typeid ($3); } + { $$ = build_typeid ($3); } | TYPEID '(' type_id ')' { tree type = groktypename ($3.t); check_for_new_type ("typeid", $3); @@ -1458,9 +1545,9 @@ primary: | overqualified_id %prec HYPERUNARY { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } | overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_globally_qualified_member_call_expr ($1, $3); } + { $$ = finish_qualified_call_expr ($1, $3); } | overqualified_id LEFT_RIGHT - { $$ = finish_globally_qualified_member_call_expr ($1, NULL_TREE); } + { $$ = finish_qualified_call_expr ($1, NULL_TREE); } | object object_template_id %prec UNARY { $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); @@ -1473,7 +1560,7 @@ primary: { $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); } | object overqualified_id %prec UNARY { if (processing_template_decl) - $$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2)); + $$ = build_min_nt (COMPONENT_REF, $1, $2); else $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } | object unqualified_id '(' nonnull_exprlist ')' @@ -1511,7 +1598,7 @@ primary_no_id: $$ = expand_start_stmt_expr (); } compstmt ')' { if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); + pedwarn ("ISO C++ forbids braced-groups within expressions"); $$ = expand_end_stmt_expr ($2); } | primary_no_id '(' nonnull_exprlist ')' { $$ = build_x_function_call ($$, $3, current_class_ref); } @@ -1567,10 +1654,6 @@ nodecls: if (! current_function_parms_stored) store_parm_decls (); setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); } ; @@ -1587,17 +1670,15 @@ object: decl: typespec initdecls ';' { - resume_momentary ($2); if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t))) note_got_semicolon ($1.t); } | typed_declspecs initdecls ';' { - resume_momentary ($2); note_list_got_semicolon ($1.t); } | declmods notype_initdecls ';' - { resume_momentary ($2); } + {} | typed_declspecs ';' { shadow_tag ($1.t); @@ -1606,7 +1687,7 @@ decl: | declmods ';' { warning ("empty declaration"); } | extension decl - { pedantic = $1; } + { pedantic = $1; } ; /* Any kind of declarator (thus, all declarators allowed @@ -1627,7 +1708,7 @@ fcast_or_absdcl: NULL_TREE); } ; -/* ANSI type-id (8.1) */ +/* ISO type-id (8.1) */ type_id: typed_typespecs absdcl { $$.t = build_decl_list ($1.t, $2); @@ -1636,7 +1717,8 @@ type_id: { $$.t = build_decl_list ($1.t, $2); $$.new_type_flag = $1.new_type_flag; } | typespec absdcl - { $$.t = build_decl_list (get_decl_list ($1.t), $2); + { $$.t = build_decl_list (build_decl_list (NULL_TREE, $1.t), + $2); $$.new_type_flag = $1.new_type_flag; } | typed_typespecs %prec EMPTY { $$.t = build_decl_list ($1.t, NULL_TREE); @@ -1653,12 +1735,14 @@ type_id: typed_declspecs: typed_typespecs %prec EMPTY + { $$.lookups = type_lookups; } | typed_declspecs1 + { $$.lookups = type_lookups; } ; typed_declspecs1: declmods typespec - { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1); + { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1.t); $$.new_type_flag = $2.new_type_flag; } | typespec reserved_declspecs %prec HYPERUNARY { $$.t = decl_tree_cons (NULL_TREE, $1.t, $2); @@ -1667,14 +1751,14 @@ typed_declspecs1: { $$.t = decl_tree_cons (NULL_TREE, $1.t, chainon ($2, $3)); $$.new_type_flag = $1.new_type_flag; } | declmods typespec reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); + { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); $$.new_type_flag = $2.new_type_flag; } | declmods typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); + { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); $$.new_type_flag = $2.new_type_flag; } | declmods typespec reserved_typespecquals reserved_declspecs { $$.t = decl_tree_cons (NULL_TREE, $2.t, - chainon ($3, chainon ($4, $1))); + chainon ($3, chainon ($4, $1.t))); $$.new_type_flag = $2.new_type_flag; } ; @@ -1702,24 +1786,43 @@ reserved_declspecs: to redeclare a typedef-name. In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ +/* We use hash_tree_cons for lists of typeless declspecs so that they end + up on a persistent obstack. Otherwise, they could appear at the + beginning of something like + + static const struct { int foo () { } } b; + + and would be discarded after we finish compiling foo. We don't need to + worry once we see a type. */ + declmods: nonempty_cv_qualifiers %prec EMPTY - { $$ = $1.t; TREE_STATIC ($$) = 1; } + { $$.lookups = NULL_TREE; TREE_STATIC ($$.t) = 1; } | SCSPEC - { $$ = IDENTIFIER_AS_LIST ($$); } + { + $$.t = hash_tree_cons (NULL_TREE, $1, NULL_TREE); + $$.new_type_flag = 0; $$.lookups = NULL_TREE; + } | declmods CV_QUALIFIER - { $$ = decl_tree_cons (NULL_TREE, $2, $$); - TREE_STATIC ($$) = 1; } + { + $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); + TREE_STATIC ($$.t) = 1; + } | declmods SCSPEC - { if (extra_warnings && TREE_STATIC ($$)) + { + if (extra_warnings && TREE_STATIC ($$.t)) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); - $$ = decl_tree_cons (NULL_TREE, $2, $$); - TREE_STATIC ($$) = TREE_STATIC ($1); } + $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); + TREE_STATIC ($$.t) = TREE_STATIC ($1.t); + } | declmods attributes - { $$ = decl_tree_cons ($2, NULL_TREE, $1); } - | attributes - { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } + { $$.t = hash_tree_cons ($2, NULL_TREE, $1.t); } + | attributes %prec EMPTY + { + $$.t = hash_tree_cons ($1, NULL_TREE, NULL_TREE); + $$.new_type_flag = 0; $$.lookups = NULL_TREE; + } ; /* Used instead of declspecs where storage classes are not allowed @@ -1730,7 +1833,7 @@ declmods: typed_typespecs: typespec %prec EMPTY - { $$.t = get_decl_list ($1.t); + { $$.t = build_decl_list (NULL_TREE, $1.t); $$.new_type_flag = $1.new_type_flag; } | nonempty_cv_qualifiers typespec { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1.t); @@ -1740,7 +1843,7 @@ typed_typespecs: $$.new_type_flag = $1.new_type_flag; } | nonempty_cv_qualifiers typespec reserved_typespecquals { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); - $$.new_type_flag = $1.new_type_flag; } + $$.new_type_flag = $2.new_type_flag; } ; reserved_typespecquals: @@ -1756,20 +1859,21 @@ reserved_typespecquals: typespec: structsp + { $$.lookups = NULL_TREE; } | TYPESPEC %prec EMPTY - { $$.t = $1; $$.new_type_flag = 0; } + { $$.t = $1; $$.new_type_flag = 0; $$.lookups = NULL_TREE; } | complete_type_name - { $$.t = $1; $$.new_type_flag = 0; } + { $$.t = $1; $$.new_type_flag = 0; $$.lookups = NULL_TREE; } | TYPEOF '(' expr ')' - { $$.t = TREE_TYPE ($3); - $$.new_type_flag = 0; } + { $$.t = finish_typeof ($3); + $$.new_type_flag = 0; $$.lookups = NULL_TREE; } | TYPEOF '(' type_id ')' { $$.t = groktypename ($3.t); - $$.new_type_flag = 0; } + $$.new_type_flag = 0; $$.lookups = NULL_TREE; } | SIGOF '(' expr ')' { tree type = TREE_TYPE ($3); - $$.new_type_flag = 0; + $$.new_type_flag = 0; $$.lookups = NULL_TREE; if (IS_AGGR_TYPE (type)) { sorry ("sigof type specifier"); @@ -1784,7 +1888,7 @@ typespec: | SIGOF '(' type_id ')' { tree type = groktypename ($3.t); - $$.new_type_flag = 0; + $$.new_type_flag = 0; $$.lookups = NULL_TREE; if (IS_AGGR_TYPE (type)) { sorry ("sigof type specifier"); @@ -1811,16 +1915,19 @@ typespecqual_reserved: initdecls: initdcl0 | initdecls ',' initdcl + { check_multiple_declarators (); } ; notype_initdecls: notype_initdcl0 | notype_initdecls ',' initdcl + { check_multiple_declarators (); } ; nomods_initdecls: nomods_initdcl0 | nomods_initdecls ',' initdcl + { check_multiple_declarators (); } ; maybeasm: @@ -1832,15 +1939,15 @@ maybeasm: initdcl: declarator maybeasm maybe_attribute '=' - { $$ = start_decl ($1, current_declspecs, 1, - $3, prefix_attributes); } + { $$ = parse_decl ($1, $3, 1); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ - { cp_finish_decl ($5, $6, $2, 1, LOOKUP_ONLYCONVERTING); } + { parse_end_decl ($5, $6, $2); } | declarator maybeasm maybe_attribute - { $$ = start_decl ($1, current_declspecs, 0, - $3, prefix_attributes); - cp_finish_decl ($$, NULL_TREE, $2, 1, 0); } + { + $$ = parse_decl ($1, $3, 0); + parse_end_decl ($$, NULL_TREE, $2); + } ; /* This rule assumes a certain configuration of the parser stack. @@ -1851,40 +1958,38 @@ initdcl: we need that reduce so we prefer fn.def1 when appropriate. */ initdcl0_innards: maybe_attribute '=' - { $2 = parse_decl ($-1, $-2, - $1, 1, &$$); } + { $$ = parse_decl0 ($-1, $-2.t, + $-2.lookups, $1, 1); } /* Note how the declaration of the variable is in effect while its init is parsed! */ init - { cp_finish_decl ($3, $4, $0, 1, - LOOKUP_ONLYCONVERTING); - $$ = $2; } + { parse_end_decl ($3, $4, $0); } | maybe_attribute - { tree d; - $$ = parse_decl ($-1, $-2, $1, 0, &d); - cp_finish_decl (d, NULL_TREE, $0, 1, 0); } + { tree d = parse_decl0 ($-1, $-2.t, + $-2.lookups, $1, 0); + parse_end_decl (d, NULL_TREE, $0); } ; initdcl0: declarator maybeasm initdcl0_innards - { $$ = $3; } - + {} + ; + notype_initdcl0: notype_declarator maybeasm initdcl0_innards - { $$ = $3; } + {} ; nomods_initdcl0: notype_declarator maybeasm { /* Set things up as initdcl0_innards expects. */ - $$ = $1; + $2 = $1; $1 = NULL_TREE; } initdcl0_innards {} | constructor_declarator maybeasm maybe_attribute - { tree d; - parse_decl($1, NULL_TREE, $3, 0, &d); - cp_finish_decl (d, NULL_TREE, $2, 1, 0); } + { tree d = parse_decl0 ($1, NULL_TREE, NULL_TREE, $3, 0); + parse_end_decl (d, NULL_TREE, $2); } ; /* the * rules are dummies to accept the Apollo extended syntax @@ -1976,34 +2081,38 @@ initlist: init { $$ = build_tree_list (NULL_TREE, $$); } | initlist ',' init - { $$ = expr_tree_cons (NULL_TREE, $3, $$); } + { $$ = tree_cons (NULL_TREE, $3, $$); } /* These are for labeled elements. */ | '[' expr_no_commas ']' init - { $$ = build_expr_list ($2, $4); } + { $$ = build_tree_list ($2, $4); } | identifier ':' init - { $$ = build_expr_list ($$, $3); } + { $$ = build_tree_list ($$, $3); } | initlist ',' identifier ':' init - { $$ = expr_tree_cons ($3, $5, $$); } + { $$ = tree_cons ($3, $5, $$); } ; fn.defpen: PRE_PARSED_FUNCTION_DECL - { start_function (NULL_TREE, TREE_VALUE ($1), - NULL_TREE, 1); + { start_function (NULL_TREE, $1->fndecl, NULL_TREE, + (SF_DEFAULT | SF_PRE_PARSED + | SF_INCLASS_INLINE)); reinit_parse_for_function (); } pending_inline: fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3, nested); + expand_body (finish_function (lineno, (int)$3 | 2)); process_next_inline ($1); } | fn.defpen maybe_return_init function_try_block - { process_next_inline ($1); } + { + expand_body (finish_function (lineno, (int)$3 | 2)); + process_next_inline ($1); + } | fn.defpen maybe_return_init error - { process_next_inline ($1); } + { + finish_function (lineno, 2); + process_next_inline ($1); } ; pending_inlines: @@ -2029,40 +2138,35 @@ pending_defargs: structsp: ENUM identifier '{' - { $3 = suspend_momentary (); - $$ = start_enum ($2); } - enumlist maybecomma_warn '}' - { $$.t = finish_enum ($4, $5); - $$.new_type_flag = 1; - resume_momentary ((int) $3); - check_for_missing_semicolon ($4); } - | ENUM identifier '{' '}' - { $$.t = finish_enum (start_enum ($2), NULL_TREE); + { $$ = current_enum_type; + current_enum_type = start_enum ($2); } + enumlist_opt '}' + { $$.t = finish_enum (current_enum_type); $$.new_type_flag = 1; + current_enum_type = $4; check_for_missing_semicolon ($$.t); } | ENUM '{' - { $2 = suspend_momentary (); - $$ = start_enum (make_anon_name ()); } - enumlist maybecomma_warn '}' - { $$.t = finish_enum ($3, $4); - resume_momentary ((int) $1); - check_for_missing_semicolon ($3); - $$.new_type_flag = 1; } - | ENUM '{' '}' - { $$.t = finish_enum (start_enum (make_anon_name()), NULL_TREE); + { $$ = current_enum_type; + current_enum_type = start_enum (make_anon_name ()); } + enumlist_opt '}' + { $$.t = finish_enum (current_enum_type); $$.new_type_flag = 1; + current_enum_type = $3; check_for_missing_semicolon ($$.t); } | ENUM identifier - { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); + { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | ENUM complex_type_name - { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); + { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | TYPENAME_KEYWORD typename_sub { $$.t = $2; - $$.new_type_flag = 0; } + $$.new_type_flag = 0; + if (!processing_template_decl) + cp_pedwarn ("using `typename' outside of template"); } /* C++ extensions, merged with C to avoid shift/reduce conflicts */ - | class_head left_curly + | class_head '{' + { $1.t = begin_class_definition ($1.t); } opt.component_decl_list '}' maybe_attribute { int semi; @@ -2071,27 +2175,38 @@ structsp: yychar = YYLEX; semi = yychar == ';'; - $$ = finish_class_definition ($1, $3, $5, semi); + $$ = finish_class_definition ($1.t, $6, semi, + $1.new_type_flag); } pending_defargs - { finish_default_args (); } + { + begin_inline_definitions (); + } pending_inlines - { $$.t = $6; + { + finish_inline_definitions (); + $$.t = $7; $$.new_type_flag = 1; - begin_inline_definitions (); } + } | class_head %prec EMPTY { + if ($1.new_type_flag && $1.t != error_mark_node) + pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL ($1.t))); $$.new_type_flag = 0; - if (TYPE_BINFO ($1) == NULL_TREE) + if ($1.t == error_mark_node) + $$.t = $1.t; + else if (TYPE_BINFO ($1.t) == NULL_TREE) { - cp_error ("%T is not a class type", $1); + cp_error ("%T is not a class type", $1.t); $$.t = error_mark_node; } else { - $$.t = $1; - /* struct B: public A; is not accepted by the WP grammar. */ - if (TYPE_BINFO_BASETYPES ($$.t) && !TYPE_SIZE ($$.t) + $$.t = $1.t; + /* struct B: public A; is not accepted by the standard grammar. */ + if (CLASS_TYPE_P ($$.t) + && TYPE_BINFO_BASETYPES ($$.t) + && !TYPE_SIZE ($$.t) && ! TYPE_BEING_DEFINED ($$.t)) cp_error ("base clause without member specification for `%#T'", $$.t); @@ -2127,87 +2242,117 @@ aggr: named_class_head_sans_basetype: aggr identifier - { current_aggr = $$; $$ = $2; } + { + current_aggr = $1; + $$ = $2; + } ; named_class_head_sans_basetype_defn: aggr identifier_defn %prec EMPTY { current_aggr = $$; $$ = $2; } + | named_class_head_sans_basetype '{' + { yyungetc ('{', 1); } + | named_class_head_sans_basetype ':' + { yyungetc (':', 1); } ; named_complex_class_head_sans_basetype: aggr nested_name_specifier identifier { current_aggr = $1; - $$ = handle_class_head ($1, $2, $3); + $$.t = handle_class_head ($1, $2, $3); + $$.new_type_flag = 1; } | aggr global_scope nested_name_specifier identifier { current_aggr = $1; - $$ = handle_class_head ($1, $3, $4); + $$.t = handle_class_head ($1, $3, $4); + $$.new_type_flag = 1; } | aggr global_scope identifier { current_aggr = $1; - $$ = handle_class_head ($1, NULL_TREE, $3); + $$.t = handle_class_head ($1, NULL_TREE, $3); + $$.new_type_flag = 1; + } + | aggr apparent_template_type + { + current_aggr = $1; + $$.t = $2; + $$.new_type_flag = 0; + } + | aggr nested_name_specifier apparent_template_type + { + current_aggr = $1; + $$.t = $3; + if (CP_DECL_CONTEXT ($$.t)) + push_scope (CP_DECL_CONTEXT ($$.t)); + $$.new_type_flag = 1; } - | aggr template_type - { current_aggr = $$; $$ = $2; } - | aggr nested_name_specifier template_type - { current_aggr = $$; $$ = $3; } - ; - -do_xref_defn: - /* empty */ %prec EMPTY - { $$ = xref_tag (current_aggr, $0, NULL_TREE, 0); } ; named_class_head: named_class_head_sans_basetype %prec EMPTY - { $$ = xref_tag (current_aggr, $1, NULL_TREE, 1); } - | named_class_head_sans_basetype_defn do_xref_defn + { + $$.t = xref_tag (current_aggr, $1, 1); + $$.new_type_flag = 0; + } + | named_class_head_sans_basetype_defn + { $$ = xref_tag (current_aggr, $1, 0); } + /* Class name is unqualified, so we look for base classes + in the current scope. */ maybe_base_class_list %prec EMPTY { - $$ = $2; + $$.t = $2; + $$.new_type_flag = 0; if ($3) xref_basetypes (current_aggr, $1, $2, $3); } - | named_complex_class_head_sans_basetype maybe_base_class_list + | named_complex_class_head_sans_basetype + maybe_base_class_list { - $$ = TREE_TYPE ($1); - if (TREE_INT_CST_LOW (current_aggr) == union_type - && TREE_CODE ($$) != UNION_TYPE) - cp_pedwarn ("`union' tag used in declaring `%#T'", $$); - else if (TREE_CODE ($$) == UNION_TYPE - && TREE_INT_CST_LOW (current_aggr) != union_type) - cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$); - if ($2) + if ($1.t != error_mark_node) { - if (IS_AGGR_TYPE ($$) && CLASSTYPE_USE_TEMPLATE ($$)) - { - if (CLASSTYPE_IMPLICIT_INSTANTIATION ($$) - && TYPE_SIZE ($$) == NULL_TREE) - { - SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$); - if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL ($$)); - } - else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$)) - cp_error ("specialization after instantiation of `%T'", $$); + $$.t = TREE_TYPE ($1.t); + $$.new_type_flag = $1.new_type_flag; + if (current_aggr == union_type_node + && TREE_CODE ($$.t) != UNION_TYPE) + cp_pedwarn ("`union' tag used in declaring `%#T'", + $$.t); + else if (TREE_CODE ($$.t) == UNION_TYPE + && current_aggr != union_type_node) + cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$); + else if (TREE_CODE ($$.t) == RECORD_TYPE) + /* We might be specializing a template with a different + class-key; deal. */ + CLASSTYPE_DECLARED_CLASS ($$.t) + = (current_aggr == class_type_node); + if ($2) + { + maybe_process_partial_specialization ($$.t); + xref_basetypes (current_aggr, $1.t, $$.t, $2); } - xref_basetypes (current_aggr, $1, $$, $2); } } ; unnamed_class_head: aggr '{' - { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0); + { $$ = xref_tag ($$, make_anon_name (), 0); yyungetc ('{', 1); } ; +/* The tree output of this nonterminal a declarationf or the type + named. If NEW_TYPE_FLAG is set, then the name used in this + class-head was explicitly qualified, e.g.: `struct X::Y'. We have + already called push_scope for X. */ class_head: unnamed_class_head + { + $$.t = $1; + $$.new_type_flag = 0; + } | named_class_head ; @@ -2228,105 +2373,20 @@ base_class_list: base_class: base_class.1 - { - tree type = TREE_TYPE ($1); - if (! is_aggr_type (type, 1)) - $$ = NULL_TREE; - else if (current_aggr == signature_type_node - && (! type) && (! IS_SIGNATURE (type))) - { - error ("class name not allowed as base signature"); - $$ = NULL_TREE; - } - else if (current_aggr == signature_type_node) - { - sorry ("signature inheritance, base type `%s' ignored", - IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (access_public_node, type); - } - else if (type && IS_SIGNATURE (type)) - { - error ("signature name not allowed as base class"); - $$ = NULL_TREE; - } - else - $$ = build_tree_list (access_default_node, type); - } + { $$ = finish_base_specifier (access_default_node, $1); } | base_class_access_list see_typename base_class.1 - { - tree type = TREE_TYPE ($3); - if (current_aggr == signature_type_node) - error ("access and source specifiers not allowed in signature"); - if (! is_aggr_type (type, 1)) - $$ = NULL_TREE; - else if (current_aggr == signature_type_node - && (! type) && (! IS_SIGNATURE (type))) - { - error ("class name not allowed as base signature"); - $$ = NULL_TREE; - } - else if (current_aggr == signature_type_node) - { - sorry ("signature inheritance, base type `%s' ignored", - IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (access_public_node, type); - } - else if (type && IS_SIGNATURE (type)) - { - error ("signature name not allowed as base class"); - $$ = NULL_TREE; - } - else - $$ = build_tree_list ($$, type); - } + { $$ = finish_base_specifier ($1, $3); } ; base_class.1: typename_sub - { $$ = TYPE_MAIN_DECL ($1); } + { if ($$ == error_mark_node) + ; + else if (!TYPE_P ($$)) + $$ = error_mark_node; + else + $$ = TYPE_MAIN_DECL ($1); } | nonnested_type - | SIGOF '(' expr ')' - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (TREE_TYPE ($3))) - { - sorry ("`sigof' as base signature specifier"); - $$ = TREE_TYPE ($3); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$ = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - $$ = error_mark_node; - } - } - | SIGOF '(' type_id ')' - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (groktypename ($3.t))) - { - sorry ("`sigof' as base signature specifier"); - $$ = groktypename ($3.t); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$ = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - $$ = error_mark_node; - } - } ; base_class_access_list: @@ -2360,71 +2420,34 @@ base_class_access_list: } ; -left_curly: - '{' - { $0 = begin_class_definition ($0); } - ; - -self_reference: - /* empty */ - { - $$ = build_self_reference (); - } - ; - opt.component_decl_list: - self_reference - { if ($$) $$ = build_tree_list (access_public_node, $$); } - | self_reference component_decl_list - { - if (current_aggr == signature_type_node) - $$ = build_tree_list (access_public_node, $2); - else - $$ = build_tree_list (access_default_node, $2); - if ($1) $$ = tree_cons (access_public_node, $1, $$); - } - | opt.component_decl_list VISSPEC ':' component_decl_list - { - tree visspec = $2; + | component_decl_list + | opt.component_decl_list access_specifier component_decl_list + | opt.component_decl_list access_specifier + ; - if (current_aggr == signature_type_node) - { - error ("access specifier not allowed in signature"); - visspec = access_public_node; - } - $$ = chainon ($$, build_tree_list (visspec, $4)); - } - | opt.component_decl_list VISSPEC ':' - { - if (current_aggr == signature_type_node) - error ("access specifier not allowed in signature"); - } +access_specifier: + VISSPEC ':' + { + current_access_specifier = $1; + } ; /* Note: we no longer warn about the semicolon after a component_decl_list. ARM $9.2 says that the semicolon is optional, and therefore allowed. */ component_decl_list: component_decl - { if ($$ == void_type_node) $$ = NULL_TREE; + { + finish_member_declaration ($1); } | component_decl_list component_decl - { /* In pushdecl, we created a reverse list of names - in this binding level. Make sure that the chain - of what we're trying to add isn't the item itself - (which can happen with what pushdecl's doing). */ - if ($2 != NULL_TREE && $2 != void_type_node) - { - if (TREE_CHAIN ($2) != $$) - $$ = chainon ($$, $2); - else - $$ = $2; - } + { + finish_member_declaration ($2); } ; component_decl: component_decl_1 ';' - { } | component_decl_1 '}' { error ("missing ';' before right brace"); yyungetc ('}', 0); } @@ -2434,7 +2457,7 @@ component_decl: { $$ = finish_method ($$); } | fn.def2 TRY /* base_init compstmt */ { $$ = finish_method ($$); } - | fn.def2 RETURN /* base_init compstmt */ + | fn.def2 RETURN_KEYWORD /* base_init compstmt */ { $$ = finish_method ($$); } | fn.def2 '{' /* nodecls compstmt */ { $$ = finish_method ($$); } @@ -2442,11 +2465,22 @@ component_decl: { $$ = NULL_TREE; } | extension component_decl { $$ = $2; - pedantic = $1; } + pedantic = $1; } | template_header component_decl - { $$ = finish_member_template_decl ($1, $2); } + { + if ($2) + $$ = finish_member_template_decl ($2); + else + /* The component was already processed. */ + $$ = NULL_TREE; + + finish_template_decl ($1); + } | template_header typed_declspecs ';' - { $$ = finish_member_class_template ($1, $2.t); } + { + $$ = finish_member_class_template ($2.t); + finish_template_decl ($1); + } ; component_decl_1: @@ -2454,9 +2488,32 @@ component_decl_1: speed; we need to call grok_x_components for enums, so the speedup would be insignificant. */ typed_declspecs components - { $$ = grok_x_components ($1.t, $2); } + { + /* Most of the productions for component_decl only + allow the creation of one new member, so we call + finish_member_declaration in component_decl_list. + For this rule and the next, however, there can be + more than one member, e.g.: + + int i, j; + + and we need the first member to be fully + registered before the second is processed. + Therefore, the rules for components take care of + this processing. To avoid registering the + components more than once, we send NULL_TREE up + here; that lets finish_member_declaration know + that there is nothing to do. */ + if (!$2) + grok_x_components ($1.t); + $$ = NULL_TREE; + } | declmods notype_components - { $$ = grok_x_components ($1, $2); } + { + if (!$2) + grok_x_components ($1.t); + $$ = NULL_TREE; + } | notype_declarator maybeasm maybe_attribute maybe_init { $$ = grokfield ($$, NULL_TREE, $4, $2, build_tree_list ($3, NULL_TREE)); } @@ -2478,7 +2535,7 @@ component_decl_1: parmlist? */ | declmods component_constructor_declarator maybeasm maybe_attribute maybe_init { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); + split_specs_attrs ($1.t, &specs, &attrs); $$ = grokfield ($2, specs, $5, $3, build_tree_list ($4, attrs)); } | component_constructor_declarator maybeasm maybe_attribute maybe_init @@ -2491,31 +2548,41 @@ component_decl_1: /* ??? Huh? ^^^ */ components: /* empty: possibly anonymous */ - { $$ = NULL_TREE; } + { $$ = 0; } | component_declarator0 + { + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $1 = finish_member_template_decl ($1); + finish_member_declaration ($1); + $$ = 1; + } | components ',' component_declarator - { - /* In this context, void_type_node encodes - friends. They have been recorded elsewhere. */ - if ($$ == void_type_node) - $$ = $3; - else - $$ = chainon ($$, $3); + { + check_multiple_declarators (); + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $3 = finish_member_template_decl ($3); + finish_member_declaration ($3); + $$ = 2; } ; notype_components: /* empty: possibly anonymous */ - { $$ = NULL_TREE; } + { $$ = 0; } | notype_component_declarator0 + { + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $1 = finish_member_template_decl ($1); + finish_member_declaration ($1); + $$ = 1; + } | notype_components ',' notype_component_declarator - { - /* In this context, void_type_node encodes - friends. They have been recorded elsewhere. */ - if ($$ == void_type_node) - $$ = $3; - else - $$ = chainon ($$, $3); + { + check_multiple_declarators (); + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $3 = finish_member_template_decl ($3); + finish_member_declaration ($3); + $$ = 2; } ; @@ -2531,65 +2598,47 @@ component_declarator: after_type_component_declarator0: after_type_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($0, ¤t_declspecs, - &prefix_attributes); - $0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } + { $$ = parse_field0 ($1, $0.t, $0.lookups, + $3, $2, $4); } | TYPENAME ':' expr_no_commas maybe_attribute - { split_specs_attrs ($0, ¤t_declspecs, - &prefix_attributes); - $0 = current_declspecs; - $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } + { $$ = parse_bitfield0 ($1, $0.t, $0.lookups, + $4, $3); } ; notype_component_declarator0: notype_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($0, ¤t_declspecs, - &prefix_attributes); - $0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } + { $$ = parse_field0 ($1, $0.t, $0.lookups, + $3, $2, $4); } | constructor_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($0, ¤t_declspecs, - &prefix_attributes); - $0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } + { $$ = parse_field0 ($1, $0.t, $0.lookups, + $3, $2, $4); } | IDENTIFIER ':' expr_no_commas maybe_attribute - { split_specs_attrs ($0, ¤t_declspecs, - &prefix_attributes); - $0 = current_declspecs; - $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } + { $$ = parse_bitfield0 ($1, $0.t, $0.lookups, + $4, $3); } | ':' expr_no_commas maybe_attribute - { split_specs_attrs ($0, ¤t_declspecs, - &prefix_attributes); - $0 = current_declspecs; - $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3, prefix_attributes); } + { $$ = parse_bitfield0 (NULL_TREE, $0.t, + $0.lookups, $3, $2); } ; after_type_component_declarator: after_type_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } + { $$ = parse_field ($1, $3, $2, $4); } | TYPENAME ':' expr_no_commas maybe_attribute - { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } + { $$ = parse_bitfield ($1, $4, $3); } ; notype_component_declarator: notype_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } + { $$ = parse_field ($1, $3, $2, $4); } | IDENTIFIER ':' expr_no_commas maybe_attribute - { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } + { $$ = parse_bitfield ($1, $4, $3); } | ':' expr_no_commas maybe_attribute - { $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3, prefix_attributes); } + { $$ = parse_bitfield (NULL_TREE, $3, $2); } + ; + +enumlist_opt: + enumlist maybecomma_warn + | maybecomma_warn ; /* We chain the enumerators in reverse order. @@ -2599,17 +2648,16 @@ notype_component_declarator: enumlist: enumerator | enumlist ',' enumerator - { TREE_CHAIN ($3) = $$; $$ = $3; } ; enumerator: identifier - { $$ = build_enumerator ($$, NULL_TREE); } + { build_enumerator ($1, NULL_TREE, current_enum_type); } | identifier '=' expr_no_commas - { $$ = build_enumerator ($$, $3); } + { build_enumerator ($1, $3, current_enum_type); } ; -/* ANSI new-type-id (5.3.4) */ +/* ISO new-type-id (5.3.4) */ new_type_id: type_specifier_seq new_declarator { $$.t = build_decl_list ($1.t, $2); @@ -2618,16 +2666,14 @@ new_type_id: { $$.t = build_decl_list ($1.t, NULL_TREE); $$.new_type_flag = $1.new_type_flag; } /* GNU extension to allow arrays of arbitrary types with - non-constant dimension. For the use of begin_new_placement - here, see the comments in unary_expr above. */ - | '(' .begin_new_placement type_id .finish_new_placement - '[' expr ']' + non-constant dimension. */ + | '(' type_id ')' '[' expr ']' { if (pedantic) - pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new"); - $$.t = build_parse_node (ARRAY_REF, TREE_VALUE ($3.t), $6); - $$.t = build_decl_list (TREE_PURPOSE ($3.t), $$.t); - $$.new_type_flag = $3.new_type_flag; + pedwarn ("ISO C++ forbids array dimensions with parenthesized type in new"); + $$.t = build_parse_node (ARRAY_REF, TREE_VALUE ($2.t), $5); + $$.t = build_decl_list (TREE_PURPOSE ($2.t), $$.t); + $$.new_type_flag = $2.new_type_flag; } ; @@ -2640,70 +2686,80 @@ cv_qualifiers: nonempty_cv_qualifiers: CV_QUALIFIER - { $$.t = IDENTIFIER_AS_LIST ($1); + { $$.t = hash_tree_cons (NULL_TREE, $1, NULL_TREE); $$.new_type_flag = 0; } | nonempty_cv_qualifiers CV_QUALIFIER - { $$.t = decl_tree_cons (NULL_TREE, $2, $1.t); + { $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); $$.new_type_flag = $1.new_type_flag; } ; /* These rules must follow the rules for function declarations and component declarations. That way, longer rules are preferred. */ -suspend_mom: - /* empty */ - { $$ = suspend_momentary (); } - -/* An expression which will not live on the momentary obstack. */ -nonmomentary_expr: - suspend_mom expr - { resume_momentary ((int) $1); $$ = $2; } - ; - /* An expression which will not live on the momentary obstack. */ maybe_parmlist: - suspend_mom '(' nonnull_exprlist ')' - { resume_momentary ((int) $1); $$ = $3; } - | suspend_mom '(' parmlist ')' - { resume_momentary ((int) $1); $$ = $3; } - | suspend_mom LEFT_RIGHT - { resume_momentary ((int) $1); $$ = empty_parms (); } - | suspend_mom '(' error ')' - { resume_momentary ((int) $1); $$ = NULL_TREE; } + '(' nonnull_exprlist ')' + { $$ = $2; } + | '(' parmlist ')' + { $$ = $2; } + | LEFT_RIGHT + { $$ = empty_parms (); } + | '(' error ')' + { $$ = NULL_TREE; } ; /* A declarator that is allowed only after an explicit typespec. */ + +after_type_declarator_intern: + after_type_declarator + | attributes after_type_declarator + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + /* may all be followed by prec '.' */ after_type_declarator: - '*' nonempty_cv_qualifiers after_type_declarator %prec UNARY + '*' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers after_type_declarator %prec UNARY + | '&' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY { $$ = make_reference_declarator ($2.t, $3); } - | '*' after_type_declarator %prec UNARY + | '*' after_type_declarator_intern %prec UNARY { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' after_type_declarator %prec UNARY + | '&' after_type_declarator_intern %prec UNARY { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers after_type_declarator + | ptr_to_mem cv_qualifiers after_type_declarator_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } | direct_after_type_declarator ; +direct_after_type_declarator: + direct_after_type_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' + { $$ = make_call_declarator ($$, $2, $3, $4); } + | direct_after_type_declarator '[' expr ']' + { $$ = build_parse_node (ARRAY_REF, $$, $3); } + | direct_after_type_declarator '[' ']' + { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } + | '(' after_type_declarator_intern ')' + { $$ = $2; } + | nested_name_specifier type_name %prec EMPTY + { push_nested_class ($1, 3); + $$ = build_parse_node (SCOPE_REF, $$, $2); + TREE_COMPLEXITY ($$) = current_class_depth; } + | type_name %prec EMPTY + ; + nonnested_type: type_name %prec EMPTY { if (TREE_CODE ($1) == IDENTIFIER_NODE) { $$ = lookup_name ($1, 1); - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ($1)) - { - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - pushdecl_class_level ($$); - } + maybe_note_name_used_in_class ($1, $$); } else $$ = $1; @@ -2730,35 +2786,29 @@ nested_type: { $$ = get_type_decl ($2); } ; -direct_after_type_declarator: - direct_after_type_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | direct_after_type_declarator '[' nonmomentary_expr ']' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - | direct_after_type_declarator '[' ']' - { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } - | '(' after_type_declarator ')' - { $$ = $2; } - | nested_name_specifier type_name %prec EMPTY - { push_nested_class ($1, 3); - $$ = build_parse_node (SCOPE_REF, $$, $2); - TREE_COMPLEXITY ($$) = current_class_depth; } - | type_name %prec EMPTY - ; - /* A declarator allowed whether or not there has been an explicit typespec. These cannot redeclare a typedef-name. */ +notype_declarator_intern: + notype_declarator + | attributes notype_declarator + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator %prec UNARY + '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator %prec UNARY + | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_reference_declarator ($2.t, $3); } - | '*' notype_declarator %prec UNARY + | '*' notype_declarator_intern %prec UNARY { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' notype_declarator %prec UNARY + | '&' notype_declarator_intern %prec UNARY { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator + | ptr_to_mem cv_qualifiers notype_declarator_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } @@ -2766,15 +2816,15 @@ notype_declarator: ; complex_notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator %prec UNARY + '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator %prec UNARY + | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_reference_declarator ($2.t, $3); } | '*' complex_notype_declarator %prec UNARY { $$ = make_pointer_declarator (NULL_TREE, $2); } | '&' complex_notype_declarator %prec UNARY { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator + | ptr_to_mem cv_qualifiers notype_declarator_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } @@ -2786,30 +2836,16 @@ complex_direct_notype_declarator: { $$ = make_call_declarator ($$, $2, $3, $4); } | '(' complex_notype_declarator ')' { $$ = $2; } - | direct_notype_declarator '[' nonmomentary_expr ']' + | direct_notype_declarator '[' expr ']' { $$ = build_parse_node (ARRAY_REF, $$, $3); } | direct_notype_declarator '[' ']' { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } | notype_qualified_id - { if (TREE_CODE (OP0 ($1)) == NAMESPACE_DECL) - { - push_decl_namespace (OP0 ($1)); - TREE_COMPLEXITY ($1) = -1; - } - else if (OP0 ($1) != current_class_type) - { - push_nested_class (OP0 ($1), 3); - TREE_COMPLEXITY ($1) = current_class_depth; - } - } + { enter_scope_of ($1); } | nested_name_specifier notype_template_declarator { got_scope = NULL_TREE; $$ = build_parse_node (SCOPE_REF, $1, $2); - if ($1 != current_class_type) - { - push_nested_class ($1, 3); - TREE_COMPLEXITY ($$) = current_class_depth; - } + enter_scope_of ($$); } ; @@ -2840,7 +2876,7 @@ overqualified_id: functional_cast: typespec '(' nonnull_exprlist ')' { $$ = build_functional_cast ($1.t, $3); } - | typespec '(' expr_or_declarator ')' + | typespec '(' expr_or_declarator_intern ')' { $$ = reparse_decl_as_expr ($1.t, $3); } | typespec fcast_or_absdcl %prec EMPTY { $$ = reparse_absdcl_as_expr ($1.t, $2); } @@ -2857,7 +2893,8 @@ nested_name_specifier: | nested_name_specifier nested_name_specifier_1 { $$ = $2; } | nested_name_specifier TEMPLATE explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $3); } + { got_scope = $$ + = make_typename_type ($1, $3, /*complain=*/1); } ; /* Why the @#$%^& do type_name and notype_identifier need to be expanded @@ -2868,14 +2905,10 @@ nested_name_specifier_1: if (TREE_CODE ($1) == IDENTIFIER_NODE) { $$ = lastiddecl; - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ($1)) - pushdecl_class_level ($$); + maybe_note_name_used_in_class ($1, $$); } - got_scope = $$ = TREE_TYPE ($$); + got_scope = $$ = + complete_type (TYPE_MAIN_VARIANT (TREE_TYPE ($$))); } | SELFNAME SCOPE { @@ -2913,7 +2946,7 @@ typename_sub0: typename_sub1 identifier %prec EMPTY { if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't') - $$ = make_typename_type ($1, $2); + $$ = make_typename_type ($1, $2, /*complain=*/1); else if (TREE_CODE ($2) == IDENTIFIER_NODE) cp_error ("`%T' is not a class or namespace", $2); else @@ -2926,9 +2959,9 @@ typename_sub0: | typename_sub1 template_type %prec EMPTY { $$ = TREE_TYPE ($2); } | typename_sub1 explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $2); } + { $$ = make_typename_type ($1, $2, /*complain=*/1); } | typename_sub1 TEMPLATE explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $3); } + { $$ = make_typename_type ($1, $3, /*complain=*/1); } ; typename_sub1: @@ -2940,7 +2973,7 @@ typename_sub1: | typename_sub1 typename_sub2 { if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't') - $$ = make_typename_type ($1, $2); + $$ = make_typename_type ($1, $2, /*complain=*/1); else if (TREE_CODE ($2) == IDENTIFIER_NODE) cp_error ("`%T' is not a class or namespace", $2); else @@ -2951,9 +2984,11 @@ typename_sub1: } } | typename_sub1 explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $2); } + { got_scope = $$ + = make_typename_type ($1, $2, /*complain=*/1); } | typename_sub1 TEMPLATE explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $3); } + { got_scope = $$ + = make_typename_type ($1, $3, /*complain=*/1); } ; typename_sub2: @@ -3020,7 +3055,7 @@ global_scope: { got_scope = void_type_node; } ; -/* ANSI new-declarator (5.3.4) */ +/* ISO new-declarator (5.3.4) */ new_declarator: '*' cv_qualifiers new_declarator { $$ = make_pointer_declarator ($2, $3); } @@ -3041,27 +3076,37 @@ new_declarator: | direct_new_declarator %prec EMPTY ; -/* ANSI direct-new-declarator (5.3.4) */ +/* ISO direct-new-declarator (5.3.4) */ direct_new_declarator: '[' expr ']' { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } - | direct_new_declarator '[' nonmomentary_expr ']' + | direct_new_declarator '[' expr ']' { $$ = build_parse_node (ARRAY_REF, $$, $3); } ; -/* ANSI abstract-declarator (8.1) */ +absdcl_intern: + absdcl + | attributes absdcl + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + +/* ISO abstract-declarator (8.1) */ absdcl: - '*' nonempty_cv_qualifiers absdcl + '*' nonempty_cv_qualifiers absdcl_intern { $$ = make_pointer_declarator ($2.t, $3); } - | '*' absdcl + | '*' absdcl_intern { $$ = make_pointer_declarator (NULL_TREE, $2); } | '*' nonempty_cv_qualifiers %prec EMPTY { $$ = make_pointer_declarator ($2.t, NULL_TREE); } | '*' %prec EMPTY { $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); } - | '&' nonempty_cv_qualifiers absdcl + | '&' nonempty_cv_qualifiers absdcl_intern { $$ = make_reference_declarator ($2.t, $3); } - | '&' absdcl + | '&' absdcl_intern { $$ = make_reference_declarator (NULL_TREE, $2); } | '&' nonempty_cv_qualifiers %prec EMPTY { $$ = make_reference_declarator ($2.t, NULL_TREE); } @@ -3071,24 +3116,23 @@ absdcl: { tree arg = make_pointer_declarator ($2, NULL_TREE); $$ = build_parse_node (SCOPE_REF, $1, arg); } - | ptr_to_mem cv_qualifiers absdcl + | ptr_to_mem cv_qualifiers absdcl_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } | direct_abstract_declarator %prec EMPTY ; -/* ANSI direct-abstract-declarator (8.1) */ +/* ISO direct-abstract-declarator (8.1) */ direct_abstract_declarator: - '(' absdcl ')' + '(' absdcl_intern ')' { $$ = $2; } /* `(typedef)1' is `int'. */ - | PAREN_STAR_PAREN | direct_abstract_declarator '(' parmlist ')' cv_qualifiers exception_specification_opt %prec '.' { $$ = make_call_declarator ($$, $3, $5, $6); } | direct_abstract_declarator LEFT_RIGHT cv_qualifiers exception_specification_opt %prec '.' { $$ = make_call_declarator ($$, empty_parms (), $3, $4); } - | direct_abstract_declarator '[' nonmomentary_expr ']' %prec '.' + | direct_abstract_declarator '[' expr ']' %prec '.' { $$ = build_parse_node (ARRAY_REF, $$, $3); } | direct_abstract_declarator '[' ']' %prec '.' { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } @@ -3098,7 +3142,7 @@ direct_abstract_declarator: { set_quals_and_spec ($$, $2, $3); } | fcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' { set_quals_and_spec ($$, $2, $3); } - | '[' nonmomentary_expr ']' %prec '.' + | '[' expr ']' %prec '.' { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } | '[' ']' %prec '.' { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); } @@ -3125,7 +3169,7 @@ maybe_label_decls: /* empty */ | label_decls { if (pedantic) - pedwarn ("ANSI C++ forbids label declarations"); } + pedwarn ("ISO C++ forbids label declarations"); } ; label_decls: @@ -3135,12 +3179,11 @@ label_decls: label_decl: LABEL identifiers_or_typenames ';' - { tree link; - for (link = $2; link; link = TREE_CHAIN (link)) + { + while ($2) { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); + finish_label_decl (TREE_VALUE ($2)); + $2 = TREE_CHAIN ($2); } } ; @@ -3228,11 +3271,11 @@ simple_stmt: already_scoped_stmt { finish_for_stmt ($9, $2); } | SWITCH - { begin_switch_stmt (); } + { $$ = begin_switch_stmt (); } '(' condition ')' - { $$ = finish_switch_cond ($4); } + { finish_switch_cond ($4, $2); } implicitly_scoped_stmt - { finish_switch_stmt ($4, $6); } + { finish_switch_stmt ($4, $2); } | CASE expr_no_commas ':' { finish_case_label ($2, NULL_TREE); } stmt @@ -3246,9 +3289,9 @@ simple_stmt: { finish_break_stmt (); } | CONTINUE ';' { finish_continue_stmt (); } - | RETURN ';' + | RETURN_KEYWORD ';' { finish_return_stmt (NULL_TREE); } - | RETURN expr ';' + | RETURN_KEYWORD expr ';' { finish_return_stmt ($2); } | asm_keyword maybe_cv_qualifier '(' string ')' ';' { @@ -3264,49 +3307,48 @@ simple_stmt: /* This is the case with input operands as well. */ | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' asm_operands ')' ';' { finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); } + | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ')' ';' + { finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); } /* This is the case with clobbered registers as well. */ | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' asm_operands ':' asm_clobbers ')' ';' { finish_asm_stmt ($2, $4, $6, $8, $10); } + | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ':' + asm_clobbers ')' ';' + { finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); } + | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands SCOPE + asm_clobbers ')' ';' + { finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); } | GOTO '*' expr ';' { if (pedantic) - pedwarn ("ANSI C++ forbids computed gotos"); + pedwarn ("ISO C++ forbids computed gotos"); finish_goto_stmt ($3); } | GOTO identifier ';' { finish_goto_stmt ($2); } | label_colon stmt - { finish_stmt (); } | label_colon '}' { error ("label must be followed by statement"); - yyungetc ('}', 0); - finish_stmt (); } + yyungetc ('}', 0); } | ';' { finish_stmt (); } | try_block | using_directive | namespace_using_decl { do_local_using_decl ($1); } + | namespace_alias ; function_try_block: TRY - { - if (! current_function_parms_stored) - store_parm_decls (); - expand_start_early_try_stmts (); - } + { $$ = begin_function_try_block (); } ctor_initializer_opt compstmt - { - expand_start_all_catch (); - } + { finish_function_try_block ($2); } handler_seq { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - expand_end_all_catch (); - finish_function (lineno, (int)$3, nested); + finish_function_handler_sequence ($2); + $$ = $3; } ; @@ -3328,9 +3370,9 @@ handler: CATCH { $$ = begin_handler(); } handler_args - { finish_handler_parms ($2); } + { $$ = finish_handler_parms ($3, $2); } compstmt - { finish_handler ($2); } + { finish_handler ($4, $2); } ; type_specifier_seq: @@ -3340,7 +3382,7 @@ type_specifier_seq: handler_args: '(' ELLIPSIS ')' - { expand_start_catch_block (NULL_TREE, NULL_TREE); } + { $$ = NULL_TREE; } /* This doesn't allow reference parameters, the below does. | '(' type_specifier_seq absdcl ')' { check_for_new_type ("inside exception declarations", $2); @@ -3356,34 +3398,31 @@ handler_args: expand_start_catch_block ($2.t, $3); } This allows reference parameters... */ | '(' parm ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block (TREE_PURPOSE ($2.t), - TREE_VALUE ($2.t)); } + { + check_for_new_type ("inside exception declarations", $2); + $$ = start_handler_parms (TREE_PURPOSE ($2.t), + TREE_VALUE ($2.t)); + } ; label_colon: IDENTIFIER ':' - { tree label; - do_label: - label = define_label (input_filename, lineno, $1); - if (label && ! minimal_parse_mode) - expand_label (label); - } + { finish_label_stmt ($1); } | PTYPENAME ':' - { goto do_label; } + { finish_label_stmt ($1); } | TYPENAME ':' - { goto do_label; } + { finish_label_stmt ($1); } | SELFNAME ':' - { goto do_label; } + { finish_label_stmt ($1); } ; for.init.statement: xexpr ';' - { if ($1) cplus_expand_expr_stmt ($1); } + { finish_expr_stmt ($1); } | decl | '{' compstmtend { if (pedantic) - pedwarn ("ANSI C++ forbids compound statements inside for initializations"); + pedwarn ("ISO C++ forbids compound statements inside for initializations"); } ; @@ -3391,10 +3430,8 @@ for.init.statement: maybe_cv_qualifier: /* empty */ - { emit_line_note (input_filename, lineno); - $$ = NULL_TREE; } + { $$ = NULL_TREE; } | CV_QUALIFIER - { emit_line_note (input_filename, lineno); } ; xexpr: @@ -3536,7 +3573,8 @@ named_parm: { $$.t = build_tree_list ($1.t, $2); $$.new_type_flag = $1.new_type_flag; } | typespec declarator - { $$.t = build_tree_list (get_decl_list ($1.t), $2); + { $$.t = build_tree_list (build_decl_list (NULL_TREE, $1.t), + $2); $$.new_type_flag = $1.new_type_flag; } | typed_declspecs1 absdcl { tree specs = strip_attrs ($1.t); @@ -3547,7 +3585,7 @@ named_parm: $$.t = build_tree_list (specs, NULL_TREE); $$.new_type_flag = $1.new_type_flag; } | declmods notype_declarator - { tree specs = strip_attrs ($1); + { tree specs = strip_attrs ($1.t); $$.t = build_tree_list (specs, $2); $$.new_type_flag = 0; } ; @@ -3594,21 +3632,22 @@ exception_specification_opt: | THROW '(' ansi_raise_identifiers ')' %prec EMPTY { $$ = $3; } | THROW LEFT_RIGHT %prec EMPTY - { $$ = build_decl_list (NULL_TREE, NULL_TREE); } + { $$ = empty_except_spec; } ; ansi_raise_identifier: type_id - { $$ = build_decl_list (NULL_TREE, groktypename($1.t)); } + { + check_for_new_type ("exception specifier", $1); + $$ = groktypename ($1.t); + } ; ansi_raise_identifiers: ansi_raise_identifier + { $$ = add_exception_specifier (NULL_TREE, $1, 1); } | ansi_raise_identifiers ',' ansi_raise_identifier - { - TREE_CHAIN ($3) = $$; - $$ = $3; - } + { $$ = add_exception_specifier ($1, $3, 1); } ; conversion_declarator: