--- gcc/cp/parse.y 2018/04/24 18:20:21 1.1.1.1 +++ gcc/cp/parse.y 2018/04/24 18:27:10 1.1.1.2 @@ -1,5 +1,5 @@ /* YACC parser for C++ syntax. - Copyright (C) 1988, 1989, 1993 Free Software Foundation, Inc. + Copyright (C) 1988, 1989, 1993, 1994, 1995 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -16,7 +16,8 @@ GNU General Public License for more deta You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* This grammar is based on the GNU CC grammar. */ @@ -25,20 +26,6 @@ the Free Software Foundation, 675 Mass A all derivations; this is applied before the explicit action, if one is given. Keep this in mind when reading the actions. */ -/* Also note: this version contains experimental exception - handling features. They could break, change, disappear, - or otherwise exhibit volatile behavior. Don't depend on - me (Michael Tiemann) to protect you from any negative impact - this may have on your professional, personal, or spiritual life. - - NEWS FLASH: This version now supports the exception handling - syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given. - THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the - 'catch' much match EXACTLY (no inheritance support or coercions). - Also, throw-specifications of functions don't work. - Destructors aren't called correctly. Etc, etc. --Per Bothner. - */ - %{ /* Cause the `yydebug' variable to be defined. */ #define YYDEBUG 1 @@ -53,6 +40,7 @@ the Free Software Foundation, 675 Mass A #include "flags.h" #include "lex.h" #include "cp-tree.h" +#include "output.h" /* Since parsers are distinct for each language, put the language string definition here. (fnf) */ @@ -68,6 +56,10 @@ extern int errno; extern int end_of_file; extern int current_class_depth; +/* FSF LOCAL dje prefix attributes */ +extern tree strip_attrs PROTO((tree)); +/* END FSF LOCAL */ + void yyerror (); /* Like YYERROR but do call yyerror. */ @@ -143,13 +135,14 @@ empty_parms () /* 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 GCC_ASM_KEYWORD TYPEOF ALIGNOF -%token HEADOF CLASSOF SIGOF +%token SIGOF %token ATTRIBUTE EXTENSION LABEL /* the reserved words... C++ extensions */ %token AGGR %token VISSPEC %token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE +%token NAMESPACE TYPENAME_KEYWORD USING %token LEFT_RIGHT TEMPLATE %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST %token SCOPE @@ -166,12 +159,14 @@ empty_parms () %nonassoc IF %nonassoc ELSE -%left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR +%left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD %left '{' ',' ';' +%nonassoc THROW +%right ':' %right ASSIGN '=' -%right '?' ':' +%right '?' %left OROR %left ANDAND %left '|' @@ -190,7 +185,7 @@ empty_parms () %left POINTSAT '.' '(' '[' %right SCOPE /* C++ extension */ -%nonassoc NEW DELETE TRY CATCH THROW +%nonassoc NEW DELETE TRY CATCH %type unop @@ -202,7 +197,7 @@ empty_parms () %type declmods typespec typespecqual_reserved %type SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual %type initdecls notype_initdecls initdcl /* C++ modification */ -%type init initlist maybeasm +%type init initlist maybeasm maybe_init %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attributes attribute attribute_list attrib %type any_word @@ -213,20 +208,20 @@ empty_parms () %type direct_notype_declarator direct_after_type_declarator %type structsp opt.component_decl_list component_decl_list -%type component_decl components component_declarator -%type notype_components notype_component_declarator +%type component_decl component_decl_1 components notype_components +%type component_declarator component_declarator0 +%type notype_component_declarator notype_component_declarator0 %type after_type_component_declarator after_type_component_declarator0 -%type notype_component_declarator0 component_decl_1 %type enumlist enumerator %type type_id absdcl type_quals %type direct_abstract_declarator conversion_declarator %type new_type_id new_declarator direct_new_declarator %type xexpr parmlist parms parm bad_parm full_parm %type identifiers_or_typenames -%type fcast_or_absdcl regcast_or_absdcl sub_cast_expr +%type fcast_or_absdcl regcast_or_absdcl %type expr_or_declarator complex_notype_declarator %type notype_unqualified_id unqualified_id qualified_id -%type overqualified_id notype_qualified_id +%type overqualified_id notype_qualified_id any_id %type complex_direct_notype_declarator functional_cast %type named_parm complex_parmlist typed_declspecs1 parms_comma @@ -236,19 +231,20 @@ empty_parms () %token PRE_PARSED_CLASS_DECL %type fn.def1 /* Not really! */ %type fn.def2 return_id +%type ctor_initializer_opt %type named_class_head named_class_head_sans_basetype +%type named_complex_class_head_sans_basetype %type unnamed_class_head %type class_head base_class_list %type base_class_access_list %type base_class maybe_base_class_list base_class.1 -%type maybe_raises ansi_raise_identifier ansi_raise_identifiers -%type component_declarator0 -%type forhead.1 operator_name +%type exception_specification_opt ansi_raise_identifier ansi_raise_identifiers +%type operator_name %type object aggr %type new delete /* %type primary_no_id */ -%type nonmomentary_expr -%type forhead.2 initdcl0 notype_initdcl0 member_init_list +%type nonmomentary_expr maybe_parmlist +%type initdcl0 notype_initdcl0 member_init_list %type template_header template_parm_list template_parm %type template_type_parm %type template_type template_arg_list template_arg @@ -262,21 +258,32 @@ empty_parms () %type complex_type_name nested_name_specifier_1 %type nomods_initdecls nomods_initdcl0 %type new_initializer new_placement specialization type_specifier_seq +%type using_decl .poplevel /* in order to recognize aggr tags as defining and thus shadowing. */ %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN %type named_class_head_sans_basetype_defn %type identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN -%type .pushlevel +%token NSNAME +%type NSNAME -/* spew.c depends on this being the last token. Define +/* Used in lex.c for parsing pragmas. */ +%token END_OF_LINE + +/* lex.c and pt.c depends on this being the last token. Define any new tokens before this one! */ %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; @@ -311,6 +318,11 @@ extdefs: { $$ = NULL_TREE; } ; +extdefs_opt: + extdefs + | /* empty */ + ; + .hush_warning: { have_extern_spec = 1; used_extern_spec = 0; @@ -328,7 +340,7 @@ asm_keyword: lang_extdef: { if (pending_lang_change) do_pending_lang_change(); } extdef - { if (! global_bindings_p () && ! pseudo_global_level_p()) + { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) pop_everything (); } ; @@ -343,9 +355,7 @@ extdef: | asm_keyword '(' string ')' ';' { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); assemble_asm ($3); } - | extern_lang_string '{' extdefs '}' - { pop_lang_context (); } - | extern_lang_string '{' '}' + | extern_lang_string '{' extdefs_opt '}' { pop_lang_context (); } | extern_lang_string .hush_warning fndef .warning_ok { if (pending_inlines) do_pending_inlines (); @@ -353,11 +363,47 @@ extdef: | extern_lang_string .hush_warning datadef .warning_ok { if (pending_inlines) do_pending_inlines (); pop_lang_context (); } + | NAMESPACE identifier '{' + { push_namespace ($2); } + extdefs_opt '}' + { pop_namespace (); } + | NAMESPACE '{' + { push_namespace (NULL_TREE); } + extdefs_opt '}' + { pop_namespace (); } + | NAMESPACE identifier '=' any_id ';' + { do_namespace_alias ($2, $4); } + | using_decl ';' + { do_toplevel_using_decl ($1); } + | USING NAMESPACE any_id ';' + { do_using_directive ($3); } + ; + +using_decl: + USING qualified_id + { $$ = $2; } + | USING global_scope qualified_id + { $$ = $3; } + | USING global_scope unqualified_id + { $$ = $3; } + ; + +any_id: + unqualified_id + | qualified_id + | global_scope qualified_id + { $$ = $2; } + | global_scope unqualified_id + { $$ = $2; } ; extern_lang_string: - EXTERN_LANG_STRING + EXTERN_LANG_STRING { push_lang_context ($1); } + | extern_lang_string EXTERN_LANG_STRING + { if (current_lang_name != $2) + cp_error ("use of linkage spec `%D' is different from previous spec `%D'", $2, current_lang_name); + pop_lang_context (); push_lang_context ($2); } ; template_header: @@ -386,6 +432,10 @@ template_type_parm: } | aggr identifier { $$ = build_tree_list ($1, $2); goto ttpa; } + | TYPENAME_KEYWORD + { $$ = build_tree_list (class_type_node, NULL_TREE); } + | TYPENAME_KEYWORD identifier + { $$ = build_tree_list (class_type_node, $2); } ; template_parm: @@ -430,9 +480,7 @@ template_def: { yychar = ':'; template1: - if (current_aggr == exception_type_node) - error ("template type must define an aggregate or union"); - else if (current_aggr == signature_type_node) + if (current_aggr == signature_type_node) sorry ("template type defining a signature"); /* Maybe pedantic warning for union? How about an enum? :-) */ @@ -452,7 +500,7 @@ template_def: /* declare $2 as template name with $1 parm list */ } | template_header /* notype_initdcl0 ';' */ - notype_declarator maybe_raises maybeasm maybe_attribute + notype_declarator exception_specification_opt maybeasm maybe_attribute fn_tmpl_end { tree d; @@ -461,27 +509,25 @@ template_def: momentary = suspend_momentary (); d = start_decl ($2, /*current_declspecs*/NULL_TREE, 0, $3); - cplus_decl_attributes (d, $5); - finish_decl (d, NULL_TREE, $4, 0); + cplus_decl_attributes (d, $5, /*prefix_attributes*/NULL_TREE); + cp_finish_decl (d, NULL_TREE, $4, 0, 0); end_template_decl ($1, d, 0, def); if (def) reinit_parse_for_template ((int) $6, $1, d); resume_momentary (momentary); } | template_header typed_declspecs /*initdcl0*/ - declarator maybe_raises maybeasm maybe_attribute + declarator exception_specification_opt maybeasm maybe_attribute fn_tmpl_end { - tree d; + tree d, specs, attrs; int momentary; int def = ($7 != ';'); - - current_declspecs = $2; + split_specs_attrs ($2, &specs, &attrs); momentary = suspend_momentary (); - d = start_decl ($3, current_declspecs, - 0, $4); - cplus_decl_attributes (d, $6); - finish_decl (d, NULL_TREE, $5, 0); + d = start_decl ($3, specs, 0, $4); + cplus_decl_attributes (d, $6, attrs); + cp_finish_decl (d, NULL_TREE, $5, 0, 0); end_template_decl ($1, d, 0, def); if (def) { @@ -493,9 +539,12 @@ template_def: } | template_header declmods notype_declarator fn_tmpl_end { + tree d, specs, attrs; int def = ($4 != ';'); - tree d = start_decl ($3, $2, 0, NULL_TREE); - finish_decl (d, NULL_TREE, NULL_TREE, 0); + split_specs_attrs ($2, &specs, &attrs); + d = start_decl ($3, specs, 0, NULL_TREE); + cplus_decl_attributes (d, NULL_TREE, attrs); + cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); end_template_decl ($1, d, 0, def); if (def) reinit_parse_for_template ((int) $4, $1, d); @@ -519,9 +568,11 @@ datadef: {} /* Normal case to make fast: "const i;". */ | declmods notype_declarator ';' - { tree d; - d = start_decl ($2, $$, 0, NULL_TREE); - finish_decl (d, NULL_TREE, NULL_TREE, 0); + { tree d, specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + d = start_decl ($2, specs, 0, NULL_TREE); + cplus_decl_attributes (d, NULL_TREE, attrs); + cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); } | typed_declspecs initdecls ';' { @@ -529,9 +580,11 @@ datadef: } /* Normal case: make this fast. */ | typed_declspecs declarator ';' - { tree d; - d = start_decl ($2, $$, 0, NULL_TREE); - finish_decl (d, NULL_TREE, NULL_TREE, 0); + { tree d, specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + d = start_decl ($2, specs, 0, NULL_TREE); + cplus_decl_attributes (d, NULL_TREE, attrs); + cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); note_list_got_semicolon ($$); } | declmods ';' @@ -539,7 +592,8 @@ datadef: | explicit_instantiation ';' | typed_declspecs ';' { - tree t = $$; + tree t, attrs; + split_specs_attrs ($1, &t, &attrs); shadow_tag (t); if (TREE_CODE (t) == TREE_LIST && TREE_PURPOSE (t) == NULL_TREE) @@ -561,42 +615,35 @@ datadef: | ';' ; -fndef: - fn.def1 base_init compstmt_or_error - { - finish_function (lineno, 1); - /* finish_function performs these three statements: +ctor_initializer_opt: + nodecls + { $$ = 0; } + | base_init + { $$ = 1; } + ; + +maybe_return_init: + /* empty */ + | return_init + | return_init ';' + ; - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 1, 0); +eat_saved_input: + /* empty */ + | END_OF_SAVED_INPUT + ; - expand_end_bindings (0, 0, 0); - poplevel (0, 0, 1); - */ +fndef: + fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error + { + finish_function (lineno, (int)$3, 0); if ($$) process_next_inline ($$); } - | fn.def1 return_init base_init compstmt_or_error + | fn.def1 maybe_return_init function_try_block { - finish_function (lineno, 1); - /* finish_function performs these three statements: - - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 1, 0); - - expand_end_bindings (0, 0, 0); - poplevel (0, 0, 1); - */ if ($$) process_next_inline ($$); } - | fn.def1 nodecls compstmt_or_error - { finish_function (lineno, 0); - if ($$) process_next_inline ($$); } - | fn.def1 return_init ';' nodecls compstmt_or_error - { finish_function (lineno, 0); - if ($$) process_next_inline ($$); } - | fn.def1 return_init nodecls compstmt_or_error - { finish_function (lineno, 0); - if ($$) process_next_inline ($$); } + eat_saved_input | typed_declspecs declarator error {} | declmods notype_declarator error @@ -606,51 +653,57 @@ fndef: ; fn.def1: - typed_declspecs declarator maybe_raises - { if (! start_function ($$, $2, $3, 0)) + typed_declspecs declarator exception_specification_opt + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + if (! start_function (specs, $2, $3, attrs, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } - | declmods notype_declarator maybe_raises - { if (! start_function ($$, $2, $3, 0)) + | declmods notype_declarator exception_specification_opt + { tree specs = strip_attrs ($1); + if (! start_function (specs, $2, $3, NULL_TREE, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } - | notype_declarator maybe_raises - { if (! start_function (NULL_TREE, $$, $2, 0)) + | notype_declarator exception_specification_opt + { if (! start_function (NULL_TREE, $$, $2, NULL_TREE, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } | PRE_PARSED_FUNCTION_DECL - { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1); + { start_function (NULL_TREE, TREE_VALUE ($$), + NULL_TREE, NULL_TREE, 1); reinit_parse_for_function (); } ; /* more C++ complexity. See component_decl for a comment on the reduce/reduce conflict introduced by these rules. */ fn.def2: - typed_declspecs '(' parmlist ')' type_quals maybe_raises - { - $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5); - $$ = start_method (TREE_CHAIN ($1), $$, $6); + typed_declspecs '(' parmlist ')' type_quals exception_specification_opt + { tree specs = strip_attrs ($1); + $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), $3, $5); + $$ = start_method (TREE_CHAIN (specs), $$, $6); rest_of_mdef: if (! $$) YYERROR1; if (yychar == YYEMPTY) yychar = YYLEX; reinit_parse_for_method (yychar, $$); } - | typed_declspecs LEFT_RIGHT type_quals maybe_raises - { - $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), + | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt + { tree specs = strip_attrs ($1); + $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), empty_parms (), $3); - $$ = start_method (TREE_CHAIN ($1), $$, $4); + $$ = start_method (TREE_CHAIN (specs), $$, $4); goto rest_of_mdef; } - | typed_declspecs declarator maybe_raises - { $$ = start_method ($$, $2, $3); goto rest_of_mdef; } - | declmods notype_declarator maybe_raises - { $$ = start_method ($$, $2, $3); goto rest_of_mdef; } - | notype_declarator maybe_raises + | typed_declspecs declarator exception_specification_opt + { tree specs = strip_attrs ($1); + $$ = start_method (specs, $2, $3); goto rest_of_mdef; } + | declmods notype_declarator exception_specification_opt + { tree specs = strip_attrs ($1); + $$ = start_method (specs, $2, $3); goto rest_of_mdef; } + | notype_declarator exception_specification_opt { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; } ; @@ -662,10 +715,8 @@ return_id: RETURN IDENTIFIER } ; -return_init: return_id - { store_return_init ($$, NULL_TREE); } - | return_id '=' init - { store_return_init ($$, $3); } +return_init: return_id maybe_init + { store_return_init ($$, $2); } | return_id '(' nonnull_exprlist ')' { store_return_init ($$, $3); } | return_id LEFT_RIGHT @@ -691,9 +742,6 @@ base_init: if (! current_function_parms_stored) store_parm_decls (); - /* Flag that we are processing base and member initializers. */ - current_vtable_decl = error_mark_node; - if (DECL_CONSTRUCTOR_P (current_function_decl)) { /* Make a contour for the initializer list. */ @@ -752,11 +800,13 @@ identifier: IDENTIFIER | TYPENAME | PTYPENAME + | NSNAME ; notype_identifier: IDENTIFIER - | PTYPENAME %prec EMPTY + | PTYPENAME + | NSNAME %prec EMPTY ; identifier_defn: @@ -769,11 +819,17 @@ explicit_instantiation: TEMPLATE specialization template_instantiation { do_type_instantiation ($3 ? $3 : $2, NULL_TREE); } | TEMPLATE typed_declspecs declarator - { do_function_instantiation ($2, $3, NULL_TREE); } + { tree specs = strip_attrs ($2); + do_function_instantiation (specs, $3, NULL_TREE); } + | TEMPLATE notype_declarator + { do_function_instantiation (NULL_TREE, $2, NULL_TREE); } | SCSPEC TEMPLATE specialization template_instantiation { do_type_instantiation ($4 ? $4 : $3, $1); } | SCSPEC TEMPLATE typed_declspecs declarator - { do_function_instantiation ($3, $4, $1); } + { tree specs = strip_attrs ($3); + do_function_instantiation (specs, $4, $1); } + | SCSPEC TEMPLATE notype_declarator + { do_function_instantiation (NULL_TREE, $3, $1); } ; template_type: @@ -849,6 +905,8 @@ template_instantiate_once: pop_obstacks (); end_template_instantiation ($1); + repo_template_used (t); + /* Now go after the methods & class data. */ instantiate_member_templates ($1); @@ -895,8 +953,7 @@ paren_expr_or_null: cond_stmt_keyword); $$ = integer_zero_node; } | '(' expr ')' - { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, - bool_truthvalue_conversion ($2)); } + { $$ = condition_conversion ($2); } ; paren_cond_or_null: @@ -905,22 +962,20 @@ paren_cond_or_null: cond_stmt_keyword); $$ = integer_zero_node; } | '(' condition ')' - { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, - bool_truthvalue_conversion ($2)); } + { $$ = condition_conversion ($2); } ; xcond: /* empty */ { $$ = NULL_TREE; } | condition - { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node, - bool_truthvalue_conversion ($$)); } + { $$ = condition_conversion ($$); } | error { $$ = NULL_TREE; } ; condition: - type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '=' + type_specifier_seq declarator exception_specification_opt maybeasm maybe_attribute '=' { { tree d; for (d = getdecls (); d; d = TREE_CHAIN (d)) @@ -935,11 +990,12 @@ condition: current_declspecs = $1; $6 = suspend_momentary (); $$ = start_decl ($2, current_declspecs, 1, $3); - cplus_decl_attributes ($$, $5); + cplus_decl_attributes ($$, $5, + /*prefix_attributes*/ NULL_TREE); } init { - finish_decl ($7, $8, $5, 0); + cp_finish_decl ($7, $8, $5, 0, LOOKUP_ONLYCONVERTING); resume_momentary ($6); $$ = $7; if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) @@ -948,12 +1004,15 @@ condition: | expr ; +compstmtend: + '}' + | maybe_label_decls stmts '}' + | maybe_label_decls stmts error '}' + | maybe_label_decls error '}' + ; + already_scoped_stmt: - '{' '}' - { finish_stmt (); } - | '{' maybe_label_decls stmts '}' - { finish_stmt (); } - | '{' maybe_label_decls error '}' + '{' compstmtend { finish_stmt (); } | simple_stmt ; @@ -1033,8 +1092,10 @@ unary_expr: { tree t = TREE_VALUE ($2); if (t != NULL_TREE - && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - pedwarn ("ANSI C++ forbids using sizeof() on a function"); + && ((TREE_TYPE (t) + && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) + || is_overloaded_fn (t))) + pedwarn ("ANSI C++ forbids taking the sizeof a function type"); } $$ = c_sizeof (TREE_TYPE ($2)); } | SIZEOF '(' type_id ')' %prec HYPERUNARY @@ -1101,7 +1162,7 @@ new_initializer: syntactically valid but semantically invalid. */ | '=' init { - if (flag_ansi) + if (pedantic) pedwarn ("ANSI C++ forbids initialization of new expression with `='"); $$ = $2; } @@ -1121,14 +1182,14 @@ regcast_or_absdcl: ; cast_expr: - sub_cast_expr - | regcast_or_absdcl sub_cast_expr %prec UNARY + unary_expr + | regcast_or_absdcl unary_expr %prec UNARY { $$ = reparse_absdcl_as_casts ($$, $2); } | regcast_or_absdcl '{' initlist maybecomma '}' %prec UNARY { tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($3)); - if (flag_ansi) + if (pedantic) pedwarn ("ANSI C++ forbids constructor-expressions"); /* Indicate that this was a GNU C constructor expression. */ TREE_HAS_CONSTRUCTOR (init) = 1; @@ -1137,29 +1198,6 @@ cast_expr: } ; -sub_cast_expr: - unary_expr - | HEADOF '(' expr ')' - { $$ = build_headof ($3); } - | CLASSOF '(' expr ')' - { $$ = build_classof ($3); } - | CLASSOF '(' TYPENAME ')' - { if (is_aggr_typedef ($3, 1)) - { - tree type = IDENTIFIER_TYPE_VALUE ($3); - if (! IS_SIGNATURE(type)) - $$ = CLASSTYPE_DOSSIER (type); - else - { - sorry ("signature name as argument of `classof'"); - $$ = error_mark_node; - } - } - else - $$ = error_mark_node; - } - ; - expr_no_commas: cast_expr /* Handle general members. */ @@ -1204,7 +1242,8 @@ expr_no_commas: | expr_no_commas '?' xexpr ':' expr_no_commas { $$ = build_x_conditional_expr ($$, $3, $5); } | expr_no_commas '=' expr_no_commas - { $$ = build_modify_expr ($$, NOP_EXPR, $3); } + { $$ = build_modify_expr ($$, NOP_EXPR, $3); + C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } | expr_no_commas ASSIGN expr_no_commas { register tree rval; if ((rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3, @@ -1225,7 +1264,7 @@ expr_no_commas: { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); } | object '(' type_id ')' expr_no_commas %prec UNARY { tree type = groktypename ($3); - $$ = build_m_component_ref ($$, build_c_cast (type, $5)); } + $$ = build_m_component_ref ($$, build_c_cast (type, $5, 0)); } | object primary_no_id %prec UNARY { $$ = build_m_component_ref ($$, $2); } */ @@ -1236,7 +1275,8 @@ notype_unqualified_id: { $$ = build_parse_node (BIT_NOT_EXPR, $3); } | operator_name | IDENTIFIER - | PTYPENAME %prec EMPTY + | PTYPENAME + | NSNAME %prec EMPTY ; unqualified_id: @@ -1246,19 +1286,19 @@ unqualified_id: expr_or_declarator: notype_unqualified_id - | notype_qualified_id | '*' expr_or_declarator %prec UNARY { $$ = build_parse_node (INDIRECT_REF, $2); } | '&' expr_or_declarator %prec UNARY { $$ = build_parse_node (ADDR_EXPR, $2); } + | '(' expr_or_declarator ')' + { $$ = $2; } ; direct_notype_declarator: complex_direct_notype_declarator | notype_unqualified_id - | notype_qualified_id - { push_nested_class (TREE_TYPE (OP0 ($$)), 3); - TREE_COMPLEXITY ($$) = current_class_depth; } + | '(' expr_or_declarator ')' + { $$ = finish_decl_parsing ($2); } ; primary: @@ -1286,7 +1326,21 @@ primary: | string { $$ = combine_strings ($$); } | '(' expr ')' - { $$ = $2; } + { char class; + $$ = $2; + class = TREE_CODE_CLASS (TREE_CODE ($$)); + if (class == 'e' || class == '1' + || class == '2' || class == '<') + /* This inhibits warnings in truthvalue_conversion. */ + C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } + | '(' expr_or_declarator ')' + { char class; + $$ = reparse_decl_as_expr (NULL_TREE, $2); + class = TREE_CODE_CLASS (TREE_CODE ($$)); + if (class == 'e' || class == '1' + || class == '2' || class == '<') + /* This inhibits warnings in truthvalue_conversion. */ + C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } | '(' error ')' { $$ = error_mark_node; } | '(' @@ -1299,7 +1353,7 @@ primary: $$ = expand_start_stmt_expr (); } compstmt ')' { tree rtl_exp; - if (flag_ansi) + if (pedantic) pedwarn ("ANSI C++ forbids braced-groups within expressions"); rtl_exp = expand_end_stmt_expr ($2); /* The statements have side effects, so the group does. */ @@ -1417,27 +1471,43 @@ primary: } #endif else my_friendly_abort (79); - $$ = build_c_cast (type, build_compound_expr ($3)); + $$ = build_c_cast (type, build_compound_expr ($3), 1); } } | functional_cast - | DYNAMIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3); - $$ = build_dynamic_cast (type, $6); } - | STATIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3); - $$ = build_static_cast (type, $6); } - | REINTERPRET_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3); - $$ = build_reinterpret_cast (type, $6); } - | CONST_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3); - $$ = build_const_cast (type, $6); } + | DYNAMIC_CAST '<' + { dont_allow_type_definitions = "inside dynamic_cast"; } + type_id '>' + { dont_allow_type_definitions = 0; } + '(' expr ')' + { tree type = groktypename ($4); + $$ = build_dynamic_cast (type, $8); } + | STATIC_CAST '<' + { dont_allow_type_definitions = "inside static_cast"; } + type_id '>' + { dont_allow_type_definitions = 0; } + '(' expr ')' + { tree type = groktypename ($4); + $$ = build_static_cast (type, $8); } + | REINTERPRET_CAST '<' + { dont_allow_type_definitions = "inside reinterpret_cast"; } + type_id '>' + { dont_allow_type_definitions = 0; } + '(' expr ')' + { tree type = groktypename ($4); + $$ = build_reinterpret_cast (type, $8); } + | CONST_CAST '<' + { dont_allow_type_definitions = "inside const_cast"; } + type_id '>' + { dont_allow_type_definitions = 0; } + '(' expr ')' + { tree type = groktypename ($4); + $$ = build_const_cast (type, $8); } | TYPEID '(' expr ')' { $$ = build_typeid ($3); } | TYPEID '(' type_id ')' { tree type = groktypename ($3); - $$ = get_typeid (type); } + $$ = get_typeid (TYPE_MAIN_VARIANT (type)); } | global_scope IDENTIFIER { do_scoped_id: @@ -1491,11 +1561,14 @@ primary: | overqualified_id LEFT_RIGHT { $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); } | object unqualified_id %prec UNARY - { $$ = build_component_ref ($$, $2, NULL_TREE, 1); } - | object qualified_id %prec UNARY - { $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } + { got_object = NULL_TREE; + $$ = build_component_ref ($$, $2, NULL_TREE, 1); } + | object overqualified_id %prec UNARY + { got_object = NULL_TREE; + $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } | object unqualified_id '(' nonnull_exprlist ')' { + got_object = NULL_TREE; #if 0 /* This is a future direction of this code, but because build_x_function_call cannot always undo what is done @@ -1511,6 +1584,7 @@ primary: } | object unqualified_id LEFT_RIGHT { + got_object = NULL_TREE; #if 0 /* This is a future direction of this code, but because build_x_function_call cannot always undo what is done @@ -1524,8 +1598,9 @@ primary: (LOOKUP_NORMAL|LOOKUP_AGGR)); #endif } - | object qualified_id '(' nonnull_exprlist ')' + | object overqualified_id '(' nonnull_exprlist ')' { + got_object = NULL_TREE; if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) { warning ("signature name in scope resolution ignored"); @@ -1535,8 +1610,9 @@ primary: else $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4); } - | object qualified_id LEFT_RIGHT + | object overqualified_id LEFT_RIGHT { + got_object = NULL_TREE; if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2)))) { warning ("signature name in scope resolution ignored"); @@ -1548,14 +1624,17 @@ primary: } /* p->int::~int() is valid -- 12.4 */ | object '~' TYPESPEC LEFT_RIGHT - { - if (TREE_CODE (TREE_TYPE ($1)) - != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3)))) + { + got_object = NULL_TREE; + if (IDENTIFIER_GLOBAL_VALUE ($3) + && (TREE_CODE (TREE_TYPE ($1)) + != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))) cp_error ("`%E' is not of type `%T'", $1, $3); $$ = convert (void_type_node, $1); } | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT - { + { + got_object = NULL_TREE; if ($2 != $5) cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5); if (TREE_CODE (TREE_TYPE ($1)) @@ -1563,6 +1642,11 @@ primary: cp_error ("`%E' is not of type `%T'", $1, $2); $$ = convert (void_type_node, $1); } + | object error + { + got_object = NULL_TREE; + $$ = error_mark_node; + } ; /* Not needed for now. @@ -1580,7 +1664,7 @@ primary_no_id: } $$ = expand_start_stmt_expr (); } compstmt ')' - { if (flag_ansi) + { if (pedantic) pedwarn ("ANSI C++ forbids braced-groups within expressions"); $$ = expand_end_stmt_expr ($2); } | primary_no_id '(' nonnull_exprlist ')' @@ -1617,9 +1701,9 @@ delete: DELETE boolean.literal: CXX_TRUE - { $$ = true_node; } + { $$ = boolean_true_node; } | CXX_FALSE - { $$ = false_node; } + { $$ = boolean_false_node; } ; /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ @@ -1643,9 +1727,11 @@ nodecls: ; object: primary '.' + { got_object = TREE_TYPE ($$); } | primary POINTSAT { - $$ = build_x_arrow ($$); + $$ = build_x_arrow ($$); + got_object = TREE_TYPE ($$); } ; @@ -1655,16 +1741,19 @@ decl: { tree d = get_decl_list ($1); int yes = suspend_momentary (); d = start_decl ($2, d, 0, NULL_TREE); - finish_decl (d, NULL_TREE, NULL_TREE, 0); + cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); resume_momentary (yes); if (IS_AGGR_TYPE_CODE (TREE_CODE ($1))) note_got_semicolon ($1); } | typed_declspecs declarator ';' - { tree d = $1; - int yes = suspend_momentary (); - d = start_decl ($2, d, 0, NULL_TREE); - finish_decl (d, NULL_TREE, NULL_TREE, 0); + { tree d, specs, attrs; + int yes; + split_specs_attrs ($1, &specs, &attrs); + yes = suspend_momentary (); + d = start_decl ($2, specs, 0, NULL_TREE); + cplus_decl_attributes (d, NULL_TREE, attrs); + cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0); resume_momentary (yes); note_list_got_semicolon ($1); } @@ -1724,17 +1813,21 @@ type_id: /* Declspecs which contain at least one type specifier or typedef name. (Just `const' or `volatile' is not enough.) - A typedef'd name following these is taken as a name to be declared. */ + A typedef'd name following these is taken as a name to be declared. + In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ typed_declspecs: typed_typespecs %prec EMPTY | typed_declspecs1 + ; typed_declspecs1: declmods typespec { $$ = decl_tree_cons (NULL_TREE, $2, $$); } | typespec reserved_declspecs %prec HYPERUNARY { $$ = decl_tree_cons (NULL_TREE, $$, $2); } + | typespec reserved_typespecquals reserved_declspecs + { $$ = decl_tree_cons (NULL_TREE, $$, chainon ($2, $3)); } | declmods typespec reserved_declspecs { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); } | declmods typespec reserved_typespecquals @@ -1757,11 +1850,16 @@ reserved_declspecs: warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); $$ = decl_tree_cons (NULL_TREE, $2, $$); } + | reserved_declspecs attributes + { $$ = decl_tree_cons ($2, NULL_TREE, $1); } + | attributes + { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } ; /* List of just storage classes and type modifiers. A declaration can start with just this, but then it cannot be used - to redeclare a typedef-name. */ + to redeclare a typedef-name. + In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ declmods: nonempty_type_quals %prec EMPTY @@ -1777,9 +1875,12 @@ declmods: IDENTIFIER_POINTER ($2)); $$ = decl_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); } ; - /* Used instead of declspecs where storage classes are not allowed (that is, for typenames and structure components). @@ -1813,11 +1914,11 @@ typespec: structsp | complete_type_name | TYPEOF '(' expr ')' { $$ = TREE_TYPE ($3); - if (flag_ansi) + if (pedantic && !in_system_header) pedwarn ("ANSI C++ forbids `typeof'"); } | TYPEOF '(' type_id ')' { $$ = groktypename ($3); - if (flag_ansi) + if (pedantic && !in_system_header) pedwarn ("ANSI C++ forbids `typeof'"); } | SIGOF '(' expr ')' { tree type = TREE_TYPE ($3); @@ -1879,8 +1980,9 @@ maybeasm: ; initdcl0: - declarator maybe_raises maybeasm maybe_attribute '=' - { current_declspecs = $0; + declarator exception_specification_opt maybeasm maybe_attribute '=' + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); if (TREE_CODE (current_declspecs) != TREE_LIST) current_declspecs = get_decl_list (current_declspecs); if (have_extern_spec && !used_extern_spec) @@ -1892,14 +1994,15 @@ initdcl0: } $5 = suspend_momentary (); $$ = start_decl ($1, current_declspecs, 1, $2); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ - { finish_decl ($6, $7, $3, 0); + { cp_finish_decl ($6, $7, $3, 0, LOOKUP_ONLYCONVERTING); $$ = $5; } - | declarator maybe_raises maybeasm maybe_attribute + | declarator exception_specification_opt maybeasm maybe_attribute { tree d; - current_declspecs = $0; + split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); if (TREE_CODE (current_declspecs) != TREE_LIST) current_declspecs = get_decl_list (current_declspecs); if (have_extern_spec && !used_extern_spec) @@ -1911,59 +2014,63 @@ initdcl0: } $$ = suspend_momentary (); d = start_decl ($1, current_declspecs, 0, $2); - cplus_decl_attributes (d, $4); - finish_decl (d, NULL_TREE, $3, 0); } + cplus_decl_attributes (d, $4, prefix_attributes); + cp_finish_decl (d, NULL_TREE, $3, 0, 0); } ; initdcl: - declarator maybe_raises maybeasm maybe_attribute '=' + declarator exception_specification_opt maybeasm maybe_attribute '=' { $$ = start_decl ($1, current_declspecs, 1, $2); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ - { finish_decl ($6, $7, $3, 0); } - | declarator maybe_raises maybeasm maybe_attribute + { cp_finish_decl ($6, $7, $3, 0, LOOKUP_ONLYCONVERTING); } + | declarator exception_specification_opt maybeasm maybe_attribute { $$ = start_decl ($1, current_declspecs, 0, $2); - cplus_decl_attributes ($$, $4); - finish_decl ($$, NULL_TREE, $3, 0); } + cplus_decl_attributes ($$, $4, prefix_attributes); + cp_finish_decl ($$, NULL_TREE, $3, 0, 0); } ; notype_initdcl0: - notype_declarator maybe_raises maybeasm maybe_attribute '=' - { current_declspecs = $0; + notype_declarator exception_specification_opt maybeasm maybe_attribute '=' + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); $5 = suspend_momentary (); $$ = start_decl ($1, current_declspecs, 1, $2); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ - { finish_decl ($6, $7, $3, 0); + { cp_finish_decl ($6, $7, $3, 0, LOOKUP_ONLYCONVERTING); $$ = $5; } - | notype_declarator maybe_raises maybeasm maybe_attribute + | notype_declarator exception_specification_opt maybeasm maybe_attribute { tree d; - current_declspecs = $0; + split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); $$ = suspend_momentary (); d = start_decl ($1, current_declspecs, 0, $2); - cplus_decl_attributes (d, $4); - finish_decl (d, NULL_TREE, $3, 0); } + cplus_decl_attributes (d, $4, prefix_attributes); + cp_finish_decl (d, NULL_TREE, $3, 0, 0); } ; nomods_initdcl0: - notype_declarator maybe_raises maybeasm maybe_attribute '=' + notype_declarator exception_specification_opt maybeasm maybe_attribute '=' { current_declspecs = NULL_TREE; + prefix_attributes = NULL_TREE; $5 = suspend_momentary (); $$ = start_decl ($1, current_declspecs, 1, $2); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ - { finish_decl ($6, $7, $3, 0); + { cp_finish_decl ($6, $7, $3, 0, LOOKUP_ONLYCONVERTING); $$ = $5; } - | notype_declarator maybe_raises maybeasm maybe_attribute + | notype_declarator exception_specification_opt maybeasm maybe_attribute { tree d; current_declspecs = NULL_TREE; + prefix_attributes = NULL_TREE; $$ = suspend_momentary (); d = start_decl ($1, current_declspecs, 0, $2); - cplus_decl_attributes (d, $4); - finish_decl (d, NULL_TREE, $3, 0); } + cplus_decl_attributes (d, $4, prefix_attributes); + cp_finish_decl (d, NULL_TREE, $3, 0, 0); } ; /* the * rules are dummies to accept the Apollo extended syntax @@ -1989,22 +2096,22 @@ attribute: attribute_list: attrib - { $$ = build_tree_list (NULL_TREE, $1); } + { $$ = $1; } | attribute_list ',' attrib - { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } + { $$ = chainon ($1, $3); } ; attrib: /* empty */ { $$ = NULL_TREE; } | any_word - { $$ = $1; } + { $$ = build_tree_list ($1, NULL_TREE); } | any_word '(' IDENTIFIER ')' - { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); } + { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' - { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); } + { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } | any_word '(' nonnull_exprlist ')' - { $$ = tree_cons ($1, NULL_TREE, $3); } + { $$ = build_tree_list ($1, $3); } ; /* This still leaves out most reserved keywords, @@ -2025,6 +2132,12 @@ identifiers_or_typenames: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ; +maybe_init: + %prec EMPTY /* empty */ + { $$ = NULL_TREE; } + | '=' init + { $$ = $2; } + init: expr_no_commas %prec '=' | '{' '}' @@ -2080,10 +2193,11 @@ structsp: { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE); check_for_missing_semicolon ($$); } | ENUM identifier - { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); } + { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 1); } | ENUM complex_type_name - { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); } - + { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 1); } + | TYPENAME_KEYWORD complex_type_name + { $$ = $2; } /* C++ extensions, merged with C to avoid shift/reduce conflicts */ | class_head left_curly opt.component_decl_list '}' { @@ -2105,9 +2219,6 @@ structsp: if (TREE_CODE ($$) == ENUMERAL_TYPE) /* $$ = $1 from default rule. */; - else if (CLASSTYPE_DECLARED_EXCEPTION ($$)) - { - } else { $$ = finish_struct ($$, $3, semi); @@ -2138,16 +2249,11 @@ structsp: check_for_missing_semicolon ($$); } | class_head %prec EMPTY { -#if 0 - /* It's no longer clear what the following error is supposed to - accomplish. If it turns out to be needed, add a comment why. */ - if (TYPE_BINFO_BASETYPES ($$) && !TYPE_SIZE ($$)) - { - error ("incomplete definition of type `%s'", - TYPE_NAME_STRING ($$)); - $$ = error_mark_node; - } -#endif + /* struct B: public A; is not accepted by the WP grammar. */ + if (TYPE_BINFO_BASETYPES ($$) && !TYPE_SIZE ($$) + && ! TYPE_BEING_DEFINED ($$)) + cp_error ("base clause without member specification for `%#T'", + $$); } ; @@ -2185,9 +2291,11 @@ specialization: named_class_head_sans_basetype: aggr identifier { current_aggr = $$; $$ = $2; } - | aggr complex_type_name - { current_aggr = $$; $$ = $2; } - | aggr template_type %prec EMPTY + | specialization + ; + +named_class_head_sans_basetype_defn: + aggr identifier_defn %prec EMPTY { current_aggr = $$; $$ = $2; } | aggr template_type_name '{' { yyungetc ('{', 1); @@ -2197,37 +2305,34 @@ named_class_head_sans_basetype: overload_template_name ($$, 0); } | aggr template_type_name ':' { yyungetc (':', 1); goto aggr2; } - | specialization ; -named_class_head_sans_basetype_defn: - aggr identifier_defn %prec EMPTY +named_complex_class_head_sans_basetype: + aggr nested_name_specifier identifier + { current_aggr = $$; $$ = $3; } + | aggr template_type %prec EMPTY { current_aggr = $$; $$ = $2; } ; -do_xref: /* empty */ %prec EMPTY - { $$ = xref_tag (current_aggr, $0, NULL_TREE, 1); } - do_xref_defn: /* empty */ %prec EMPTY - { $$ = xref_defn_tag (current_aggr, $0, NULL_TREE); } + { $$ = xref_tag (current_aggr, $0, NULL_TREE, 0); } + ; named_class_head: - named_class_head_sans_basetype do_xref - maybe_base_class_list %prec EMPTY - { + named_class_head_sans_basetype %prec EMPTY + { $$ = xref_tag (current_aggr, $1, NULL_TREE, 1); } + | named_class_head_sans_basetype_defn do_xref_defn + maybe_base_class_list %prec EMPTY + { + $$ = $2; if ($3) - $$ = xref_tag (current_aggr, $1, $3, 1); - else - $$ = $2; + xref_basetypes (current_aggr, $1, $2, $3); } - | - named_class_head_sans_basetype_defn do_xref_defn - maybe_base_class_list %prec EMPTY - { - if ($3) - $$ = xref_defn_tag (current_aggr, $1, $3); - else - $$ = $2; + | named_complex_class_head_sans_basetype maybe_base_class_list + { + $$ = TREE_TYPE ($1); + if ($2) + xref_basetypes (current_aggr, $1, TREE_TYPE ($1), $2); } ; @@ -2241,23 +2346,22 @@ class_head: unnamed_class_head | named_c maybe_base_class_list: %prec EMPTY /* empty */ { $$ = NULL_TREE; } - | ':' %prec EMPTY + | ':' see_typename %prec EMPTY { yyungetc(':', 1); $$ = NULL_TREE; } - | ':' base_class_list %prec EMPTY - { $$ = $2; } + | ':' see_typename base_class_list %prec EMPTY + { $$ = $3; } ; base_class_list: base_class - | base_class_list ',' base_class - { $$ = chainon ($$, $3); } + | base_class_list ',' see_typename base_class + { $$ = chainon ($$, $4); } ; base_class: base_class.1 { tree type; - do_base_class1: type = IDENTIFIER_TYPE_VALUE ($$); if (! is_aggr_typedef ($$, 1)) $$ = NULL_TREE; @@ -2281,14 +2385,13 @@ base_class: else $$ = build_tree_list ((tree)access_default, $$); } - | base_class_access_list base_class.1 + | base_class_access_list see_typename base_class.1 { tree type; - do_base_class2: - type = IDENTIFIER_TYPE_VALUE ($2); + type = IDENTIFIER_TYPE_VALUE ($3); if (current_aggr == signature_type_node) error ("access and source specifiers not allowed in signature"); - if (! is_aggr_typedef ($2, 1)) + if (! is_aggr_typedef ($3, 1)) $$ = NULL_TREE; else if (current_aggr == signature_type_node && (! type) && (! IS_SIGNATURE (type))) @@ -2300,7 +2403,7 @@ base_class: { sorry ("signature inheritance, base type `%s' ignored", IDENTIFIER_POINTER ($$)); - $$ = build_tree_list ((tree)access_public, $2); + $$ = build_tree_list ((tree)access_public, $3); } else if (type && IS_SIGNATURE (type)) { @@ -2308,7 +2411,7 @@ base_class: $$ = NULL_TREE; } else - $$ = build_tree_list ((tree) $$, $2); + $$ = build_tree_list ((tree) $$, $3); } ; @@ -2361,12 +2464,12 @@ base_class.1: ; base_class_access_list: - VISSPEC - | SCSPEC + VISSPEC see_typename + | SCSPEC see_typename { if ($$ != ridpointers[(int)RID_VIRTUAL]) sorry ("non-virtual access"); $$ = access_default_virtual; } - | base_class_access_list VISSPEC + | base_class_access_list VISSPEC see_typename { int err = 0; if ($2 == access_protected) { @@ -2392,7 +2495,7 @@ base_class_access_list: $$ = access_private_virtual; } } - | base_class_access_list SCSPEC + | base_class_access_list SCSPEC see_typename { if ($2 != ridpointers[(int)RID_VIRTUAL]) sorry ("non-virtual access"); if ($$ == access_public) @@ -2431,8 +2534,12 @@ left_curly: '{' int needs_writing; tree name = TYPE_IDENTIFIER (t); - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); + if (! ANON_AGGRNAME_P (name)) + { + CLASSTYPE_INTERFACE_ONLY (t) = interface_only; + SET_CLASSTYPE_INTERFACE_UNKNOWN_X + (t, interface_unknown); + } /* Record how to set the access of this class's virtual functions. If write_virtuals == 2 or 3, then @@ -2510,11 +2617,11 @@ component_decl_list: $$ = $2; } } - | component_decl_list ';' ; component_decl: component_decl_1 ';' + { } | component_decl_1 '}' { error ("missing ';' before right brace"); yyungetc ('}', 0); } @@ -2522,8 +2629,14 @@ component_decl: /* note that INLINE is like a TYPESPEC */ | fn.def2 ':' /* base_init compstmt */ { $$ = finish_method ($$); } + | fn.def2 TRY /* base_init compstmt */ + { $$ = finish_method ($$); } + | fn.def2 RETURN /* base_init compstmt */ + { $$ = finish_method ($$); } | fn.def2 '{' /* nodecls compstmt */ { $$ = finish_method ($$); } + | ';' + { $$ = NULL_TREE; } ; component_decl_1: @@ -2531,16 +2644,12 @@ 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 ($$, $2); - } + { $$ = grok_x_components ($1, $2); } | declmods notype_components - { - $$ = grok_x_components ($$, $2); - } - | notype_declarator maybe_raises maybeasm maybe_attribute - { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } + { $$ = grok_x_components ($1, $2); } + | notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, NULL_TREE, $2, $5, $3, + build_tree_list ($4, NULL_TREE)); } | ':' expr_no_commas { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } | error @@ -2554,19 +2663,26 @@ component_decl_1: should "A::foo" be declared as a function or "A::bar" as a data member? In other words, is "bar" an after_type_declarator or a parmlist? */ - | typed_declspecs '(' parmlist ')' type_quals - { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), + | typed_declspecs '(' parmlist ')' type_quals exception_specification_opt maybeasm maybe_attribute maybe_init + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), $3, $5); - $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, - NULL_TREE); } - | typed_declspecs LEFT_RIGHT type_quals - { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), + $$ = grokfield ($$, TREE_CHAIN (specs), $6, $9, $7, + build_tree_list ($8, attrs)); } + | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt maybeasm maybe_attribute maybe_init + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + $$ = build_parse_node (CALL_EXPR, TREE_VALUE (specs), empty_parms (), $3); - $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, - NULL_TREE); } + $$ = grokfield ($$, TREE_CHAIN (specs), $4, $7, $5, + build_tree_list ($6, attrs)); } + | using_decl + { $$ = do_class_using_decl ($1); } ; /* The case of exactly one component is handled directly by component_decl. */ +/* ??? Huh? ^^^ */ components: /* empty: possibly anonymous */ { $$ = NULL_TREE; } @@ -2608,64 +2724,60 @@ component_declarator: ; after_type_component_declarator0: - after_type_declarator maybe_raises maybeasm maybe_attribute - { current_declspecs = $0; - $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init - { current_declspecs = $0; - $$ = grokfield ($$, current_declspecs, $2, $6, $3); - cplus_decl_attributes ($$, $4); } + after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); + $0 = current_declspecs; + $$ = grokfield ($$, current_declspecs, $2, $5, $3, + build_tree_list ($4, prefix_attributes)); } | TYPENAME ':' expr_no_commas maybe_attribute - { current_declspecs = $0; + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); + $0 = current_declspecs; $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } ; notype_component_declarator0: - notype_declarator maybe_raises maybeasm maybe_attribute - { current_declspecs = $0; - $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | notype_declarator maybe_raises maybeasm maybe_attribute '=' init - { current_declspecs = $0; - $$ = grokfield ($$, current_declspecs, $2, $6, $3); - cplus_decl_attributes ($$, $4); } + notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); + $0 = current_declspecs; + $$ = grokfield ($$, current_declspecs, $2, $5, $3, + build_tree_list ($4, prefix_attributes)); } | IDENTIFIER ':' expr_no_commas maybe_attribute - { current_declspecs = $0; + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); + $0 = current_declspecs; $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } | ':' expr_no_commas maybe_attribute - { current_declspecs = $0; + { split_specs_attrs ($0, ¤t_declspecs, + &prefix_attributes); + $0 = current_declspecs; $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3); } + cplus_decl_attributes ($$, $3, prefix_attributes); } ; after_type_component_declarator: - after_type_declarator maybe_raises maybeasm maybe_attribute - { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init - { $$ = grokfield ($$, current_declspecs, $2, $6, $3); - cplus_decl_attributes ($$, $4); } + after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, current_declspecs, $2, $5, $3, + build_tree_list ($4, prefix_attributes)); } | TYPENAME ':' expr_no_commas maybe_attribute { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } ; notype_component_declarator: - notype_declarator maybe_raises maybeasm maybe_attribute - { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | notype_declarator maybe_raises maybeasm maybe_attribute '=' init - { $$ = grokfield ($$, current_declspecs, $2, $6, $3); - cplus_decl_attributes ($$, $4); } + notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, current_declspecs, $2, $5, $3, + build_tree_list ($4, prefix_attributes)); } | IDENTIFIER ':' expr_no_commas maybe_attribute { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4); } + cplus_decl_attributes ($$, $4, prefix_attributes); } | ':' expr_no_commas maybe_attribute { $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3); } + cplus_decl_attributes ($$, $3, prefix_attributes); } ; /* We chain the enumerators in reverse order. @@ -2695,7 +2807,7 @@ new_type_id: non-constant dimension. */ | '(' type_id ')' '[' expr ']' { - if (flag_ansi) + if (pedantic) pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new"); $$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5); $$ = build_decl_list (TREE_PURPOSE ($2), $$); @@ -2719,12 +2831,27 @@ nonempty_type_quals: /* These rules must follow the rules for function declarations and component declarations. That way, longer rules are preferred. */ +suspend_mom: + { $$ = suspend_momentary (); } + /* An expression which will not live on the momentary obstack. */ nonmomentary_expr: - { $$ = suspend_momentary (); } 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; } + ; + /* A declarator that is allowed only after an explicit typespec. */ /* may all be followed by prec '.' */ after_type_declarator: @@ -2766,14 +2893,8 @@ nested_type: ; direct_after_type_declarator: - direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_after_type_declarator '(' parmlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_after_type_declarator LEFT_RIGHT type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } - | direct_after_type_declarator '(' error ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } + direct_after_type_declarator maybe_parmlist type_quals %prec '.' + { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); } | direct_after_type_declarator '[' nonmomentary_expr ']' { $$ = build_parse_node (ARRAY_REF, $$, $3); } | direct_after_type_declarator '[' ']' @@ -2823,22 +2944,21 @@ complex_notype_declarator: ; complex_direct_notype_declarator: - direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_notype_declarator '(' parmlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_notype_declarator LEFT_RIGHT type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } - | direct_notype_declarator '(' error ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } - | '(' expr_or_declarator ')' - { $$ = finish_decl_parsing ($2); } + direct_notype_declarator maybe_parmlist type_quals %prec '.' + { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); } | '(' complex_notype_declarator ')' { $$ = $2; } | direct_notype_declarator '[' nonmomentary_expr ']' { $$ = build_parse_node (ARRAY_REF, $$, $3); } | direct_notype_declarator '[' ']' { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } + | notype_qualified_id + { if (TREE_TYPE (OP0 ($$)) != current_class_type) + { + push_nested_class (TREE_TYPE (OP0 ($$)), 3); + TREE_COMPLEXITY ($$) = current_class_depth; + } + } ; qualified_id: @@ -2884,6 +3004,8 @@ nested_name_specifier: nested_name_specifier_1: TYPENAME SCOPE { got_scope = TREE_TYPE ($$); } + | NSNAME SCOPE + { got_scope = $$; } | template_type SCOPE { got_scope = TREE_TYPE ($$); } /* These break 'const i;' @@ -3034,12 +3156,18 @@ errstmt: error ';' expand_start_bindings (0); } ; +.poplevel: /* empty */ + { expand_end_bindings (getdecls (), kept_level_p (), 1); + $$ = poplevel (kept_level_p (), 1, 0); + pop_momentary (); } + ; + /* Read zero or more forward-declarations for labels that nested functions can jump to. */ maybe_label_decls: /* empty */ | label_decls - { if (flag_ansi) + { if (pedantic) pedwarn ("ANSI C++ forbids label declarations"); } ; @@ -3068,22 +3196,8 @@ compstmt_or_error: | error compstmt ; -compstmt: '{' .pushlevel '}' - { expand_end_bindings (getdecls (), kept_level_p(), 1); - $$ = poplevel (kept_level_p (), 1, 0); - pop_momentary (); } - | '{' .pushlevel maybe_label_decls stmts '}' - { expand_end_bindings (getdecls (), kept_level_p(), 1); - $$ = poplevel (kept_level_p (), 1, 0); - pop_momentary (); } - | '{' .pushlevel maybe_label_decls stmts error '}' - { expand_end_bindings (getdecls (), kept_level_p(), 1); - $$ = poplevel (kept_level_p (), 0, 0); - pop_momentary (); } - | '{' .pushlevel maybe_label_decls error '}' - { expand_end_bindings (getdecls (), kept_level_p(), 1); - $$ = poplevel (kept_level_p (), 0, 0); - pop_momentary (); } +compstmt: '{' .pushlevel compstmtend .poplevel + { $$ = $4; } ; simple_if: @@ -3098,10 +3212,8 @@ simple_if: implicitly_scoped_stmt: compstmt { finish_stmt (); } - | .pushlevel simple_stmt - { expand_end_bindings (getdecls (), kept_level_p (), 1); - $$ = poplevel (kept_level_p (), 1, 0); - pop_momentary (); } + | .pushlevel simple_stmt .poplevel + { $$ = $3; } ; stmt: @@ -3129,11 +3241,9 @@ simple_stmt: | simple_if ELSE { expand_start_else (); } implicitly_scoped_stmt - { expand_end_cond (); - expand_end_bindings (getdecls (), kept_level_p (), 1); - poplevel (kept_level_p (), 1, 0); - pop_momentary (); - finish_stmt (); } + { expand_end_cond (); } + .poplevel + { finish_stmt (); } | simple_if %prec IF { expand_end_cond (); expand_end_bindings (getdecls (), kept_level_p (), 1); @@ -3147,11 +3257,8 @@ simple_stmt: cond_stmt_keyword = "while"; } .pushlevel paren_cond_or_null { expand_exit_loop_if_false (0, $4); } - already_scoped_stmt - { expand_end_bindings (getdecls (), kept_level_p (), 1); - poplevel (kept_level_p (), 1, 0); - pop_momentary (); - expand_end_loop (); + already_scoped_stmt .poplevel + { expand_end_loop (); finish_stmt (); } | DO { emit_nop (); @@ -3166,64 +3273,55 @@ simple_stmt: expand_end_loop (); clear_momentary (); finish_stmt (); } - | forhead.1 + | FOR + { emit_line_note (input_filename, lineno); + if (flag_new_for_scope > 0) + { + /* Conditionalize .pushlevel */ + pushlevel (0); + note_level_for_for (); + clear_last_expr (); + push_momentary (); + expand_start_bindings (0); + } + } + '(' for.init.statement { emit_nop (); emit_line_note (input_filename, lineno); - if ($1) cplus_expand_expr_stmt ($1); expand_start_loop_continue_elsewhere (1); } .pushlevel xcond ';' { emit_line_note (input_filename, lineno); - if ($4) expand_exit_loop_if_false (0, $4); } + if ($7) expand_exit_loop_if_false (0, $7); } xexpr ')' - /* Don't let the tree nodes for $7 be discarded + /* Don't let the tree nodes for $10 be discarded by clear_momentary during the parsing of the next stmt. */ { push_momentary (); } - already_scoped_stmt + already_scoped_stmt .poplevel { emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), kept_level_p (), 1); - poplevel (kept_level_p (), 1, 0); - pop_momentary (); expand_loop_continue_here (); - if ($7) cplus_expand_expr_stmt ($7); + if ($10) cplus_expand_expr_stmt ($10); pop_momentary (); expand_end_loop (); + if (flag_new_for_scope > 0) + { + expand_end_bindings (getdecls (), kept_level_p (), 1); + poplevel (kept_level_p (), 1, 0); + pop_momentary (); + } finish_stmt (); } - | forhead.2 - { emit_nop (); - emit_line_note (input_filename, lineno); - expand_start_loop_continue_elsewhere (1); } - .pushlevel xcond ';' - { emit_line_note (input_filename, lineno); - if ($4) expand_exit_loop_if_false (0, $4); } - xexpr ')' - /* Don't let the tree nodes for $7 be discarded - by clear_momentary during the parsing of the next stmt. */ - { push_momentary (); - $8 = lineno; } - already_scoped_stmt - { emit_line_note (input_filename, (int) $8); - expand_end_bindings (getdecls (), kept_level_p (), 1); - poplevel (kept_level_p (), 1, 0); - pop_momentary (); - expand_loop_continue_here (); - if ($7) cplus_expand_expr_stmt ($7); - pop_momentary (); - expand_end_loop (); - finish_stmt (); - } | SWITCH .pushlevel '(' condition ')' { emit_line_note (input_filename, lineno); c_expand_start_case ($4); + push_switch (); /* Don't let the tree nodes for $4 be discarded by clear_momentary during the parsing of the next stmt. */ push_momentary (); } implicitly_scoped_stmt { expand_end_case ($4); pop_momentary (); - expand_end_bindings (getdecls (), kept_level_p (), 1); - poplevel (kept_level_p (), 1, 0); - pop_momentary (); - finish_stmt (); } + pop_switch (); } + .poplevel + { finish_stmt (); } | CASE expr_no_commas ':' { register tree value = check_cp_case_value ($2); register tree label @@ -3239,7 +3337,7 @@ simple_stmt: else if (success == 2) { cp_error ("duplicate case value `%E'", $2); - cp_error_at ("`%E' previously used here", duplicate); + cp_error_at ("previously used here", duplicate); } else if (success == 3) warning ("case value out of range"); @@ -3255,7 +3353,7 @@ simple_stmt: register tree label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - if (flag_ansi) + if (pedantic) pedwarn ("ANSI C++ forbids range expressions in switch statement"); if (value1 != error_mark_node && value2 != error_mark_node) @@ -3367,40 +3465,42 @@ simple_stmt: | try_block ; +function_try_block: + TRY + { + if (! current_function_parms_stored) + store_parm_decls (); + expand_start_early_try_stmts (); + } + ctor_initializer_opt compstmt_or_error + { expand_end_try_stmts (); + expand_start_all_catch (); } + handler_seq + { + expand_end_all_catch (); + finish_function (lineno, (int)$3, 0); + } + ; + try_block: - TRY '{' .pushlevel + TRY { expand_start_try_stmts (); } - ansi_try_stmts + compstmt { expand_end_try_stmts (); expand_start_all_catch (); } handler_seq { expand_end_all_catch (); } ; -ansi_try_stmts: - '}' - /* An empty try block is degenerate, but it's better to - do extra work here than to do all the special-case work - everywhere else. */ - { expand_end_bindings (0,1,1); - poplevel (2,0,0); - } - | stmts '}' - { expand_end_bindings (0,1,1); - poplevel (2,0,0); - } - | error '}' - { expand_end_bindings (0,1,1); - poplevel (2,0,0); - } - ; - handler_seq: /* empty */ - | handler_seq CATCH - { emit_line_note (input_filename, lineno); } - handler_args compstmt + | handler_seq CATCH .pushlevel + { dont_allow_type_definitions = "inside exception declarations"; } + handler_args + { dont_allow_type_definitions = 0; } + compstmt { expand_end_catch_block (); } + .poplevel ; type_specifier_seq: @@ -3420,7 +3520,7 @@ handler_args: { expand_start_catch_block ($2, $3); } | '(' typed_typespecs after_type_declarator ')' { expand_start_catch_block ($2, $3); } - */ + This allows reference parameters... */ | '(' parm ')' { expand_start_catch_block (TREE_PURPOSE ($2), TREE_VALUE ($2)); } @@ -3440,24 +3540,11 @@ label_colon: { goto do_label; } ; -forhead.1: - FOR '(' ';' - { $$ = NULL_TREE; } - | FOR '(' expr ';' - { $$ = $3; } - | FOR '(' '{' '}' - { $$ = NULL_TREE; } - ; - -forhead.2: - FOR '(' decl - { $$ = 0; } - | FOR '(' error ';' - { $$ = 0; } - | FOR '(' '{' .pushlevel stmts '}' - { $$ = 1; } - | FOR '(' '{' .pushlevel error '}' - { $$ = -1; } +for.init.statement: + xexpr ';' + { if ($1) cplus_expand_expr_stmt ($1); } + | decl + | '{' compstmtend ; /* Either a type-qualifier or nothing. First thing in an `asm' statement. */ @@ -3615,10 +3702,12 @@ parms_comma: named_parm: /* typed_declspecs dont_see_typename '*' IDENTIFIER - { $$ = build_tree_list ($$, build_parse_node (INDIRECT_REF, $4)); + { tree specs = strip_attrs ($1); + $$ = build_tree_list (specs, build_parse_node (INDIRECT_REF, $4)); see_typename (); } | typed_declspecs dont_see_typename '&' IDENTIFIER - { $$ = build_tree_list ($$, build_parse_node (ADDR_EXPR, $4)); + { tree specs = strip_attrs ($1); + $$ = build_tree_list (specs, build_parse_node (ADDR_EXPR, $4)); see_typename (); } | TYPENAME IDENTIFIER { $$ = build_tree_list (get_decl_list ($$), $2); } @@ -3628,24 +3717,26 @@ named_parm: /* Here we expand typed_declspecs inline to avoid mis-parsing of TYPESPEC IDENTIFIER. */ typed_declspecs1 declarator - { $$ = build_tree_list ($$, $2); } + { tree specs = strip_attrs ($1); + $$ = build_tree_list (specs, $2); } | typed_typespecs declarator { $$ = build_tree_list ($$, $2); } | typespec declarator { $$ = build_tree_list (get_decl_list ($$), $2); } | typed_declspecs1 absdcl - { $$ = build_tree_list ($$, $2); } + { tree specs = strip_attrs ($1); + $$ = build_tree_list (specs, $2); } | typed_declspecs1 %prec EMPTY - { $$ = build_tree_list ($$, NULL_TREE); } + { tree specs = strip_attrs ($1); + $$ = build_tree_list (specs, NULL_TREE); } | declmods notype_declarator - { $$ = build_tree_list ($$, $2); } + { tree specs = strip_attrs ($1); + $$ = build_tree_list (specs, $2); } ; full_parm: - parm - { $$ = build_tree_list (NULL_TREE, $$); } - | parm '=' init - { $$ = build_tree_list ($3, $$); } + parm maybe_init + { $$ = build_tree_list ($2, $$); } ; parm: @@ -3678,26 +3769,28 @@ try_for_typename: bad_parm: /* empty */ %prec EMPTY { - warning ("type specifier omitted for parameter"); - $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($-1)), NULL_TREE); + error ("type specifier omitted for parameter"); + $$ = build_tree_list (integer_type_node, NULL_TREE); } | notype_declarator { - warning ("type specifier omitted for parameter"); - $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($-1)), $$); + error ("type specifier omitted for parameter"); + $$ = build_tree_list (integer_type_node, $$); } ; -maybe_raises: +exception_specification_opt: %prec EMPTY /* empty */ { $$ = NULL_TREE; } | THROW '(' ansi_raise_identifiers ')' %prec EMPTY { $$ = $3; } + | THROW LEFT_RIGHT %prec EMPTY + { $$ = build_decl_list (NULL_TREE, NULL_TREE); } ; ansi_raise_identifier: type_id - { $$ = build_decl_list (NULL_TREE, $$); } + { $$ = build_decl_list (NULL_TREE, groktypename($$)); } ; ansi_raise_identifiers: