diff options
Diffstat (limited to 'contrib/gcc/cp/parse.y')
-rw-r--r-- | contrib/gcc/cp/parse.y | 842 |
1 files changed, 454 insertions, 388 deletions
diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y index 279cec3..7b5d3bd 100644 --- a/contrib/gcc/cp/parse.y +++ b/contrib/gcc/cp/parse.y @@ -1,5 +1,5 @@ /* YACC parser for C++ syntax. - Copyright (C) 1988, 89, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 89, 93-98, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -60,9 +60,10 @@ 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 const char *cond_stmt_keyword; static tree empty_parms PROTO((void)); +static int parse_decl PROTO((tree, tree, tree, int, tree *)); /* Nonzero if we have an `extern "C"' acting as an extern specifier. */ int have_extern_spec; @@ -130,7 +131,7 @@ 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 @@ -203,11 +204,12 @@ empty_parms () %type <ttype> compstmt implicitly_scoped_stmt %type <ttype> declarator notype_declarator after_type_declarator +%type <ttype> notype_declarator_intern absdcl_intern +%type <ttype> after_type_declarator_intern %type <ttype> direct_notype_declarator direct_after_type_declarator - -%type <ttype> opt.component_decl_list component_decl_list -%type <ttype> component_decl component_decl_1 components notype_components -%type <ttype> component_declarator component_declarator0 self_reference +%type <itype> components notype_components +%type <ttype> component_decl component_decl_1 +%type <ttype> component_declarator component_declarator0 %type <ttype> notype_component_declarator notype_component_declarator0 %type <ttype> after_type_component_declarator after_type_component_declarator0 %type <ttype> enumlist enumerator @@ -217,7 +219,8 @@ empty_parms () %type <ttype> xexpr parmlist parms bad_parm %type <ttype> identifiers_or_typenames %type <ttype> fcast_or_absdcl regcast_or_absdcl -%type <ttype> expr_or_declarator complex_notype_declarator +%type <ttype> expr_or_declarator expr_or_declarator_intern +%type <ttype> complex_notype_declarator %type <ttype> notype_unqualified_id unqualified_id qualified_id %type <ttype> template_id do_id object_template_id notype_template_declarator %type <ttype> overqualified_id notype_qualified_id any_id @@ -235,11 +238,12 @@ empty_parms () %token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER %type <ttype> component_constructor_declarator %type <ttype> fn.def2 return_id fn.defpen constructor_declarator -%type <itype> ctor_initializer_opt -%type <ttype> named_class_head named_class_head_sans_basetype -%type <ttype> named_complex_class_head_sans_basetype +%type <itype> ctor_initializer_opt function_try_block +%type <ttype> named_class_head_sans_basetype +%type <ftype> class_head named_class_head +%type <ftype> named_complex_class_head_sans_basetype %type <ttype> unnamed_class_head -%type <ttype> class_head base_class_list +%type <ttype> base_class_list %type <ttype> base_class_access_list %type <ttype> base_class maybe_base_class_list base_class.1 %type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers @@ -252,6 +256,7 @@ empty_parms () %type <ttype> template_header template_parm_list template_parm %type <ttype> template_type_parm template_template_parm %type <code> template_close_bracket +%type <ttype> apparent_template_type %type <ttype> template_type template_arg_list template_arg_list_opt %type <ttype> template_arg %type <ttype> condition xcond paren_cond_or_null @@ -267,7 +272,7 @@ empty_parms () %type <ttype> named_class_head_sans_basetype_defn %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN -%type <ttype> self_template_type +%type <ttype> self_template_type .finish_template_type %token NSNAME %type <ttype> NSNAME @@ -290,9 +295,13 @@ static tree current_declspecs; a declspec list have been updated. */ static tree prefix_attributes; -/* When defining an aggregate, this is the most recent one being defined. */ +/* 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; + /* Tell yyparse how to print a token's value, if yydebug is set. */ #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) @@ -312,7 +321,7 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl) 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); + current_declspecs = build_decl_list (NULL_TREE, current_declspecs); if (have_extern_spec && !used_extern_spec) { current_declspecs = decl_tree_cons (NULL_TREE, @@ -556,22 +565,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 = $<itype>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: @@ -579,9 +604,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 ';' @@ -619,7 +642,11 @@ fndef: fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error { finish_function (lineno, (int)$3, 0); } | fn.def1 maybe_return_init function_try_block - { } + { + int nested = (hack_decl_function_context + (current_function_decl) != NULL_TREE); + finish_function (lineno, (int)$3, nested); + } | fn.def1 maybe_return_init error { } ; @@ -692,8 +719,10 @@ 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); + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); rest_of_mdef: if (! $$) YYERROR1; @@ -701,24 +730,33 @@ fn.def2: yychar = YYLEX; reinit_parse_for_method (yychar, $$); } | component_constructor_declarator - { $$ = start_method (NULL_TREE, $1); goto rest_of_mdef; } + { $$ = start_method (NULL_TREE, $1, NULL_TREE); + goto rest_of_mdef; } | typed_declspecs declarator - { tree specs = strip_attrs ($1.t); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { tree specs, attrs; + split_specs_attrs ($1.t, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } | declmods notype_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } | notype_declarator - { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } + { $$ = start_method (NULL_TREE, $$, NULL_TREE); + goto rest_of_mdef; } | declmods constructor_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } | constructor_declarator - { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } + { $$ = start_method (NULL_TREE, $$, NULL_TREE); + goto rest_of_mdef; } ; return_id: - RETURN IDENTIFIER + RETURN_KEYWORD IDENTIFIER { if (! current_function_parms_stored) store_parm_decls (); @@ -870,29 +908,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 ($<ttype>-3, $<ttype>-1, + yychar == SCOPE); + } + template_close_bracket: '>' | RSHIFT @@ -1056,7 +1100,8 @@ unary_expr: | 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 @@ -1265,6 +1310,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 @@ -1273,7 +1320,16 @@ notype_unqualified_id: ; do_id: - { $$ = do_identifier ($<ttype>-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<int>, so + don't do_identifier; we only do that for unqualified + identifiers. */ + if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST) + $$ = do_identifier ($<ttype>-1, 1, NULL_TREE); + else + $$ = $<ttype>-1; + } template_id: PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket @@ -1298,13 +1354,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; } ; @@ -1321,8 +1387,8 @@ direct_notype_declarator: 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: @@ -1340,18 +1406,25 @@ primary: if (processing_template_decl) push_obstacks (&permanent_obstack, &permanent_obstack); $$ = combine_strings ($$); + /* 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 ($$))); if (processing_template_decl) pop_obstacks (); } | '(' 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; @@ -1384,47 +1457,20 @@ 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 = cp_build_qualified_type (integer_type_node, + cp_type_qual_from_rid ($1)); + $$ = build_c_cast (type, build_compound_expr ($3)); } | functional_cast | DYNAMIC_CAST '<' type_id '>' '(' expr ')' @@ -1464,9 +1510,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); @@ -1642,7 +1688,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); @@ -1708,24 +1755,33 @@ 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; } | SCSPEC - { $$ = IDENTIFIER_AS_LIST ($$); } + { $$ = hash_tree_cons (NULL_TREE, $$, NULL_TREE); } | declmods CV_QUALIFIER - { $$ = decl_tree_cons (NULL_TREE, $2, $$); + { $$ = hash_tree_cons (NULL_TREE, $2, $$); TREE_STATIC ($$) = 1; } | declmods SCSPEC { if (extra_warnings && TREE_STATIC ($$)) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); - $$ = decl_tree_cons (NULL_TREE, $2, $$); + $$ = hash_tree_cons (NULL_TREE, $2, $$); TREE_STATIC ($$) = TREE_STATIC ($1); } | declmods attributes - { $$ = decl_tree_cons ($2, NULL_TREE, $1); } - | attributes - { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } + { $$ = hash_tree_cons ($2, NULL_TREE, $1); } + | attributes %prec EMPTY + { $$ = hash_tree_cons ($1, NULL_TREE, NULL_TREE); } ; /* Used instead of declspecs where storage classes are not allowed @@ -1736,7 +1792,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); @@ -1767,7 +1823,7 @@ typespec: | complete_type_name { $$.t = $1; $$.new_type_flag = 0; } | TYPEOF '(' expr ')' - { $$.t = TREE_TYPE ($3); + { $$.t = finish_typeof ($3); $$.new_type_flag = 0; } | TYPEOF '(' type_id ')' { $$.t = groktypename ($3.t); @@ -1817,16 +1873,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: @@ -1995,7 +2054,7 @@ initlist: fn.defpen: PRE_PARSED_FUNCTION_DECL { start_function (NULL_TREE, TREE_VALUE ($1), - NULL_TREE, 1); + NULL_TREE, 2); reinit_parse_for_function (); } pending_inline: @@ -2003,11 +2062,16 @@ pending_inline: { int nested = (hack_decl_function_context (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3, nested); + finish_function (lineno, (int)$3 | 2, nested); process_next_inline ($1); } | fn.defpen maybe_return_init function_try_block - { process_next_inline ($1); } + { + int nested = (hack_decl_function_context + (current_function_decl) != NULL_TREE); + finish_function (lineno, (int)$3 | 2, nested); + process_next_inline ($1); + } | fn.defpen maybe_return_init error { process_next_inline ($1); } ; @@ -2036,39 +2100,48 @@ pending_defargs: structsp: ENUM identifier '{' { $<itype>3 = suspend_momentary (); - $<ttype>$ = start_enum ($2); } + $<ttype>$ = current_enum_type; + current_enum_type = start_enum ($2); } enumlist maybecomma_warn '}' - { $$.t = finish_enum ($<ttype>4, $5); + { TYPE_VALUES (current_enum_type) = $5; + $$.t = finish_enum (current_enum_type); $$.new_type_flag = 1; + current_enum_type = $<ttype>4; resume_momentary ((int) $<itype>3); - check_for_missing_semicolon ($<ttype>4); } + check_for_missing_semicolon ($$.t); } | ENUM identifier '{' '}' - { $$.t = finish_enum (start_enum ($2), NULL_TREE); + { $$.t = finish_enum (start_enum ($2)); $$.new_type_flag = 1; check_for_missing_semicolon ($$.t); } | ENUM '{' { $<itype>2 = suspend_momentary (); - $<ttype>$ = start_enum (make_anon_name ()); } + $<ttype>$ = current_enum_type; + current_enum_type = start_enum (make_anon_name ()); } enumlist maybecomma_warn '}' - { $$.t = finish_enum ($<ttype>3, $4); + { TYPE_VALUES (current_enum_type) = $4; + $$.t = finish_enum (current_enum_type); + $$.new_type_flag = 1; + current_enum_type = $<ttype>3; resume_momentary ((int) $<itype>1); - check_for_missing_semicolon ($<ttype>3); - $$.new_type_flag = 1; } + check_for_missing_semicolon ($$.t); } | ENUM '{' '}' - { $$.t = finish_enum (start_enum (make_anon_name()), NULL_TREE); + { $$.t = finish_enum (start_enum (make_anon_name())); $$.new_type_flag = 1; 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; @@ -2077,25 +2150,32 @@ structsp: yychar = YYLEX; semi = yychar == ';'; - $<ttype>$ = finish_class_definition ($1, $3, $5, semi); + $<ttype>$ = finish_class_definition ($1.t, $6, semi, + $1.new_type_flag); } pending_defargs - { finish_default_args (); } + { + begin_inline_definitions (); + } pending_inlines - { $$.t = $<ttype>6; + { + finish_inline_definitions (); + $$.t = $<ttype>7; $$.new_type_flag = 1; - begin_inline_definitions (); } + } | class_head %prec EMPTY { + if ($1.new_type_flag) + pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL ($1.t))); $$.new_type_flag = 0; - if (TYPE_BINFO ($1) == NULL_TREE) + 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; + $$.t = $1.t; /* struct B: public A; is not accepted by the WP grammar. */ if (TYPE_BINFO_BASETYPES ($$.t) && !TYPE_SIZE ($$.t) && ! TYPE_BEING_DEFINED ($$.t)) @@ -2133,7 +2213,10 @@ aggr: named_class_head_sans_basetype: aggr identifier - { current_aggr = $$; $$ = $2; } + { + current_aggr = $1; + $$ = $2; + } ; named_class_head_sans_basetype_defn: @@ -2149,75 +2232,98 @@ 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 - { $<ttype>$ = xref_tag (current_aggr, $<ttype>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 + { $<ttype>$ = 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 { - $$ = $<ttype>2; + $$.t = $<ttype>2; + $$.new_type_flag = 0; if ($3) xref_basetypes (current_aggr, $1, $<ttype>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 ; @@ -2238,76 +2344,18 @@ base_class_list: base_class: base_class.1 - { - tree type; - if ($1 == NULL_TREE) - { - error ("invalid base class"); - type = error_mark_node; - } - else - 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, + current_aggr + == signature_type_node); } | base_class_access_list see_typename base_class.1 - { - tree type; - if ($3 == NULL_TREE) - { - error ("invalid base class"); - type = error_mark_node; - } - else - 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, + current_aggr + == signature_type_node); } ; base_class.1: typename_sub - { $$ = TYPE_MAIN_DECL ($1); } + { if ($$ != error_mark_node) $$ = TYPE_MAIN_DECL ($1); } | nonnested_type | SIGOF '(' expr ')' { @@ -2384,71 +2432,40 @@ base_class_access_list: } ; -left_curly: - '{' - { $<ttype>0 = begin_class_definition ($<ttype>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 + ; +access_specifier: + VISSPEC ':' + { if (current_aggr == signature_type_node) { error ("access specifier not allowed in signature"); - visspec = access_public_node; + $1 = 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"); - } + + 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); } @@ -2458,7 +2475,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 ($$); } @@ -2468,9 +2485,20 @@ component_decl: { $$ = $2; pedantic = $<itype>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: @@ -2478,9 +2506,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); + $$ = NULL_TREE; + } | notype_declarator maybeasm maybe_attribute maybe_init { $$ = grokfield ($$, NULL_TREE, $4, $2, build_tree_list ($3, NULL_TREE)); } @@ -2515,31 +2566,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; } ; @@ -2628,9 +2689,9 @@ enumlist: enumerator: identifier - { $$ = build_enumerator ($$, NULL_TREE); } + { $$ = build_enumerator ($$, NULL_TREE, current_enum_type); } | identifier '=' expr_no_commas - { $$ = build_enumerator ($$, $3); } + { $$ = build_enumerator ($$, $3, current_enum_type); } ; /* ANSI new-type-id (5.3.4) */ @@ -2664,10 +2725,10 @@ 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; } ; @@ -2697,37 +2758,57 @@ maybe_parmlist: ; /* 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 '[' nonmomentary_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; @@ -2754,35 +2835,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); } @@ -2790,15 +2865,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); } @@ -2815,25 +2890,11 @@ complex_direct_notype_declarator: | 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 ($$); } ; @@ -2864,12 +2925,11 @@ 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); } ; - type_name: TYPENAME | SELFNAME @@ -2892,14 +2952,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 = $$ = TYPE_MAIN_VARIANT (TREE_TYPE ($$)); + got_scope = $$ = + complete_type (TYPE_MAIN_VARIANT (TREE_TYPE ($$))); } | SELFNAME SCOPE { @@ -3073,19 +3129,29 @@ direct_new_declarator: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ; +absdcl_intern: + absdcl + | attributes absdcl + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + /* ANSI 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); } @@ -3095,7 +3161,7 @@ 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); } @@ -3104,7 +3170,7 @@ absdcl: /* ANSI direct-abstract-declarator (8.1) */ direct_abstract_declarator: - '(' absdcl ')' + '(' absdcl_intern ')' { $$ = $2; } /* `(typedef)1' is `int'. */ | PAREN_STAR_PAREN @@ -3270,9 +3336,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 ')' ';' { @@ -3324,14 +3390,13 @@ function_try_block: } ctor_initializer_opt compstmt { + end_protect_partials (); expand_start_all_catch (); } handler_seq { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); expand_end_all_catch (); - finish_function (lineno, (int)$3, nested); + $$ = $3; } ; @@ -3561,7 +3626,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); |