diff options
Diffstat (limited to 'contrib/gcc/cp/parse.y')
-rw-r--r-- | contrib/gcc/cp/parse.y | 3807 |
1 files changed, 0 insertions, 3807 deletions
diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y deleted file mode 100644 index 7b5d3bdede9b..000000000000 --- a/contrib/gcc/cp/parse.y +++ /dev/null @@ -1,3807 +0,0 @@ -/* YACC parser for C++ syntax. - 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. - -GNU CC is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -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, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This grammar is based on the GNU CC grammar. */ - -/* Note: Bison automatically applies a default action of "$$ = $1" for - all derivations; this is applied before the explicit action, if one - is given. Keep this in mind when reading the actions. */ - -%{ -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#include "config.h" - -#include "system.h" - -#include "tree.h" -#include "input.h" -#include "flags.h" -#include "lex.h" -#include "cp-tree.h" -#include "output.h" -#include "except.h" -#include "toplev.h" - -/* Since parsers are distinct for each language, put the language string - definition here. (fnf) */ -char *language_string = "GNU C++"; - -extern tree void_list_node; -extern struct obstack permanent_obstack; - -extern int end_of_file; - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -#define OP0(NODE) (TREE_OPERAND (NODE, 0)) -#define OP1(NODE) (TREE_OPERAND (NODE, 1)) - -/* Contains the statement keyword (if/while/do) to include in an - error message if the user supplies an empty conditional expression. */ -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; -int used_extern_spec; - -/* Cons up an empty parameter list. */ -#ifdef __GNUC__ -__inline -#endif -static tree -empty_parms () -{ - tree parms; - - if (strict_prototype - || current_class_type != NULL) - parms = void_list_node; - else - parms = NULL_TREE; - return parms; -} - -%} - -%start program - -%union {long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; } - -/* All identifiers that are not reserved words - and are not declared typedefs in the current block */ -%token IDENTIFIER - -/* All identifiers that are declared typedefs in the current block. - In some contexts, they are treated just like IDENTIFIER, - but they can also serve as typespecs in declarations. */ -%token TYPENAME -%token SELFNAME - -/* A template function. */ -%token PFUNCNAME - -/* Reserved words that specify storage class. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token SCSPEC - -/* Reserved words that specify type. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token TYPESPEC - -/* Reserved words that qualify type: "const" or "volatile". - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token CV_QUALIFIER - -/* Character or numeric constants. - yylval is the node for the constant. */ -%token CONSTANT - -/* String constants in raw form. - yylval is a STRING_CST node. */ -%token STRING - -/* "...", used for functions with variable arglists. */ -%token ELLIPSIS - -/* 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_KEYWORD GOTO ASM_KEYWORD TYPEOF ALIGNOF -%token SIGOF -%token ATTRIBUTE EXTENSION LABEL -%token REALPART IMAGPART - -/* the reserved words... C++ extensions */ -%token <ttype> AGGR -%token <ttype> VISSPEC -%token DELETE NEW 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 <itype> SCOPE - -/* Define the operator tokens and their precedences. - The value is an integer because, if used, it is the tree code - to use in the expression made from the operator. */ - -%left EMPTY /* used to resolve s/r with epsilon */ - -%left error - -/* Add precedence rules to solve dangling else s/r conflict */ -%nonassoc IF -%nonassoc ELSE - -%left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD - -%left '{' ',' ';' - -%nonassoc THROW -%right <code> ':' -%right <code> ASSIGN '=' -%right <code> '?' -%left <code> OROR -%left <code> ANDAND -%left <code> '|' -%left <code> '^' -%left <code> '&' -%left <code> MIN_MAX -%left <code> EQCOMPARE -%left <code> ARITHCOMPARE '<' '>' -%left <code> LSHIFT RSHIFT -%left <code> '+' '-' -%left <code> '*' '/' '%' -%left <code> POINTSAT_STAR DOT_STAR -%right <code> UNARY PLUSPLUS MINUSMINUS '~' -%left HYPERUNARY -%left <ttype> PAREN_STAR_PAREN LEFT_RIGHT -%left <code> POINTSAT '.' '(' '[' - -%right SCOPE /* C++ extension */ -%nonassoc NEW DELETE TRY CATCH - -%type <code> unop - -%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist -%type <ttype> PFUNCNAME maybe_identifier -%type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME -%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING -%type <ttype> reserved_declspecs boolean.literal -%type <ttype> reserved_typespecquals -%type <ttype> declmods -%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier -%type <itype> initdecls notype_initdecls initdcl /* C++ modification */ -%type <ttype> init initlist maybeasm maybe_init defarg defarg1 -%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers -%type <ttype> maybe_attribute attributes attribute attribute_list attrib -%type <ttype> any_word - -%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 <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 -%type <ttype> absdcl cv_qualifiers -%type <ttype> direct_abstract_declarator conversion_declarator -%type <ttype> new_declarator direct_new_declarator -%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 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 -%type <ttype> complex_direct_notype_declarator functional_cast -%type <ttype> complex_parmlist parms_comma -%type <ttype> namespace_qualifier namespace_using_decl - -%type <ftype> type_id new_type_id typed_typespecs typespec typed_declspecs -%type <ftype> typed_declspecs1 type_specifier_seq nonempty_cv_qualifiers -%type <ftype> structsp typespecqual_reserved parm named_parm full_parm - -/* C++ extensions */ -%token <ttype> PTYPENAME -%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL -%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 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> 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 -%type <ttype> operator_name -%type <ttype> object aggr -%type <itype> new delete .begin_new_placement -/* %type <ttype> primary_no_id */ -%type <ttype> nonmomentary_expr maybe_parmlist -%type <itype> initdcl0 notype_initdcl0 member_init_list initdcl0_innards -%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 -%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem -%type <ttype> complete_type_name notype_identifier nonnested_type -%type <ttype> complex_type_name nested_name_specifier_1 -%type <ttype> new_initializer new_placement -%type <ttype> using_decl -%type <ttype> typename_sub typename_sub0 typename_sub1 typename_sub2 -%type <ttype> explicit_template_type -/* in order to recognize aggr tags as defining and thus shadowing. */ -%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN -%type <ttype> named_class_head_sans_basetype_defn -%type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN - -%type <ttype> self_template_type .finish_template_type - -%token NSNAME -%type <ttype> NSNAME - -/* Used in lex.c for parsing pragmas. */ -%token END_OF_LINE - -/* lex.c and pt.c depend 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 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) -extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern tree combine_strings PROTO((tree)); - -static int -parse_decl(declarator, specs_attrs, attributes, initialized, decl) - tree declarator; - tree specs_attrs; - tree attributes; - int initialized; - tree* decl; -{ - int sm; - - split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); - if (current_declspecs - && TREE_CODE (current_declspecs) != TREE_LIST) - current_declspecs = build_decl_list (NULL_TREE, current_declspecs); - if (have_extern_spec && !used_extern_spec) - { - current_declspecs = decl_tree_cons (NULL_TREE, - get_identifier ("extern"), - current_declspecs); - used_extern_spec = 1; - } - sm = suspend_momentary (); - *decl = start_decl (declarator, current_declspecs, initialized, - attributes, prefix_attributes); - return sm; -} -%} - -%% -program: - /* empty */ - | extdefs - { finish_translation_unit (); } - ; - -/* the reason for the strange actions in this rule - is so that notype_initdecls when reached via datadef - can find a valid list of type and sc specs in $0. */ - -extdefs: - { $<ttype>$ = NULL_TREE; } - lang_extdef - { $<ttype>$ = NULL_TREE; } - | extdefs lang_extdef - { $<ttype>$ = NULL_TREE; } - ; - -extdefs_opt: - extdefs - | /* empty */ - ; - -.hush_warning: - { have_extern_spec = 1; - used_extern_spec = 0; - $<ttype>$ = NULL_TREE; } - ; -.warning_ok: - { have_extern_spec = 0; } - ; - -extension: - EXTENSION - { $<itype>$ = pedantic; - pedantic = 0; } - ; - -asm_keyword: - ASM_KEYWORD - ; - -lang_extdef: - { if (pending_lang_change) do_pending_lang_change(); } - extdef - { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) - pop_everything (); } - ; - -extdef: - fndef eat_saved_input - { if (pending_inlines) do_pending_inlines (); } - | datadef - { if (pending_inlines) do_pending_inlines (); } - | template_def - { if (pending_inlines) do_pending_inlines (); } - | asm_keyword '(' string ')' ';' - { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); - assemble_asm ($3); } - | extern_lang_string '{' extdefs_opt '}' - { pop_lang_context (); } - | 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 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_alias - | using_decl ';' - { do_toplevel_using_decl ($1); } - | using_directive - | extension extdef - { pedantic = $<itype>1; } - ; - -namespace_alias: - NAMESPACE identifier '=' - { begin_only_namespace_names (); } - any_id ';' - { - end_only_namespace_names (); - if (lastiddecl) - $5 = lastiddecl; - do_namespace_alias ($2, $5); - } - ; - -using_decl: - USING qualified_id - { $$ = $2; } - | USING global_scope qualified_id - { $$ = $3; } - | USING global_scope unqualified_id - { $$ = $3; } - ; - -namespace_using_decl: - USING namespace_qualifier identifier - { $$ = build_parse_node (SCOPE_REF, $2, $3); } - | USING global_scope identifier - { $$ = build_parse_node (SCOPE_REF, global_namespace, $3); } - | USING global_scope namespace_qualifier identifier - { $$ = build_parse_node (SCOPE_REF, $3, $4); } - ; - -using_directive: - USING NAMESPACE - { begin_only_namespace_names (); } - any_id ';' - { - end_only_namespace_names (); - /* If no declaration was found, the using-directive is - invalid. Since that was not reported, we need the - identifier for the error message. */ - if (TREE_CODE ($4) == IDENTIFIER_NODE && lastiddecl) - $4 = lastiddecl; - do_using_directive ($4); - } - ; - -namespace_qualifier: - NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - | namespace_qualifier NSNAME SCOPE - { - $$ = $2; - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - -any_id: - unqualified_id - | qualified_id - | global_scope qualified_id - { $$ = $2; } - | global_scope unqualified_id - { $$ = $2; } - ; - -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: - TEMPLATE '<' - { begin_template_parm_list (); } - template_parm_list '>' - { $$ = end_template_parm_list ($4); } - | TEMPLATE '<' '>' - { begin_specialization(); - $$ = NULL_TREE; } - ; - -template_parm_list: - template_parm - { $$ = process_template_parm (NULL_TREE, $1); } - | template_parm_list ',' template_parm - { $$ = process_template_parm ($1, $3); } - ; - -maybe_identifier: - identifier - { $$ = $1; } - | /* empty */ - { $$ = NULL_TREE; } - -template_type_parm: - aggr maybe_identifier - { $$ = finish_template_type_parm ($1, $2); } - | TYPENAME_KEYWORD maybe_identifier - { $$ = finish_template_type_parm (class_type_node, $2); } - ; - -template_template_parm: - template_header aggr maybe_identifier - { $$ = finish_template_template_parm ($2, $3); } - ; - -template_parm: - /* The following rules introduce a new reduce/reduce - conflict on the ',' and '>' input tokens: they are valid - prefixes for a `structsp', which means they could match a - nameless parameter. See 14.6, paragraph 3. - By putting them before the `parm' rule, we get - their match before considering them nameless parameter - declarations. */ - template_type_parm - { $$ = build_tree_list (NULL_TREE, $1); } - | template_type_parm '=' type_id - { $$ = build_tree_list (groktypename ($3.t), $1); } - | parm - { $$ = build_tree_list (NULL_TREE, $1.t); } - | parm '=' expr_no_commas %prec ARITHCOMPARE - { $$ = build_tree_list ($3, $1.t); } - | template_template_parm - { $$ = build_tree_list (NULL_TREE, $1); } - | template_template_parm '=' template_arg - { - if (TREE_CODE ($3) != TEMPLATE_DECL - && TREE_CODE ($3) != TEMPLATE_TEMPLATE_PARM - && TREE_CODE ($3) != TYPE_DECL) - { - error ("invalid default template argument"); - $3 = error_mark_node; - } - $$ = build_tree_list ($3, $1); - } - ; - -template_def: - 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: - nomods_initdecls ';' - | declmods notype_initdecls ';' - {} - | typed_declspecs initdecls ';' - { note_list_got_semicolon ($1.t); } - | declmods ';' - { pedwarn ("empty declaration"); } - | explicit_instantiation ';' - | typed_declspecs ';' - { - tree t, attrs; - split_specs_attrs ($1.t, &t, &attrs); - shadow_tag (t); - note_list_got_semicolon ($1.t); - } - | error ';' - | error '}' - | ';' - ; - -ctor_initializer_opt: - nodecls - { $$ = 0; } - | base_init - { $$ = 1; } - ; - -maybe_return_init: - /* empty */ - | return_init - | return_init ';' - ; - -eat_saved_input: - /* empty */ - | END_OF_SAVED_INPUT - ; - -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 - { } - ; - -constructor_declarator: - nested_name_specifier SELFNAME '(' - { $$ = begin_constructor_declarator ($1, $2); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } - | nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($1, $2); - $$ = make_call_declarator ($$, empty_parms (), $4, $5); - } - | global_scope nested_name_specifier SELFNAME '(' - { $$ = begin_constructor_declarator ($2, $3); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } - | global_scope nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($2, $3); - $$ = make_call_declarator ($$, empty_parms (), $5, $6); - } - | nested_name_specifier self_template_type '(' - { $$ = begin_constructor_declarator ($1, $2); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } - | nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($1, $2); - $$ = make_call_declarator ($$, empty_parms (), $4, $5); - } - | global_scope nested_name_specifier self_template_type '(' - { $$ = begin_constructor_declarator ($2, $3); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } - | global_scope nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($2, $3); - $$ = make_call_declarator ($$, empty_parms (), $5, $6); - } - ; - -fn.def1: - typed_declspecs declarator - { if (!begin_function_definition ($1.t, $2)) - YYERROR1; } - | declmods notype_declarator - { if (!begin_function_definition ($1, $2)) - YYERROR1; } - | notype_declarator - { if (!begin_function_definition (NULL_TREE, $1)) - YYERROR1; } - | declmods constructor_declarator - { if (!begin_function_definition ($1, $2)) - YYERROR1; } - | constructor_declarator - { if (!begin_function_definition (NULL_TREE, $1)) - YYERROR1; } - ; - -component_constructor_declarator: - SELFNAME '(' parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, $3, $5, $6); } - | SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } - | self_template_type '(' parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, $3, $5, $6); } - | self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } - ; - -/* more C++ complexity. See component_decl for a comment on the - reduce/reduce conflict introduced by these rules. */ -fn.def2: - declmods component_constructor_declarator - { 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; - if (yychar == YYEMPTY) - yychar = YYLEX; - reinit_parse_for_method (yychar, $$); } - | component_constructor_declarator - { $$ = start_method (NULL_TREE, $1, NULL_TREE); - goto rest_of_mdef; } - | typed_declspecs declarator - { 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, 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, $$, NULL_TREE); - goto rest_of_mdef; } - | declmods constructor_declarator - { 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, $$, NULL_TREE); - goto rest_of_mdef; } - ; - -return_id: - RETURN_KEYWORD IDENTIFIER - { - if (! current_function_parms_stored) - store_parm_decls (); - $$ = $2; - } - ; - -return_init: - return_id maybe_init - { store_return_init ($<ttype>$, $2); } - | return_id '(' nonnull_exprlist ')' - { store_return_init ($<ttype>$, $3); } - | return_id LEFT_RIGHT - { store_return_init ($<ttype>$, NULL_TREE); } - ; - -base_init: - ':' .set_base_init member_init_list - { - if ($3 == 0) - error ("no base initializers given following ':'"); - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - } - ; - -.set_base_init: - /* empty */ - { - if (! current_function_parms_stored) - store_parm_decls (); - - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - /* Make a contour for the initializer list. */ - pushlevel (0); - clear_last_expr (); - expand_start_bindings (0); - } - else if (current_class_type == NULL_TREE) - error ("base initializers not allowed for non-member functions"); - else if (! DECL_CONSTRUCTOR_P (current_function_decl)) - error ("only constructors take base initializers"); - } - ; - -member_init_list: - /* empty */ - { $$ = 0; } - | member_init - { $$ = 1; } - | member_init_list ',' member_init - | member_init_list error - ; - -member_init: - '(' nonnull_exprlist ')' - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - expand_member_init (current_class_ref, NULL_TREE, $2); - } - | LEFT_RIGHT - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - expand_member_init (current_class_ref, NULL_TREE, void_type_node); - } - | notype_identifier '(' nonnull_exprlist ')' - { expand_member_init (current_class_ref, $1, $3); } - | notype_identifier LEFT_RIGHT - { expand_member_init (current_class_ref, $1, void_type_node); } - | nonnested_type '(' nonnull_exprlist ')' - { expand_member_init (current_class_ref, $1, $3); } - | nonnested_type LEFT_RIGHT - { expand_member_init (current_class_ref, $1, void_type_node); } - | typename_sub '(' nonnull_exprlist ')' - { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), - $3); } - | typename_sub LEFT_RIGHT - { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), - void_type_node); } - ; - -identifier: - IDENTIFIER - | TYPENAME - | SELFNAME - | PTYPENAME - | NSNAME - ; - -notype_identifier: - IDENTIFIER - | PTYPENAME - | NSNAME %prec EMPTY - ; - -identifier_defn: - IDENTIFIER_DEFN - | TYPENAME_DEFN - | PTYPENAME_DEFN - ; - -explicit_instantiation: - TEMPLATE begin_explicit_instantiation typespec ';' - { do_type_instantiation ($3.t, NULL_TREE); - yyungetc (';', 1); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation typed_declspecs declarator - { tree specs = strip_attrs ($3.t); - do_decl_instantiation (specs, $4, NULL_TREE); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation notype_declarator - { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation constructor_declarator - { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation typespec ';' - { do_type_instantiation ($4.t, $1); - yyungetc (';', 1); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs - declarator - { tree specs = strip_attrs ($4.t); - do_decl_instantiation (specs, $5, $1); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator - { do_decl_instantiation (NULL_TREE, $4, $1); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator - { do_decl_instantiation (NULL_TREE, $4, $1); } - end_explicit_instantiation - ; - -begin_explicit_instantiation: - { begin_explicit_instantiation(); } - -end_explicit_instantiation: - { end_explicit_instantiation(); } - -/* The TYPENAME expansions are to deal with use of a template class name as - a template within the class itself, where the template decl is hidden by - a type decl. Got all that? */ - -template_type: - PTYPENAME '<' template_arg_list_opt template_close_bracket - .finish_template_type - { $$ = $5; } - | TYPENAME '<' template_arg_list_opt template_close_bracket - .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 - .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 - { - /* Handle `Class<Class<Type>>' without space in the `>>' */ - pedwarn ("`>>' should be `> >' in template class name"); - yyungetc ('>', 1); - } - ; - -template_arg_list_opt: - /* empty */ - { $$ = NULL_TREE; } - | template_arg_list - ; - -template_arg_list: - template_arg - { $$ = build_tree_list (NULL_TREE, $$); } - | template_arg_list ',' template_arg - { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } - ; - -template_arg: - type_id - { $$ = groktypename ($1.t); } - | PTYPENAME - { $$ = lastiddecl; } - | expr_no_commas %prec ARITHCOMPARE - ; - -unop: - '-' - { $$ = NEGATE_EXPR; } - | '+' - { $$ = CONVERT_EXPR; } - | PLUSPLUS - { $$ = PREINCREMENT_EXPR; } - | MINUSMINUS - { $$ = PREDECREMENT_EXPR; } - | '!' - { $$ = TRUTH_NOT_EXPR; } - ; - -expr: - nontrivial_exprlist - { $$ = build_x_compound_expr ($$); } - | expr_no_commas - ; - -paren_expr_or_null: - LEFT_RIGHT - { error ("ANSI C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - $$ = integer_zero_node; } - | '(' expr ')' - { $$ = $2; } - ; - -paren_cond_or_null: - LEFT_RIGHT - { error ("ANSI C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - $$ = integer_zero_node; } - | '(' condition ')' - { $$ = $2; } - ; - -xcond: - /* empty */ - { $$ = NULL_TREE; } - | condition - | error - { $$ = NULL_TREE; } - ; - -condition: - type_specifier_seq declarator maybeasm maybe_attribute '=' - { { - tree d; - for (d = getdecls (); d; d = TREE_CHAIN (d)) - if (TREE_CODE (d) == TYPE_DECL) { - tree s = TREE_TYPE (d); - if (TREE_CODE (s) == RECORD_TYPE) - cp_error ("definition of class `%T' in condition", s); - else if (TREE_CODE (s) == ENUMERAL_TYPE) - cp_error ("definition of enum `%T' in condition", s); - } - } - current_declspecs = $1.t; - $<itype>5 = suspend_momentary (); - $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, - $4, /*prefix_attributes*/ NULL_TREE); - } - init - { - cp_finish_decl ($<ttype>6, $7, $4, 1, LOOKUP_ONLYCONVERTING); - resume_momentary ($<itype>5); - $$ = convert_from_reference ($<ttype>6); - if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) - cp_error ("definition of array `%#D' in condition", $$); - } - | expr - ; - -compstmtend: - '}' - | maybe_label_decls stmts '}' - | maybe_label_decls stmts error '}' - | maybe_label_decls error '}' - ; - -already_scoped_stmt: - '{' - { $<ttype>$ = begin_compound_stmt (1); } - compstmtend - { finish_compound_stmt (1, $<ttype>2); } - | simple_stmt - ; - - -nontrivial_exprlist: - expr_no_commas ',' expr_no_commas - { $$ = expr_tree_cons (NULL_TREE, $$, - build_expr_list (NULL_TREE, $3)); } - | expr_no_commas ',' error - { $$ = expr_tree_cons (NULL_TREE, $$, - build_expr_list (NULL_TREE, error_mark_node)); } - | nontrivial_exprlist ',' expr_no_commas - { chainon ($$, build_expr_list (NULL_TREE, $3)); } - | nontrivial_exprlist ',' error - { chainon ($$, build_expr_list (NULL_TREE, error_mark_node)); } - ; - -nonnull_exprlist: - expr_no_commas - { $$ = build_expr_list (NULL_TREE, $$); } - | nontrivial_exprlist - ; - -unary_expr: - primary %prec UNARY - { $$ = $1; } - /* __extension__ turns off -pedantic for following primary. */ - | extension cast_expr %prec UNARY - { $$ = $2; - pedantic = $<itype>1; } - | '*' cast_expr %prec UNARY - { $$ = build_x_indirect_ref ($2, "unary *"); } - | '&' cast_expr %prec UNARY - { $$ = build_x_unary_op (ADDR_EXPR, $2); } - | '~' cast_expr - { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } - | unop cast_expr %prec UNARY - { $$ = finish_unary_op_expr ($1, $2); } - /* Refer to the address of a label as a pointer. */ - | ANDAND identifier - { if (pedantic) - pedwarn ("ANSI C++ forbids `&&'"); - $$ = finish_label_address_expr ($2); } - | SIZEOF unary_expr %prec UNARY - { $$ = expr_sizeof ($2); } - | SIZEOF '(' type_id ')' %prec HYPERUNARY - { $$ = c_sizeof (groktypename ($3.t)); - check_for_new_type ("sizeof", $3); } - | ALIGNOF unary_expr %prec UNARY - { $$ = grok_alignof ($2); } - | ALIGNOF '(' type_id ')' %prec HYPERUNARY - { $$ = c_alignof (groktypename ($3.t)); - check_for_new_type ("alignof", $3); } - - /* The %prec EMPTY's here are required by the = init initializer - syntax extension; see below. */ - | new new_type_id %prec EMPTY - { $$ = build_new (NULL_TREE, $2.t, NULL_TREE, $1); - check_for_new_type ("new", $2); } - | new new_type_id new_initializer - { $$ = build_new (NULL_TREE, $2.t, $3, $1); - check_for_new_type ("new", $2); } - | new new_placement new_type_id %prec EMPTY - { $$ = build_new ($2, $3.t, NULL_TREE, $1); - check_for_new_type ("new", $3); } - | new new_placement new_type_id new_initializer - { $$ = build_new ($2, $3.t, $4, $1); - check_for_new_type ("new", $3); } - /* The .begin_new_placement in the following rules is - necessary to avoid shift/reduce conflicts that lead to - mis-parsing some expressions. Of course, these constructs - are not really new-placement and it is bogus to call - begin_new_placement. But, the parser cannot always tell at this - point whether the next thing is an expression or a type-id, - so there is nothing we can do. Fortunately, - begin_new_placement does nothing harmful. When we rewrite - the parser, this lossage should be removed, of course. */ - | new '(' .begin_new_placement type_id .finish_new_placement - %prec EMPTY - { $$ = build_new (NULL_TREE, groktypename($4.t), - NULL_TREE, $1); - check_for_new_type ("new", $4); } - | new '(' .begin_new_placement type_id .finish_new_placement - new_initializer - { $$ = build_new (NULL_TREE, groktypename($4.t), $6, $1); - check_for_new_type ("new", $4); } - | new new_placement '(' .begin_new_placement type_id - .finish_new_placement %prec EMPTY - { $$ = build_new ($2, groktypename($5.t), NULL_TREE, $1); - check_for_new_type ("new", $5); } - | new new_placement '(' .begin_new_placement type_id - .finish_new_placement new_initializer - { $$ = build_new ($2, groktypename($5.t), $7, $1); - check_for_new_type ("new", $5); } - - | delete cast_expr %prec UNARY - { $$ = delete_sanity ($2, NULL_TREE, 0, $1); } - | delete '[' ']' cast_expr %prec UNARY - { $$ = delete_sanity ($4, NULL_TREE, 1, $1); - if (yychar == YYEMPTY) - yychar = YYLEX; } - | delete '[' expr ']' cast_expr %prec UNARY - { $$ = delete_sanity ($5, $3, 2, $1); - if (yychar == YYEMPTY) - yychar = YYLEX; } - | REALPART cast_expr %prec UNARY - { $$ = build_x_unary_op (REALPART_EXPR, $2); } - | IMAGPART cast_expr %prec UNARY - { $$ = build_x_unary_op (IMAGPART_EXPR, $2); } - ; - - /* Note this rule is not suitable for use in new_placement - since it uses NULL_TREE as the argument to - finish_new_placement. This rule serves only to avoid - reduce/reduce conflicts in unary_expr. See the comments - there on the use of begin/finish_new_placement. */ -.finish_new_placement: - ')' - { finish_new_placement (NULL_TREE, $<itype>-1); } - -.begin_new_placement: - { $$ = begin_new_placement (); } - -new_placement: - '(' .begin_new_placement nonnull_exprlist ')' - { $$ = finish_new_placement ($3, $2); } - | '{' .begin_new_placement nonnull_exprlist '}' - { cp_pedwarn ("old style placement syntax, use () instead"); - $$ = finish_new_placement ($3, $2); } - ; - -new_initializer: - '(' nonnull_exprlist ')' - { $$ = $2; } - | LEFT_RIGHT - { $$ = NULL_TREE; } - | '(' typespec ')' - { - cp_error ("`%T' is not a valid expression", $2.t); - $$ = error_mark_node; - } - /* GNU extension so people can use initializer lists. Note that - this alters the meaning of `new int = 1', which was previously - syntactically valid but semantically invalid. */ - | '=' init - { - if (pedantic) - pedwarn ("ANSI C++ forbids initialization of new expression with `='"); - if (TREE_CODE ($2) != TREE_LIST - && TREE_CODE ($2) != CONSTRUCTOR) - $$ = build_expr_list (NULL_TREE, $2); - else - $$ = $2; - } - ; - -/* This is necessary to postpone reduction of `int ((int)(int)(int))'. */ -regcast_or_absdcl: - '(' type_id ')' %prec EMPTY - { $2.t = finish_parmlist (build_tree_list (NULL_TREE, $2.t), 0); - $$ = make_call_declarator (NULL_TREE, $2.t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", $2); } - | regcast_or_absdcl '(' type_id ')' %prec EMPTY - { $3.t = finish_parmlist (build_tree_list (NULL_TREE, $3.t), 0); - $$ = make_call_declarator ($$, $3.t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", $3); } - ; - -cast_expr: - 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 (pedantic) - pedwarn ("ANSI C++ forbids constructor-expressions"); - /* Indicate that this was a GNU C constructor expression. */ - TREE_HAS_CONSTRUCTOR (init) = 1; - - $$ = reparse_absdcl_as_casts ($$, init); - } - ; - -expr_no_commas: - cast_expr - /* Handle general members. */ - | expr_no_commas POINTSAT_STAR expr_no_commas - { $$ = build_x_binary_op (MEMBER_REF, $$, $3); } - | expr_no_commas DOT_STAR expr_no_commas - { $$ = build_m_component_ref ($$, $3); } - | expr_no_commas '+' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '-' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '*' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '/' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '%' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas LSHIFT expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas RSHIFT expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas ARITHCOMPARE expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '<' expr_no_commas - { $$ = build_x_binary_op (LT_EXPR, $$, $3); } - | expr_no_commas '>' expr_no_commas - { $$ = build_x_binary_op (GT_EXPR, $$, $3); } - | expr_no_commas EQCOMPARE expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas MIN_MAX expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '&' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '|' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '^' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas ANDAND expr_no_commas - { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } - | expr_no_commas OROR expr_no_commas - { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } - | expr_no_commas '?' xexpr ':' expr_no_commas - { $$ = build_x_conditional_expr ($$, $3, $5); } - | expr_no_commas '=' expr_no_commas - { $$ = build_x_modify_expr ($$, NOP_EXPR, $3); - if ($$ != error_mark_node) - C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } - | expr_no_commas ASSIGN expr_no_commas - { $$ = build_x_modify_expr ($$, $2, $3); } - | THROW - { $$ = build_throw (NULL_TREE); } - | THROW expr_no_commas - { $$ = build_throw ($2); } -/* These extensions are not defined. The second arg to build_m_component_ref - is old, build_m_component_ref now does an implicit - build_indirect_ref (x, NULL_PTR) on the second argument. - | object '&' expr_no_commas %prec UNARY - { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); } - | object unop expr_no_commas %prec UNARY - { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); } - | object '(' type_id ')' expr_no_commas %prec UNARY - { tree type = groktypename ($3.t); - $$ = build_m_component_ref ($$, build_c_cast (type, $5)); } - | object primary_no_id %prec UNARY - { $$ = build_m_component_ref ($$, $2); } -*/ - ; - -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 - | PTYPENAME - | NSNAME %prec EMPTY - ; - -do_id: - { - /* 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 - { $$ = lookup_template_function ($3, $4); } - | operator_name '<' do_id template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($3, $4); } - ; - -object_template_id: - TEMPLATE identifier '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($2, $4); } - | TEMPLATE PFUNCNAME '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($2, $4); } - | TEMPLATE operator_name '<' template_arg_list_opt - template_close_bracket - { $$ = lookup_template_function ($2, $4); } - ; - -unqualified_id: - notype_unqualified_id - | TYPENAME - | 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_intern %prec UNARY - { $$ = build_parse_node (INDIRECT_REF, $2); } - | '&' expr_or_declarator_intern %prec UNARY - { $$ = build_parse_node (ADDR_EXPR, $2); } - | '(' expr_or_declarator_intern ')' - { $$ = $2; } - ; - -notype_template_declarator: - IDENTIFIER '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($1, $3); } - | NSNAME '<' template_arg_list template_close_bracket - { $$ = lookup_template_function ($1, $3); } - ; - -direct_notype_declarator: - complex_direct_notype_declarator - /* This precedence declaration is to prefer this reduce - to the Koenig lookup shift in primary, below. I hate yacc. */ - | notype_unqualified_id %prec '(' - | notype_template_declarator - | '(' expr_or_declarator_intern ')' - { $$ = finish_decl_parsing ($2); } - ; - -primary: - notype_unqualified_id - { - if (TREE_CODE ($1) == BIT_NOT_EXPR) - $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($1, 0)); - else - $$ = finish_id_expr ($1); - } - | CONSTANT - | boolean.literal - | string - { - 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_intern ')' - { $2 = reparse_decl_as_expr (NULL_TREE, $2); - $$ = finish_parenthesized_expr ($2); } - | '(' error ')' - { $$ = error_mark_node; } - | '(' - { tree scope = current_scope (); - if (!scope || TREE_CODE (scope) != FUNCTION_DECL) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); - $<ttype>$ = begin_stmt_expr (); - } - compstmt ')' - { $$ = finish_stmt_expr ($<ttype>2, $3); } - /* Koenig lookup support - We could store lastiddecl in $1 to avoid another lookup, - but that would result in many additional reduce/reduce conflicts. */ - | notype_unqualified_id '(' nonnull_exprlist ')' - { $$ = finish_call_expr ($1, $3, 1); } - | notype_unqualified_id LEFT_RIGHT - { $$ = finish_call_expr ($1, NULL_TREE, 1); } - | primary '(' nonnull_exprlist ')' - { $$ = finish_call_expr ($1, $3, 0); } - | primary LEFT_RIGHT - { $$ = finish_call_expr ($1, NULL_TREE, 0); } - | primary '[' expr ']' - { $$ = grok_array_decl ($$, $3); } - | primary PLUSPLUS - { $$ = finish_increment_expr ($1, POSTINCREMENT_EXPR); } - | primary MINUSMINUS - { $$ = finish_increment_expr ($1, POSTDECREMENT_EXPR); } - /* C++ extensions */ - | THIS - { $$ = finish_this_expr (); } - | CV_QUALIFIER '(' nonnull_exprlist ')' - { - /* 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; - - if ($3 == error_mark_node) - { - $$ = error_mark_node; - break; - } - - 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 ')' - { tree type = groktypename ($3.t); - check_for_new_type ("dynamic_cast", $3); - $$ = build_dynamic_cast (type, $6); } - | STATIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("static_cast", $3); - $$ = build_static_cast (type, $6); } - | REINTERPRET_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("reinterpret_cast", $3); - $$ = build_reinterpret_cast (type, $6); } - | CONST_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("const_cast", $3); - $$ = build_const_cast (type, $6); } - | TYPEID '(' expr ')' - { $$ = build_x_typeid ($3); } - | TYPEID '(' type_id ')' - { tree type = groktypename ($3.t); - check_for_new_type ("typeid", $3); - $$ = get_typeid (TYPE_MAIN_VARIANT (type)); } - | global_scope IDENTIFIER - { $$ = do_scoped_id ($2, 1); } - | global_scope template_id - { $$ = $2; } - | global_scope operator_name - { - got_scope = NULL_TREE; - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = do_scoped_id ($2, 1); - else - $$ = $2; - } - | overqualified_id %prec HYPERUNARY - { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } - | overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_qualified_call_expr ($1, $3); } - | overqualified_id LEFT_RIGHT - { $$ = finish_qualified_call_expr ($1, NULL_TREE); } - | object object_template_id %prec UNARY - { - $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); - } - | object object_template_id '(' nonnull_exprlist ')' - { $$ = finish_object_call_expr ($2, $1, $4); } - | object object_template_id LEFT_RIGHT - { $$ = finish_object_call_expr ($2, $1, NULL_TREE); } - | object unqualified_id %prec UNARY - { $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); } - | object overqualified_id %prec UNARY - { if (processing_template_decl) - $$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2)); - else - $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } - | object unqualified_id '(' nonnull_exprlist ')' - { $$ = finish_object_call_expr ($2, $1, $4); } - | object unqualified_id LEFT_RIGHT - { $$ = finish_object_call_expr ($2, $1, NULL_TREE); } - | object overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_qualified_object_call_expr ($2, $1, $4); } - | object overqualified_id LEFT_RIGHT - { $$ = finish_qualified_object_call_expr ($2, $1, NULL_TREE); } - /* p->int::~int() is valid -- 12.4 */ - | object '~' TYPESPEC LEFT_RIGHT - { $$ = finish_pseudo_destructor_call_expr ($1, NULL_TREE, $3); } - | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT - { $$ = finish_pseudo_destructor_call_expr ($1, $2, $5); } - | object error - { - $$ = error_mark_node; - } - ; - -/* Not needed for now. - -primary_no_id: - '(' expr ')' - { $$ = $2; } - | '(' error ')' - { $$ = error_mark_node; } - | '(' - { if (current_function_decl == 0) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - $<ttype>$ = expand_start_stmt_expr (); } - compstmt ')' - { if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); - $$ = expand_end_stmt_expr ($<ttype>2); } - | primary_no_id '(' nonnull_exprlist ')' - { $$ = build_x_function_call ($$, $3, current_class_ref); } - | primary_no_id LEFT_RIGHT - { $$ = build_x_function_call ($$, NULL_TREE, current_class_ref); } - | primary_no_id '[' expr ']' - { goto do_array; } - | primary_no_id PLUSPLUS - { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } - | primary_no_id MINUSMINUS - { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } - | SCOPE IDENTIFIER - { goto do_scoped_id; } - | SCOPE operator_name - { if (TREE_CODE ($2) == IDENTIFIER_NODE) - goto do_scoped_id; - goto do_scoped_operator; - } - ; -*/ - -new: - NEW - { $$ = 0; } - | global_scope NEW - { got_scope = NULL_TREE; $$ = 1; } - ; - -delete: - DELETE - { $$ = 0; } - | global_scope delete - { got_scope = NULL_TREE; $$ = 1; } - ; - -boolean.literal: - CXX_TRUE - { $$ = boolean_true_node; } - | CXX_FALSE - { $$ = boolean_false_node; } - ; - -/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ -string: - STRING - | string STRING - { $$ = chainon ($$, $2); } - ; - -nodecls: - /* empty */ - { - if (! current_function_parms_stored) - store_parm_decls (); - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - } - ; - -object: - primary '.' - { got_object = TREE_TYPE ($$); } - | primary POINTSAT - { - $$ = build_x_arrow ($$); - got_object = TREE_TYPE ($$); - } - ; - -decl: - typespec initdecls ';' - { - resume_momentary ($2); - if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t))) - note_got_semicolon ($1.t); - } - | typed_declspecs initdecls ';' - { - resume_momentary ($2); - note_list_got_semicolon ($1.t); - } - | declmods notype_initdecls ';' - { resume_momentary ($2); } - | typed_declspecs ';' - { - shadow_tag ($1.t); - note_list_got_semicolon ($1.t); - } - | declmods ';' - { warning ("empty declaration"); } - | extension decl - { pedantic = $<itype>1; } - ; - -/* Any kind of declarator (thus, all declarators allowed - after an explicit typespec). */ - -declarator: - after_type_declarator %prec EMPTY - | notype_declarator %prec EMPTY - ; - -/* This is necessary to postpone reduction of `int()()()()'. */ -fcast_or_absdcl: - LEFT_RIGHT %prec EMPTY - { $$ = make_call_declarator (NULL_TREE, empty_parms (), - NULL_TREE, NULL_TREE); } - | fcast_or_absdcl LEFT_RIGHT %prec EMPTY - { $$ = make_call_declarator ($$, empty_parms (), NULL_TREE, - NULL_TREE); } - ; - -/* ANSI type-id (8.1) */ -type_id: - typed_typespecs absdcl - { $$.t = build_decl_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers absdcl - { $$.t = build_decl_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec absdcl - { $$.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); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers %prec EMPTY - { $$.t = build_decl_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - ; - -/* 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. - 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 - { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1); - $$.new_type_flag = $2.new_type_flag; } - | typespec reserved_declspecs %prec HYPERUNARY - { $$.t = decl_tree_cons (NULL_TREE, $1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec reserved_typespecquals reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $1.t, chainon ($2, $3)); - $$.new_type_flag = $1.new_type_flag; } - | declmods typespec reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); - $$.new_type_flag = $2.new_type_flag; } - | declmods typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); - $$.new_type_flag = $2.new_type_flag; } - | declmods typespec reserved_typespecquals reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $2.t, - chainon ($3, chainon ($4, $1))); - $$.new_type_flag = $2.new_type_flag; } - ; - -reserved_declspecs: - SCSPEC - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($$)); - $$ = build_decl_list (NULL_TREE, $$); } - | reserved_declspecs typespecqual_reserved - { $$ = decl_tree_cons (NULL_TREE, $2.t, $$); } - | reserved_declspecs SCSPEC - { if (extra_warnings) - 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. - 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 - { $$ = hash_tree_cons (NULL_TREE, $$, NULL_TREE); } - | declmods CV_QUALIFIER - { $$ = 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)); - $$ = hash_tree_cons (NULL_TREE, $2, $$); - TREE_STATIC ($$) = TREE_STATIC ($1); } - | declmods attributes - { $$ = 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 - (that is, for typenames and structure components). - - C++ can takes storage classes for structure components. - Don't accept a typedef-name if anything but a modifier precedes it. */ - -typed_typespecs: - typespec %prec EMPTY - { $$.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); - $$.new_type_flag = $2.new_type_flag; } - | typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); - $$.new_type_flag = $1.new_type_flag; } - ; - -reserved_typespecquals: - typespecqual_reserved - { $$ = build_decl_list (NULL_TREE, $1.t); } - | reserved_typespecquals typespecqual_reserved - { $$ = decl_tree_cons (NULL_TREE, $2.t, $1); } - ; - -/* A typespec (but not a type qualifier). - Once we have seen one of these in a declaration, - if a typedef name appears then it is being redeclared. */ - -typespec: - structsp - | TYPESPEC %prec EMPTY - { $$.t = $1; $$.new_type_flag = 0; } - | complete_type_name - { $$.t = $1; $$.new_type_flag = 0; } - | TYPEOF '(' expr ')' - { $$.t = finish_typeof ($3); - $$.new_type_flag = 0; } - | TYPEOF '(' type_id ')' - { $$.t = groktypename ($3.t); - $$.new_type_flag = 0; } - | SIGOF '(' expr ')' - { tree type = TREE_TYPE ($3); - - $$.new_type_flag = 0; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - $$.t = type; - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$.t = error_mark_node; - } - } - | SIGOF '(' type_id ')' - { tree type = groktypename ($3.t); - - $$.new_type_flag = 0; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - $$.t = type; - } - else - { - error("`sigof' applied to non-aggregate type"); - $$.t = error_mark_node; - } - } - ; - -/* A typespec that is a reserved word, or a type qualifier. */ - -typespecqual_reserved: - TYPESPEC - { $$.t = $1; $$.new_type_flag = 0; } - | CV_QUALIFIER - { $$.t = $1; $$.new_type_flag = 0; } - | structsp - ; - -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: - /* empty */ - { $$ = NULL_TREE; } - | asm_keyword '(' string ')' - { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } - ; - -initdcl: - declarator maybeasm maybe_attribute '=' - { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, - $3, prefix_attributes); } - init -/* Note how the declaration of the variable is in effect while its init is parsed! */ - { cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); } - | declarator maybeasm maybe_attribute - { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, - $3, prefix_attributes); - cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); } - ; - - /* This rule assumes a certain configuration of the parser stack. - In particular, $0, the element directly before the beginning of - this rule on the stack, must be a maybeasm. $-1 must be a - declarator or notype_declarator. And $-2 must be some declmods - or declspecs. We can't move the maybeasm into this rule because - we need that reduce so we prefer fn.def1 when appropriate. */ -initdcl0_innards: - maybe_attribute '=' - { $<itype>2 = parse_decl ($<ttype>-1, $<ttype>-2, - $1, 1, &$<ttype>$); } - /* Note how the declaration of the variable is in effect - while its init is parsed! */ - init - { cp_finish_decl ($<ttype>3, $4, $<ttype>0, 1, - LOOKUP_ONLYCONVERTING); - $$ = $<itype>2; } - | maybe_attribute - { tree d; - $$ = parse_decl ($<ttype>-1, $<ttype>-2, $1, 0, &d); - cp_finish_decl (d, NULL_TREE, $<ttype>0, 1, 0); } - ; - -initdcl0: - declarator maybeasm initdcl0_innards - { $$ = $3; } - -notype_initdcl0: - notype_declarator maybeasm initdcl0_innards - { $$ = $3; } - ; - -nomods_initdcl0: - notype_declarator maybeasm - { /* Set things up as initdcl0_innards expects. */ - $<ttype>2 = $1; - $1 = NULL_TREE; } - initdcl0_innards - {} - | constructor_declarator maybeasm maybe_attribute - { tree d; - parse_decl($1, NULL_TREE, $3, 0, &d); - cp_finish_decl (d, NULL_TREE, $2, 1, 0); } - ; - -/* the * rules are dummies to accept the Apollo extended syntax - so that the header files compile. */ -maybe_attribute: - /* empty */ - { $$ = NULL_TREE; } - | attributes - { $$ = $1; } - ; - -attributes: - attribute - { $$ = $1; } - | attributes attribute - { $$ = chainon ($1, $2); } - ; - -attribute: - ATTRIBUTE '(' '(' attribute_list ')' ')' - { $$ = $4; } - ; - -attribute_list: - attrib - { $$ = $1; } - | attribute_list ',' attrib - { $$ = chainon ($1, $3); } - ; - -attrib: - /* empty */ - { $$ = NULL_TREE; } - | any_word - { $$ = build_tree_list ($1, NULL_TREE); } - | any_word '(' IDENTIFIER ')' - { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } - | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' - { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } - | any_word '(' nonnull_exprlist ')' - { $$ = build_tree_list ($1, $3); } - ; - -/* This still leaves out most reserved keywords, - shouldn't we include them? */ - -any_word: - identifier - | SCSPEC - | TYPESPEC - | CV_QUALIFIER - ; - -/* A nonempty list of identifiers, including typenames. */ -identifiers_or_typenames: - identifier - { $$ = build_tree_list (NULL_TREE, $1); } - | identifiers_or_typenames ',' identifier - { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } - ; - -maybe_init: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | '=' init - { $$ = $2; } - -/* If we are processing a template, we don't want to expand this - initializer yet. */ - -init: - expr_no_commas %prec '=' - | '{' '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | '{' initlist '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | '{' initlist ',' '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | error - { $$ = NULL_TREE; } - ; - -/* This chain is built in reverse order, - and put in forward order where initlist is used. */ -initlist: - init - { $$ = build_tree_list (NULL_TREE, $$); } - | initlist ',' init - { $$ = expr_tree_cons (NULL_TREE, $3, $$); } - /* These are for labeled elements. */ - | '[' expr_no_commas ']' init - { $$ = build_expr_list ($2, $4); } - | identifier ':' init - { $$ = build_expr_list ($$, $3); } - | initlist ',' identifier ':' init - { $$ = expr_tree_cons ($3, $5, $$); } - ; - -fn.defpen: - PRE_PARSED_FUNCTION_DECL - { start_function (NULL_TREE, TREE_VALUE ($1), - NULL_TREE, 2); - reinit_parse_for_function (); } - -pending_inline: - fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3 | 2, nested); - process_next_inline ($1); - } - | fn.defpen maybe_return_init function_try_block - { - 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); } - ; - -pending_inlines: - /* empty */ - | pending_inlines pending_inline eat_saved_input - ; - -/* A regurgitated default argument. The value of DEFARG_MARKER will be - the TREE_LIST node for the parameter in question. */ -defarg_again: - DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT - { replace_defarg ($1, $2); } - | DEFARG_MARKER error END_OF_SAVED_INPUT - { replace_defarg ($1, error_mark_node); } - -pending_defargs: - /* empty */ %prec EMPTY - | pending_defargs defarg_again - { do_pending_defargs (); } - | pending_defargs error - { do_pending_defargs (); } - ; - -structsp: - ENUM identifier '{' - { $<itype>3 = suspend_momentary (); - $<ttype>$ = current_enum_type; - current_enum_type = start_enum ($2); } - enumlist maybecomma_warn '}' - { 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 ($$.t); } - | ENUM identifier '{' '}' - { $$.t = finish_enum (start_enum ($2)); - $$.new_type_flag = 1; - check_for_missing_semicolon ($$.t); } - | ENUM '{' - { $<itype>2 = suspend_momentary (); - $<ttype>$ = current_enum_type; - current_enum_type = start_enum (make_anon_name ()); } - enumlist maybecomma_warn '}' - { 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 ($$.t); } - | ENUM '{' '}' - { $$.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, 1); - $$.new_type_flag = 0; } - | ENUM complex_type_name - { $$.t = xref_tag (enum_type_node, $2, 1); - $$.new_type_flag = 0; } - | TYPENAME_KEYWORD typename_sub - { $$.t = $2; - $$.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 '{' - { $1.t = begin_class_definition ($1.t); } - opt.component_decl_list '}' maybe_attribute - { - int semi; - - if (yychar == YYEMPTY) - yychar = YYLEX; - semi = yychar == ';'; - - $<ttype>$ = finish_class_definition ($1.t, $6, semi, - $1.new_type_flag); - } - pending_defargs - { - begin_inline_definitions (); - } - pending_inlines - { - finish_inline_definitions (); - $$.t = $<ttype>7; - $$.new_type_flag = 1; - } - | 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.t) == NULL_TREE) - { - cp_error ("%T is not a class type", $1.t); - $$.t = error_mark_node; - } - else - { - $$.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)) - cp_error ("base clause without member specification for `%#T'", - $$.t); - } - } - ; - -maybecomma: - /* empty */ - | ',' - ; - -maybecomma_warn: - /* empty */ - | ',' - { if (pedantic && !in_system_header) - pedwarn ("comma at end of enumerator list"); } - ; - -aggr: - AGGR - | aggr SCSPEC - { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr TYPESPEC - { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr CV_QUALIFIER - { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr AGGR - { error ("no body nor ';' separates two class, struct or union declarations"); } - | aggr attributes - { $$ = build_decl_list ($2, $1); } - ; - -named_class_head_sans_basetype: - aggr identifier - { - current_aggr = $1; - $$ = $2; - } - ; - -named_class_head_sans_basetype_defn: - aggr identifier_defn %prec EMPTY - { current_aggr = $$; $$ = $2; } - | named_class_head_sans_basetype '{' - { yyungetc ('{', 1); } - | named_class_head_sans_basetype ':' - { yyungetc (':', 1); } - ; - -named_complex_class_head_sans_basetype: - aggr nested_name_specifier identifier - { - current_aggr = $1; - $$.t = handle_class_head ($1, $2, $3); - $$.new_type_flag = 1; - } - | aggr global_scope nested_name_specifier identifier - { - current_aggr = $1; - $$.t = handle_class_head ($1, $3, $4); - $$.new_type_flag = 1; - } - | aggr global_scope identifier - { - current_aggr = $1; - $$.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; - } - ; - -named_class_head: - named_class_head_sans_basetype %prec EMPTY - { - $$.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 - { - $$.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 - { - if ($1.t != error_mark_node) - { - $$.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); - } - } - } - ; - -unnamed_class_head: - aggr '{' - { $$ = 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 - ; - -maybe_base_class_list: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | ':' see_typename %prec EMPTY - { yyungetc(':', 1); $$ = NULL_TREE; } - | ':' see_typename base_class_list %prec EMPTY - { $$ = $3; } - ; - -base_class_list: - base_class - | base_class_list ',' see_typename base_class - { $$ = chainon ($$, $4); } - ; - -base_class: - base_class.1 - { $$ = finish_base_specifier (access_default_node, $1, - current_aggr - == signature_type_node); } - | base_class_access_list see_typename base_class.1 - { $$ = finish_base_specifier ($1, $3, - current_aggr - == signature_type_node); } - ; - -base_class.1: - typename_sub - { if ($$ != error_mark_node) $$ = TYPE_MAIN_DECL ($1); } - | nonnested_type - | SIGOF '(' expr ')' - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (TREE_TYPE ($3))) - { - sorry ("`sigof' as base signature specifier"); - $$ = TREE_TYPE ($3); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$ = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - $$ = error_mark_node; - } - } - | SIGOF '(' type_id ')' - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (groktypename ($3.t))) - { - sorry ("`sigof' as base signature specifier"); - $$ = groktypename ($3.t); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$ = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - $$ = error_mark_node; - } - } - ; - -base_class_access_list: - VISSPEC see_typename - | SCSPEC see_typename - { if ($1 != ridpointers[(int)RID_VIRTUAL]) - cp_error ("`%D' access", $1); - $$ = access_default_virtual_node; } - | base_class_access_list VISSPEC see_typename - { - if ($1 != access_default_virtual_node) - error ("multiple access specifiers"); - else if ($2 == access_public_node) - $$ = access_public_virtual_node; - else if ($2 == access_protected_node) - $$ = access_protected_virtual_node; - else /* $2 == access_private_node */ - $$ = access_private_virtual_node; - } - | base_class_access_list SCSPEC see_typename - { if ($2 != ridpointers[(int)RID_VIRTUAL]) - cp_error ("`%D' access", $2); - else if ($$ == access_public_node) - $$ = access_public_virtual_node; - else if ($$ == access_protected_node) - $$ = access_protected_virtual_node; - else if ($$ == access_private_node) - $$ = access_private_virtual_node; - else - error ("multiple `virtual' specifiers"); - } - ; - -opt.component_decl_list: - | 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"); - $1 = access_public_node; - } - - 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 - { - finish_member_declaration ($1); - } - | component_decl_list component_decl - { - finish_member_declaration ($2); - } - ; - -component_decl: - component_decl_1 ';' - | component_decl_1 '}' - { error ("missing ';' before right brace"); - yyungetc ('}', 0); } - /* C++: handle constructors, destructors and inline functions */ - /* 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_KEYWORD /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn.def2 '{' /* nodecls compstmt */ - { $$ = finish_method ($$); } - | ';' - { $$ = NULL_TREE; } - | extension component_decl - { $$ = $2; - pedantic = $<itype>1; } - | template_header component_decl - { - 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 ($2.t); - finish_template_decl ($1); - } - ; - -component_decl_1: - /* Do not add a "typed_declspecs declarator" rule here for - speed; we need to call grok_x_components for enums, so the - speedup would be insignificant. */ - typed_declspecs components - { - /* 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 - { - 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)); } - | constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } - | ':' expr_no_commas - { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } - | error - { $$ = NULL_TREE; } - - /* These rules introduce a reduce/reduce conflict; in - typedef int foo, bar; - class A { - foo (bar); - }; - 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? */ - | declmods component_constructor_declarator maybeasm maybe_attribute maybe_init - { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); - $$ = grokfield ($2, specs, $5, $3, - build_tree_list ($4, attrs)); } - | component_constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } - | using_decl - { $$ = do_class_using_decl ($1); } - -/* The case of exactly one component is handled directly by component_decl. */ -/* ??? Huh? ^^^ */ -components: - /* empty: possibly anonymous */ - { $$ = 0; } - | component_declarator0 - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $1 = finish_member_template_decl ($1); - finish_member_declaration ($1); - $$ = 1; - } - | components ',' component_declarator - { - 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 */ - { $$ = 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 - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $3 = finish_member_template_decl ($3); - finish_member_declaration ($3); - $$ = 2; - } - ; - -component_declarator0: - after_type_component_declarator0 - | notype_component_declarator0 - ; - -component_declarator: - after_type_component_declarator - | notype_component_declarator - ; - -after_type_component_declarator0: - after_type_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | TYPENAME ':' expr_no_commas maybe_attribute - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - ; - -notype_component_declarator0: - notype_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | constructor_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | IDENTIFIER ':' expr_no_commas maybe_attribute - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - | ':' expr_no_commas maybe_attribute - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3, prefix_attributes); } - ; - -after_type_component_declarator: - after_type_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | TYPENAME ':' expr_no_commas maybe_attribute - { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - ; - -notype_component_declarator: - notype_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | IDENTIFIER ':' expr_no_commas maybe_attribute - { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - | ':' expr_no_commas maybe_attribute - { $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3, prefix_attributes); } - ; - -/* We chain the enumerators in reverse order. - Because of the way enums are built, the order is - insignificant. Take advantage of this fact. */ - -enumlist: - enumerator - | enumlist ',' enumerator - { TREE_CHAIN ($3) = $$; $$ = $3; } - ; - -enumerator: - identifier - { $$ = build_enumerator ($$, NULL_TREE, current_enum_type); } - | identifier '=' expr_no_commas - { $$ = build_enumerator ($$, $3, current_enum_type); } - ; - -/* ANSI new-type-id (5.3.4) */ -new_type_id: - type_specifier_seq new_declarator - { $$.t = build_decl_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | type_specifier_seq %prec EMPTY - { $$.t = build_decl_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - /* GNU extension to allow arrays of arbitrary types with - non-constant dimension. For the use of begin_new_placement - here, see the comments in unary_expr above. */ - | '(' .begin_new_placement type_id .finish_new_placement - '[' expr ']' - { - if (pedantic) - pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new"); - $$.t = build_parse_node (ARRAY_REF, TREE_VALUE ($3.t), $6); - $$.t = build_decl_list (TREE_PURPOSE ($3.t), $$.t); - $$.new_type_flag = $3.new_type_flag; - } - ; - -cv_qualifiers: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | cv_qualifiers CV_QUALIFIER - { $$ = decl_tree_cons (NULL_TREE, $2, $$); } - ; - -nonempty_cv_qualifiers: - CV_QUALIFIER - { $$.t = hash_tree_cons (NULL_TREE, $1, NULL_TREE); - $$.new_type_flag = 0; } - | nonempty_cv_qualifiers CV_QUALIFIER - { $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); - $$.new_type_flag = $1.new_type_flag; } - ; - -/* These rules must follow the rules for function declarations - and component declarations. That way, longer rules are preferred. */ - -suspend_mom: - /* empty */ - { $<itype>$ = suspend_momentary (); } - -/* An expression which will not live on the momentary obstack. */ -nonmomentary_expr: - suspend_mom expr - { resume_momentary ((int) $<itype>1); $$ = $2; } - ; - -/* An expression which will not live on the momentary obstack. */ -maybe_parmlist: - suspend_mom '(' nonnull_exprlist ')' - { resume_momentary ((int) $<itype>1); $$ = $3; } - | suspend_mom '(' parmlist ')' - { resume_momentary ((int) $<itype>1); $$ = $3; } - | suspend_mom LEFT_RIGHT - { resume_momentary ((int) $<itype>1); $$ = empty_parms (); } - | suspend_mom '(' error ')' - { resume_momentary ((int) $<itype>1); $$ = NULL_TREE; } - ; - -/* A declarator that is allowed only after an explicit typespec. */ - -after_type_declarator_intern: - after_type_declarator - | attributes after_type_declarator - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = decl_tree_cons ($1, $2, NULL_TREE); - } - ; - -/* may all be followed by prec '.' */ -after_type_declarator: - '*' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' after_type_declarator_intern %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' after_type_declarator_intern %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | 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); - maybe_note_name_used_in_class ($1, $$); - } - else - $$ = $1; - } - | global_scope type_name - { - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = IDENTIFIER_GLOBAL_VALUE ($2); - else - $$ = $2; - got_scope = NULL_TREE; - } - ; - -complete_type_name: - nonnested_type - | nested_type - | global_scope nested_type - { $$ = $2; } - ; - -nested_type: - nested_name_specifier type_name %prec EMPTY - { $$ = get_type_decl ($2); } - ; - -/* 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_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_notype_declarator - ; - -complex_notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' 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_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | complex_direct_notype_declarator - ; - -complex_direct_notype_declarator: - direct_notype_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | '(' 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 - { enter_scope_of ($1); } - | nested_name_specifier notype_template_declarator - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $1, $2); - enter_scope_of ($$); - } - ; - -qualified_id: - nested_name_specifier unqualified_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $$, $2); } - | nested_name_specifier object_template_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $1, $2); } - ; - -notype_qualified_id: - nested_name_specifier notype_unqualified_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $$, $2); } - | nested_name_specifier object_template_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $1, $2); } - ; - -overqualified_id: - notype_qualified_id - | global_scope notype_qualified_id - { $$ = $2; } - ; - -functional_cast: - typespec '(' nonnull_exprlist ')' - { $$ = build_functional_cast ($1.t, $3); } - | 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 - | template_type %prec EMPTY - ; - -nested_name_specifier: - nested_name_specifier_1 - | nested_name_specifier nested_name_specifier_1 - { $$ = $2; } - | nested_name_specifier TEMPLATE explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $3); } - ; - -/* Why the @#$%^& do type_name and notype_identifier need to be expanded - inline here?!? (jason) */ -nested_name_specifier_1: - TYPENAME SCOPE - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - { - $$ = lastiddecl; - maybe_note_name_used_in_class ($1, $$); - } - got_scope = $$ = - complete_type (TYPE_MAIN_VARIANT (TREE_TYPE ($$))); - } - | SELFNAME SCOPE - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$ = TREE_TYPE ($$); - } - | NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - | template_type SCOPE - { got_scope = $$ = complete_type (TREE_TYPE ($1)); } -/* These break 'const i;' - | IDENTIFIER SCOPE - { - failed_scope: - cp_error ("`%D' is not an aggregate typedef", - lastiddecl ? lastiddecl : $$); - $$ = error_mark_node; - } - | PTYPENAME SCOPE - { goto failed_scope; } */ - ; - -typename_sub: - typename_sub0 - | global_scope typename_sub0 - { $$ = $2; } - ; - -typename_sub0: - typename_sub1 identifier %prec EMPTY - { - if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't') - $$ = make_typename_type ($1, $2); - else if (TREE_CODE ($2) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", $2); - else - { - $$ = $2; - if (TREE_CODE ($$) == TYPE_DECL) - $$ = TREE_TYPE ($$); - } - } - | typename_sub1 template_type %prec EMPTY - { $$ = TREE_TYPE ($2); } - | typename_sub1 explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $2); } - | typename_sub1 TEMPLATE explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $3); } - ; - -typename_sub1: - typename_sub2 - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", $1); - } - | typename_sub1 typename_sub2 - { - if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't') - $$ = make_typename_type ($1, $2); - else if (TREE_CODE ($2) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", $2); - else - { - $$ = $2; - if (TREE_CODE ($$) == TYPE_DECL) - $$ = TREE_TYPE ($$); - } - } - | typename_sub1 explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $2); } - | typename_sub1 TEMPLATE explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $3); } - ; - -typename_sub2: - TYPENAME SCOPE - { - if (TREE_CODE ($1) != IDENTIFIER_NODE) - $1 = lastiddecl; - - /* Retrieve the type for the identifier, which might involve - some computation. */ - got_scope = $$ = complete_type (IDENTIFIER_TYPE_VALUE ($1)); - - if ($$ == error_mark_node) - cp_error ("`%T' is not a class or namespace", $1); - } - | SELFNAME SCOPE - { - if (TREE_CODE ($1) != IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$ = complete_type (TREE_TYPE ($$)); - } - | template_type SCOPE - { got_scope = $$ = complete_type (TREE_TYPE ($$)); } - | PTYPENAME SCOPE - | IDENTIFIER SCOPE - | NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - ; - -explicit_template_type: - identifier '<' template_arg_list_opt template_close_bracket - { $$ = build_min_nt (TEMPLATE_ID_EXPR, $1, $3); } - ; - -complex_type_name: - global_scope type_name - { - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = IDENTIFIER_GLOBAL_VALUE ($2); - else - $$ = $2; - got_scope = NULL_TREE; - } - | nested_type - | global_scope nested_type - { $$ = $2; } - ; - -ptr_to_mem: - nested_name_specifier '*' - { got_scope = NULL_TREE; } - | global_scope nested_name_specifier '*' - { $$ = $2; got_scope = NULL_TREE; } - ; - -/* All uses of explicit global scope must go through this nonterminal so - that got_scope will be set before yylex is called to get the next token. */ -global_scope: - SCOPE - { got_scope = void_type_node; } - ; - -/* ANSI new-declarator (5.3.4) */ -new_declarator: - '*' cv_qualifiers new_declarator - { $$ = make_pointer_declarator ($2, $3); } - | '*' cv_qualifiers %prec EMPTY - { $$ = make_pointer_declarator ($2, NULL_TREE); } - | '&' cv_qualifiers new_declarator %prec EMPTY - { $$ = make_reference_declarator ($2, $3); } - | '&' cv_qualifiers %prec EMPTY - { $$ = make_reference_declarator ($2, NULL_TREE); } - | ptr_to_mem cv_qualifiers %prec EMPTY - { tree arg = make_pointer_declarator ($2, NULL_TREE); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | ptr_to_mem cv_qualifiers new_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_new_declarator %prec EMPTY - ; - -/* ANSI direct-new-declarator (5.3.4) */ -direct_new_declarator: - '[' expr ']' - { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } - | direct_new_declarator '[' nonmomentary_expr ']' - { $$ = 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_intern - { $$ = make_pointer_declarator ($2.t, $3); } - | '*' 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_intern - { $$ = make_reference_declarator ($2.t, $3); } - | '&' absdcl_intern - { $$ = make_reference_declarator (NULL_TREE, $2); } - | '&' nonempty_cv_qualifiers %prec EMPTY - { $$ = make_reference_declarator ($2.t, NULL_TREE); } - | '&' %prec EMPTY - { $$ = make_reference_declarator (NULL_TREE, NULL_TREE); } - | ptr_to_mem cv_qualifiers %prec EMPTY - { tree arg = make_pointer_declarator ($2, NULL_TREE); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | ptr_to_mem cv_qualifiers absdcl_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_abstract_declarator %prec EMPTY - ; - -/* ANSI direct-abstract-declarator (8.1) */ -direct_abstract_declarator: - '(' absdcl_intern ')' - { $$ = $2; } - /* `(typedef)1' is `int'. */ - | PAREN_STAR_PAREN - | direct_abstract_declarator '(' parmlist ')' cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $3, $5, $6); } - | direct_abstract_declarator LEFT_RIGHT cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, empty_parms (), $3, $4); } - | direct_abstract_declarator '[' nonmomentary_expr ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - | direct_abstract_declarator '[' ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } - | '(' complex_parmlist ')' cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator (NULL_TREE, $2, $4, $5); } - | regcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' - { set_quals_and_spec ($$, $2, $3); } - | fcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' - { set_quals_and_spec ($$, $2, $3); } - | '[' nonmomentary_expr ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } - | '[' ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); } - ; - -/* For C++, decls and stmts can be intermixed, so we don't need to - have a special rule that won't start parsing the stmt section - until we have a stmt that parses without errors. */ - -stmts: - stmt - | errstmt - | stmts stmt - | stmts errstmt - ; - -errstmt: - error ';' - ; - -/* Read zero or more forward-declarations for labels - that nested functions can jump to. */ -maybe_label_decls: - /* empty */ - | label_decls - { if (pedantic) - pedwarn ("ANSI C++ forbids label declarations"); } - ; - -label_decls: - label_decl - | label_decls label_decl - ; - -label_decl: - LABEL identifiers_or_typenames ';' - { tree link; - for (link = $2; link; link = TREE_CHAIN (link)) - { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); - } - } - ; - -/* This is the body of a function definition. - It causes syntax errors to ignore to the next openbrace. */ -compstmt_or_error: - compstmt - {} - | error compstmt - ; - -compstmt: - '{' - { $<ttype>$ = begin_compound_stmt (0); } - compstmtend - { $$ = finish_compound_stmt (0, $<ttype>2); } - ; - -simple_if: - IF - { - $<ttype>$ = begin_if_stmt (); - cond_stmt_keyword = "if"; - } - paren_cond_or_null - { finish_if_stmt_cond ($3, $<ttype>2); } - implicitly_scoped_stmt - { $<ttype>$ = finish_then_clause ($<ttype>2); } - ; - -implicitly_scoped_stmt: - compstmt - | { $<ttype>$ = begin_compound_stmt (0); } - simple_stmt - { $$ = finish_compound_stmt (0, $<ttype>1); } - ; - -stmt: - compstmt - {} - | simple_stmt - ; - -simple_stmt: - decl - { finish_stmt (); } - | expr ';' - { finish_expr_stmt ($1); } - | simple_if ELSE - { begin_else_clause (); } - implicitly_scoped_stmt - { - finish_else_clause ($<ttype>1); - finish_if_stmt (); - } - | simple_if %prec IF - { finish_if_stmt (); } - | WHILE - { - $<ttype>$ = begin_while_stmt (); - cond_stmt_keyword = "while"; - } - paren_cond_or_null - { finish_while_stmt_cond ($3, $<ttype>2); } - already_scoped_stmt - { finish_while_stmt ($<ttype>2); } - | DO - { $<ttype>$ = begin_do_stmt (); } - implicitly_scoped_stmt WHILE - { - finish_do_body ($<ttype>2); - cond_stmt_keyword = "do"; - } - paren_expr_or_null ';' - { finish_do_stmt ($6, $<ttype>2); } - | FOR - { $<ttype>$ = begin_for_stmt (); } - '(' for.init.statement - { finish_for_init_stmt ($<ttype>2); } - xcond ';' - { finish_for_cond ($6, $<ttype>2); } - xexpr ')' - { finish_for_expr ($9, $<ttype>2); } - already_scoped_stmt - { finish_for_stmt ($9, $<ttype>2); } - | SWITCH - { begin_switch_stmt (); } - '(' condition ')' - { $<ttype>$ = finish_switch_cond ($4); } - implicitly_scoped_stmt - { finish_switch_stmt ($4, $<ttype>6); } - | CASE expr_no_commas ':' - { finish_case_label ($2, NULL_TREE); } - stmt - | CASE expr_no_commas ELLIPSIS expr_no_commas ':' - { finish_case_label ($2, $4); } - stmt - | DEFAULT ':' - { finish_case_label (NULL_TREE, NULL_TREE); } - stmt - | BREAK ';' - { finish_break_stmt (); } - | CONTINUE ';' - { finish_continue_stmt (); } - | RETURN_KEYWORD ';' - { finish_return_stmt (NULL_TREE); } - | RETURN_KEYWORD expr ';' - { finish_return_stmt ($2); } - | asm_keyword maybe_cv_qualifier '(' string ')' ';' - { - finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE, - NULL_TREE); - } - /* This is the case with just output operands. */ - | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ')' ';' - { - finish_asm_stmt ($2, $4, $6, NULL_TREE, - NULL_TREE); - } - /* This is the case with input operands as well. */ - | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' asm_operands ')' ';' - { finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); } - /* This is the case with clobbered registers as well. */ - | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' - asm_operands ':' asm_clobbers ')' ';' - { finish_asm_stmt ($2, $4, $6, $8, $10); } - | GOTO '*' expr ';' - { - if (pedantic) - pedwarn ("ANSI C++ forbids computed gotos"); - finish_goto_stmt ($3); - } - | GOTO identifier ';' - { finish_goto_stmt ($2); } - | label_colon stmt - { finish_stmt (); } - | label_colon '}' - { error ("label must be followed by statement"); - yyungetc ('}', 0); - finish_stmt (); } - | ';' - { finish_stmt (); } - | try_block - | using_directive - | namespace_using_decl - { do_local_using_decl ($1); } - | namespace_alias - ; - -function_try_block: - TRY - { - if (! current_function_parms_stored) - store_parm_decls (); - expand_start_early_try_stmts (); - } - ctor_initializer_opt compstmt - { - end_protect_partials (); - expand_start_all_catch (); - } - handler_seq - { - expand_end_all_catch (); - $$ = $3; - } - ; - -try_block: - TRY - { $<ttype>$ = begin_try_block (); } - compstmt - { finish_try_block ($<ttype>2); } - handler_seq - { finish_handler_sequence ($<ttype>2); } - ; - -handler_seq: - handler - | handler_seq handler - ; - -handler: - CATCH - { $<ttype>$ = begin_handler(); } - handler_args - { finish_handler_parms ($<ttype>2); } - compstmt - { finish_handler ($<ttype>2); } - ; - -type_specifier_seq: - typed_typespecs %prec EMPTY - | nonempty_cv_qualifiers %prec EMPTY - ; - -handler_args: - '(' ELLIPSIS ')' - { expand_start_catch_block (NULL_TREE, NULL_TREE); } - /* This doesn't allow reference parameters, the below does. - | '(' type_specifier_seq absdcl ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - | '(' type_specifier_seq ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, NULL_TREE); } - | '(' type_specifier_seq notype_declarator ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - | '(' typed_typespecs after_type_declarator ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - This allows reference parameters... */ - | '(' parm ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block (TREE_PURPOSE ($2.t), - TREE_VALUE ($2.t)); } - ; - -label_colon: - IDENTIFIER ':' - { tree label; - do_label: - label = define_label (input_filename, lineno, $1); - if (label && ! minimal_parse_mode) - expand_label (label); - } - | PTYPENAME ':' - { goto do_label; } - | TYPENAME ':' - { goto do_label; } - | SELFNAME ':' - { goto do_label; } - ; - -for.init.statement: - xexpr ';' - { if ($1) cplus_expand_expr_stmt ($1); } - | decl - | '{' compstmtend - { if (pedantic) - pedwarn ("ANSI C++ forbids compound statements inside for initializations"); - } - ; - -/* Either a type-qualifier or nothing. First thing in an `asm' statement. */ - -maybe_cv_qualifier: - /* empty */ - { emit_line_note (input_filename, lineno); - $$ = NULL_TREE; } - | CV_QUALIFIER - { emit_line_note (input_filename, lineno); } - ; - -xexpr: - /* empty */ - { $$ = NULL_TREE; } - | expr - | error - { $$ = NULL_TREE; } - ; - -/* These are the operands other than the first string and colon - in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ -asm_operands: - /* empty */ - { $$ = NULL_TREE; } - | nonnull_asm_operands - ; - -nonnull_asm_operands: - asm_operand - | nonnull_asm_operands ',' asm_operand - { $$ = chainon ($$, $3); } - ; - -asm_operand: - STRING '(' expr ')' - { $$ = build_tree_list ($$, $3); } - ; - -asm_clobbers: - STRING - { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); } - | asm_clobbers ',' STRING - { $$ = tree_cons (NULL_TREE, $3, $$); } - ; - -/* This is what appears inside the parens in a function declarator. - Its value is represented in the format that grokdeclarator expects. - - In C++, declaring a function with no parameters - means that that function takes *no* parameters. */ - -parmlist: - /* empty */ - { - $$ = empty_parms(); - } - | complex_parmlist - | type_id - { $$ = finish_parmlist (build_tree_list (NULL_TREE, $1.t), 0); - check_for_new_type ("inside parameter list", $1); } - ; - -/* This nonterminal does not include the common sequence '(' type_id ')', - as it is ambiguous and must be disambiguated elsewhere. */ -complex_parmlist: - parms - { $$ = finish_parmlist ($$, 0); } - | parms_comma ELLIPSIS - { $$ = finish_parmlist ($1, 1); } - /* C++ allows an ellipsis without a separating ',' */ - | parms ELLIPSIS - { $$ = finish_parmlist ($1, 1); } - | type_id ELLIPSIS - { $$ = finish_parmlist (build_tree_list (NULL_TREE, - $1.t), 1); } - | ELLIPSIS - { $$ = finish_parmlist (NULL_TREE, 1); } - | parms ':' - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - $$ = finish_parmlist ($1, 0); - yyungetc (':', 0); - yychar = ')'; - } - | type_id ':' - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - $$ = finish_parmlist (build_tree_list (NULL_TREE, - $1.t), 0); - yyungetc (':', 0); - yychar = ')'; - } - ; - -/* A default argument to a */ -defarg: - '=' - { maybe_snarf_defarg (); } - defarg1 - { $$ = $3; } - ; - -defarg1: - DEFARG - | init - ; - -/* A nonempty list of parameter declarations or type names. */ -parms: - named_parm - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list (NULL_TREE, $1.t); } - | parm defarg - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list ($2, $1.t); } - | parms_comma full_parm - { check_for_new_type ("in a parameter list", $2); - $$ = chainon ($$, $2.t); } - | parms_comma bad_parm - { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); } - | parms_comma bad_parm '=' init - { $$ = chainon ($$, build_tree_list ($4, $2)); } - ; - -parms_comma: - parms ',' - | type_id ',' - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list (NULL_TREE, $1.t); } - ; - -/* A single parameter declaration or parameter type name, - as found in a parmlist. */ -named_parm: - /* Here we expand typed_declspecs inline to avoid mis-parsing of - TYPESPEC IDENTIFIER. */ - typed_declspecs1 declarator - { tree specs = strip_attrs ($1.t); - $$.new_type_flag = $1.new_type_flag; - $$.t = build_tree_list (specs, $2); } - | typed_typespecs declarator - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec declarator - { $$.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); - $$.t = build_tree_list (specs, $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_declspecs1 %prec EMPTY - { tree specs = strip_attrs ($1.t); - $$.t = build_tree_list (specs, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - | declmods notype_declarator - { tree specs = strip_attrs ($1); - $$.t = build_tree_list (specs, $2); - $$.new_type_flag = 0; } - ; - -full_parm: - parm - { $$.t = build_tree_list (NULL_TREE, $1.t); - $$.new_type_flag = $1.new_type_flag; } - | parm defarg - { $$.t = build_tree_list ($2, $1.t); - $$.new_type_flag = $1.new_type_flag; } - ; - -parm: - named_parm - | type_id - ; - -see_typename: - /* empty */ %prec EMPTY - { see_typename (); } - ; - -bad_parm: - /* empty */ %prec EMPTY - { - error ("type specifier omitted for parameter"); - $$ = build_tree_list (integer_type_node, NULL_TREE); - } - | notype_declarator - { - error ("type specifier omitted for parameter"); - if (TREE_CODE ($$) == SCOPE_REF - && (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TEMPLATE_PARM)) - cp_error (" perhaps you want `typename %E' to make it a type", $$); - $$ = build_tree_list (integer_type_node, $$); - } - ; - -exception_specification_opt: - /* empty */ %prec 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, groktypename($1.t)); } - ; - -ansi_raise_identifiers: - ansi_raise_identifier - | ansi_raise_identifiers ',' ansi_raise_identifier - { - TREE_CHAIN ($3) = $$; - $$ = $3; - } - ; - -conversion_declarator: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | '*' cv_qualifiers conversion_declarator - { $$ = make_pointer_declarator ($2, $3); } - | '&' cv_qualifiers conversion_declarator - { $$ = make_reference_declarator ($2, $3); } - | ptr_to_mem cv_qualifiers conversion_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - ; - -operator: - OPERATOR - { got_scope = NULL_TREE; } - ; - -operator_name: - operator '*' - { $$ = ansi_opname[MULT_EXPR]; } - | operator '/' - { $$ = ansi_opname[TRUNC_DIV_EXPR]; } - | operator '%' - { $$ = ansi_opname[TRUNC_MOD_EXPR]; } - | operator '+' - { $$ = ansi_opname[PLUS_EXPR]; } - | operator '-' - { $$ = ansi_opname[MINUS_EXPR]; } - | operator '&' - { $$ = ansi_opname[BIT_AND_EXPR]; } - | operator '|' - { $$ = ansi_opname[BIT_IOR_EXPR]; } - | operator '^' - { $$ = ansi_opname[BIT_XOR_EXPR]; } - | operator '~' - { $$ = ansi_opname[BIT_NOT_EXPR]; } - | operator ',' - { $$ = ansi_opname[COMPOUND_EXPR]; } - | operator ARITHCOMPARE - { $$ = ansi_opname[$2]; } - | operator '<' - { $$ = ansi_opname[LT_EXPR]; } - | operator '>' - { $$ = ansi_opname[GT_EXPR]; } - | operator EQCOMPARE - { $$ = ansi_opname[$2]; } - | operator ASSIGN - { $$ = ansi_assopname[$2]; } - | operator '=' - { $$ = ansi_opname [MODIFY_EXPR]; } - | operator LSHIFT - { $$ = ansi_opname[$2]; } - | operator RSHIFT - { $$ = ansi_opname[$2]; } - | operator PLUSPLUS - { $$ = ansi_opname[POSTINCREMENT_EXPR]; } - | operator MINUSMINUS - { $$ = ansi_opname[PREDECREMENT_EXPR]; } - | operator ANDAND - { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; } - | operator OROR - { $$ = ansi_opname[TRUTH_ORIF_EXPR]; } - | operator '!' - { $$ = ansi_opname[TRUTH_NOT_EXPR]; } - | operator '?' ':' - { $$ = ansi_opname[COND_EXPR]; } - | operator MIN_MAX - { $$ = ansi_opname[$2]; } - | operator POINTSAT %prec EMPTY - { $$ = ansi_opname[COMPONENT_REF]; } - | operator POINTSAT_STAR %prec EMPTY - { $$ = ansi_opname[MEMBER_REF]; } - | operator LEFT_RIGHT - { $$ = ansi_opname[CALL_EXPR]; } - | operator '[' ']' - { $$ = ansi_opname[ARRAY_REF]; } - | operator NEW %prec EMPTY - { $$ = ansi_opname[NEW_EXPR]; } - | operator DELETE %prec EMPTY - { $$ = ansi_opname[DELETE_EXPR]; } - | operator NEW '[' ']' - { $$ = ansi_opname[VEC_NEW_EXPR]; } - | operator DELETE '[' ']' - { $$ = ansi_opname[VEC_DELETE_EXPR]; } - /* Names here should be looked up in class scope ALSO. */ - | operator type_specifier_seq conversion_declarator - { $$ = grokoptypename ($2.t, $3); } - | operator error - { $$ = ansi_opname[ERROR_MARK]; } - ; - -%% - -#ifdef SPEW_DEBUG -const char * -debug_yytranslate (value) - int value; -{ - return yytname[YYTRANSLATE (value)]; -} - -#endif |