summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/parse.y')
-rw-r--r--contrib/gcc/cp/parse.y953
1 files changed, 582 insertions, 371 deletions
diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y
index e929ebe..46e5021 100644
--- a/contrib/gcc/cp/parse.y
+++ b/contrib/gcc/cp/parse.y
@@ -28,9 +28,6 @@ Boston, MA 02111-1307, USA. */
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"
@@ -39,17 +36,59 @@ Boston, MA 02111-1307, USA. */
#include "input.h"
#include "flags.h"
#include "cp-tree.h"
+#include "decl.h"
#include "lex.h"
+#include "c-pragma.h" /* For YYDEBUG definition. */
#include "output.h"
#include "except.h"
#include "toplev.h"
#include "ggc.h"
-extern struct obstack permanent_obstack;
-
/* Like YYERROR but do call yyerror. */
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
+/* Like the default stack expander, except (1) use realloc when possible,
+ (2) impose no hard maxiumum on stack size, (3) REALLY do not use alloca.
+
+ Irritatingly, YYSTYPE is defined after this %{ %} block, so we cannot
+ give malloced_yyvs its proper type. This is ok since all we need from
+ it is to be able to free it. */
+
+static short *malloced_yyss;
+static void *malloced_yyvs;
+
+#define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ) \
+do { \
+ size_t newsize; \
+ short *newss; \
+ YYSTYPE *newvs; \
+ newsize = *(YYSSZ) *= 2; \
+ if (malloced_yyss) \
+ { \
+ newss = (short *) \
+ really_call_realloc (*(SS), newsize * sizeof (short)); \
+ newvs = (YYSTYPE *) \
+ really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \
+ } \
+ else \
+ { \
+ newss = (short *) really_call_malloc (newsize * sizeof (short)); \
+ newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \
+ if (newss) \
+ memcpy (newss, *(SS), (SSSIZE)); \
+ if (newvs) \
+ memcpy (newvs, *(VS), (VSSIZE)); \
+ } \
+ if (!newss || !newvs) \
+ { \
+ yyerror (MSG); \
+ return 2; \
+ } \
+ *(SS) = newss; \
+ *(VS) = newvs; \
+ malloced_yyss = newss; \
+ malloced_yyvs = (void *) newvs; \
+} while (0)
#define OP0(NODE) (TREE_OPERAND (NODE, 0))
#define OP1(NODE) (TREE_OPERAND (NODE, 1))
@@ -57,26 +96,22 @@ extern struct obstack permanent_obstack;
error message if the user supplies an empty conditional expression. */
static const char *cond_stmt_keyword;
-/* Nonzero if we have an `extern "C"' acting as an extern specifier. */
-int have_extern_spec;
-int used_extern_spec;
-
/* List of types and structure classes of the current declaration. */
-static tree current_declspecs;
+static GTY(()) 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;
+static GTY(()) tree prefix_attributes;
/* When defining an enumeration, this is the type of the enumeration. */
-static tree current_enum_type;
+static GTY(()) tree current_enum_type;
/* When parsing a conversion operator name, this is the scope of the
operator itself. */
-static tree saved_scopes;
+static GTY(()) tree saved_scopes;
static tree empty_parms PARAMS ((void));
static tree parse_decl0 PARAMS ((tree, tree, tree, tree, int));
@@ -89,6 +124,12 @@ static tree parse_bitfield PARAMS ((tree, tree, tree));
static tree parse_method PARAMS ((tree, tree, tree));
static void frob_specs PARAMS ((tree, tree));
static void check_class_key PARAMS ((tree, tree));
+static tree parse_scoped_id PARAMS ((tree));
+static tree parse_xref_tag (tree, tree, int);
+static tree parse_handle_class_head (tree, tree, tree, int, int *);
+static void parse_decl_instantiation (tree, tree, tree);
+static int parse_begin_function_definition (tree, tree);
+static tree parse_finish_call_expr (tree, tree, int);
/* Cons up an empty parameter list. */
static inline tree
@@ -97,7 +138,7 @@ empty_parms ()
tree parms;
#ifndef NO_IMPLICIT_EXTERN_C
- if (in_system_header && current_class_type == NULL
+ if (in_system_header && current_class_type == NULL
&& current_lang_name == lang_name_c)
parms = NULL_TREE;
else
@@ -118,18 +159,18 @@ frob_specs (specs_attrs, lookups)
if (current_declspecs
&& TREE_CODE (current_declspecs) != TREE_LIST)
current_declspecs = build_tree_list (NULL_TREE, current_declspecs);
- if (have_extern_spec && !used_extern_spec)
+ if (have_extern_spec)
{
/* We have to indicate that there is an "extern", but that it
was part of a language specifier. For instance,
-
+
extern "C" typedef int (*Ptr) ();
is well formed. */
current_declspecs = tree_cons (error_mark_node,
- get_identifier ("extern"),
+ get_identifier ("extern"),
current_declspecs);
- used_extern_spec = 1;
+ have_extern_spec = false;
}
}
@@ -222,26 +263,15 @@ check_class_key (key, aggr)
: key == record_type_node ? "struct" : "class", aggr);
}
-void
-cp_parse_init ()
-{
- ggc_add_tree_root (&current_declspecs, 1);
- ggc_add_tree_root (&prefix_attributes, 1);
- ggc_add_tree_root (&current_enum_type, 1);
- ggc_add_tree_root (&saved_scopes, 1);
-}
-
-/* Rename the "yyparse" function so that we can override it elsewhere. */
-#define yyparse yyparse_1
%}
%start program
-%union {
- long itype;
- tree ttype;
- char *strtype;
- enum tree_code code;
+%union { GTY(())
+ long itype;
+ tree ttype;
+ char *strtype;
+ enum tree_code code;
flagged_type_tree ftype;
struct unparsed_text *pi;
}
@@ -277,7 +307,7 @@ cp_parse_init ()
/* __func__, __FUNCTION__ or __PRETTY_FUNCTION__.
yylval contains an IDENTIFIER_NODE which indicates which one. */
-%token VAR_FUNC_NAME
+%token <ttype> VAR_FUNC_NAME
/* String constants in raw form.
yylval is a STRING_CST node. */
@@ -349,14 +379,14 @@ cp_parse_init ()
%type <ttype> PFUNCNAME maybe_identifier
%type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME
%type <ttype> expr_no_commas expr_no_comma_rangle
-%type <ttype> cast_expr unary_expr primary string STRING
-%type <ttype> reserved_declspecs boolean.literal
+%type <ttype> cast_expr unary_expr primary STRING
+%type <ttype> reserved_declspecs boolean_literal
%type <ttype> reserved_typespecquals
%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
%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> any_word unoperator
%type <itype> save_lineno
%type <ttype> simple_stmt simple_if
@@ -366,14 +396,14 @@ cp_parse_init ()
%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_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> 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> 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
@@ -382,7 +412,7 @@ cp_parse_init ()
%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> complex_parmlist parms_comma
%type <ttype> namespace_qualifier namespace_using_decl
%type <ftype> type_id new_type_id typed_typespecs typespec typed_declspecs
@@ -396,22 +426,22 @@ cp_parse_init ()
%token <ttype> PTYPENAME
%token <ttype> EXTERN_LANG_STRING ALL
%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
-%token <pi> PRE_PARSED_FUNCTION_DECL
+%token <pi> PRE_PARSED_FUNCTION_DECL
%type <ttype> component_constructor_declarator
-%type <ttype> fn.def2 return_id constructor_declarator
-%type <ttype> .begin_function_body
+%type <ttype> fn_def2 return_id constructor_declarator
+%type <ttype> begin_function_body_
%type <ttype> class_head class_head_apparent_template
%type <ftype> class_head_decl class_head_defn
%type <ttype> base_class_list
%type <ttype> base_class_access_list
-%type <ttype> base_class maybe_base_class_list base_class.1
+%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
/* %type <ttype> primary_no_id */
%type <ttype> maybe_parmlist
-%type <ttype> member_init
+%type <ttype> begin_member_init member_init
%type <ftype> member_init_list
%type <ttype> template_parm_header template_spec_header template_header
%type <ttype> template_parm_list template_parm
@@ -432,7 +462,7 @@ cp_parse_init ()
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
%type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN
%type <ttype> handler_args
-%type <ttype> self_template_type .finish_template_type
+%type <ttype> self_template_type finish_template_type_
%token NSNAME
%type <ttype> NSNAME
@@ -476,12 +506,11 @@ extdefs_opt:
;
.hush_warning:
- { have_extern_spec = 1;
- used_extern_spec = 0;
+ { have_extern_spec = true;
$<ttype>$ = NULL_TREE; }
;
.warning_ok:
- { have_extern_spec = 0; }
+ { have_extern_spec = false; }
;
extension:
@@ -514,9 +543,8 @@ extdef:
{ do_pending_inlines (); }
| template_def
{ do_pending_inlines (); }
- | asm_keyword '(' string ')' ';'
- { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
- assemble_asm ($3); }
+ | asm_keyword '(' STRING ')' ';'
+ { assemble_asm ($3); }
| extern_lang_string '{' extdefs_opt '}'
{ pop_lang_context (); }
| extern_lang_string .hush_warning fndef .warning_ok eat_saved_input
@@ -540,7 +568,7 @@ extdef:
;
namespace_alias:
- NAMESPACE identifier '='
+ NAMESPACE identifier '='
{ begin_only_namespace_names (); }
any_id ';'
{
@@ -627,7 +655,7 @@ template_parm_header:
template_spec_header:
TEMPLATE '<' '>'
- { begin_specialization();
+ { begin_specialization();
$$ = NULL_TREE; }
;
@@ -682,14 +710,7 @@ 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
- && TREE_CODE ($3) != UNBOUND_CLASS_TEMPLATE)
- {
- error ("invalid default template argument");
- $3 = error_mark_node;
- }
+ $3 = check_template_template_default_arg ($3);
$$ = build_tree_list ($3, $1);
}
;
@@ -778,9 +799,9 @@ eat_saved_input:
mem-initializer-list, so we open one there and suppress the one that
actually corresponds to the curly braces. */
function_body:
- .begin_function_body ctor_initializer_opt save_lineno '{'
+ begin_function_body_ ctor_initializer_opt save_lineno '{'
{ $<ttype>$ = begin_compound_stmt (/*has_no_scope=*/1); }
- compstmtend
+ compstmtend
{
STMT_LINENO ($<ttype>5) = $3;
finish_compound_stmt (/*has_no_scope=*/1, $<ttype>5);
@@ -798,15 +819,15 @@ fndef:
;
constructor_declarator:
- nested_name_specifier SELFNAME '('
+ 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);
+ { $$ = begin_constructor_declarator ($1, $2);
$$ = make_call_declarator ($$, empty_parms (), $4, $5);
}
- | global_scope nested_name_specifier SELFNAME '('
+ | 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); }
@@ -814,7 +835,7 @@ constructor_declarator:
{ $$ = begin_constructor_declarator ($2, $3);
$$ = make_call_declarator ($$, empty_parms (), $5, $6);
}
- | nested_name_specifier self_template_type '('
+ | 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); }
@@ -822,12 +843,12 @@ constructor_declarator:
{ $$ = begin_constructor_declarator ($1, $2);
$$ = make_call_declarator ($$, empty_parms (), $4, $5);
}
- | global_scope nested_name_specifier self_template_type '('
+ | 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);
+ { $$ = begin_constructor_declarator ($2, $3);
$$ = make_call_declarator ($$, empty_parms (), $5, $6);
}
;
@@ -835,19 +856,19 @@ constructor_declarator:
fn.def1:
typed_declspecs declarator
{ check_for_new_type ("return type", $1);
- if (!begin_function_definition ($1.t, $2))
+ if (!parse_begin_function_definition ($1.t, $2))
YYERROR1; }
| declmods notype_declarator
- { if (!begin_function_definition ($1.t, $2))
+ { if (!parse_begin_function_definition ($1.t, $2))
YYERROR1; }
| notype_declarator
- { if (!begin_function_definition (NULL_TREE, $1))
+ { if (!parse_begin_function_definition (NULL_TREE, $1))
YYERROR1; }
| declmods constructor_declarator
- { if (!begin_function_definition ($1.t, $2))
+ { if (!parse_begin_function_definition ($1.t, $2))
YYERROR1; }
| constructor_declarator
- { if (!begin_function_definition (NULL_TREE, $1))
+ { if (!parse_begin_function_definition (NULL_TREE, $1))
YYERROR1; }
;
@@ -872,7 +893,7 @@ component_constructor_declarator:
/* more C++ complexity. See component_decl for a comment on the
reduce/reduce conflict introduced by these rules. */
-fn.def2:
+fn_def2:
declmods component_constructor_declarator
{ $$ = parse_method ($2, $1.t, $1.lookups);
rest_of_mdef:
@@ -882,19 +903,19 @@ fn.def2:
yychar = YYLEX;
snarf_method ($$); }
| component_constructor_declarator
- { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
+ { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
goto rest_of_mdef; }
| typed_declspecs declarator
{ $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;}
| declmods notype_declarator
{ $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;}
| notype_declarator
- { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
+ { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
goto rest_of_mdef; }
| declmods constructor_declarator
{ $$ = parse_method ($2, $1.t, $1.lookups); goto rest_of_mdef;}
| constructor_declarator
- { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
+ { $$ = parse_method ($1, NULL_TREE, NULL_TREE);
goto rest_of_mdef; }
;
@@ -915,18 +936,15 @@ return_init:
;
base_init:
- ':' member_init_list
+ ':' { begin_mem_initializers (); } member_init_list
{
- if (! DECL_CONSTRUCTOR_P (current_function_decl))
- error ("only constructors take base initializers");
- else if ($2.new_type_flag == 0)
+ if ($3.new_type_flag == 0)
error ("no base or member initializers given following ':'");
-
- finish_mem_initializers ($2.t);
+ finish_mem_initializers ($3.t);
}
;
-.begin_function_body:
+begin_function_body_:
/* empty */
{
$$ = begin_function_body ();
@@ -935,20 +953,20 @@ base_init:
member_init_list:
/* empty */
- {
- $$.new_type_flag = 0;
- $$.t = NULL_TREE;
+ {
+ $$.new_type_flag = 0;
+ $$.t = NULL_TREE;
}
| member_init
- {
- $$.new_type_flag = 1;
- $$.t = $1;
+ {
+ $$.new_type_flag = 1;
+ $$.t = $1;
}
| member_init_list ',' member_init
- {
- if ($3)
+ {
+ if ($3)
{
- $$.new_type_flag = 1;
+ $$.new_type_flag = 1;
TREE_CHAIN ($3) = $1.t;
$$.t = $3;
}
@@ -958,38 +976,35 @@ member_init_list:
| member_init_list error
;
-member_init:
- '(' nonnull_exprlist ')'
+begin_member_init:
+ /* empty */
{
- if (current_class_name)
+ if (current_class_name)
pedwarn ("anachronistic old style base class initializer");
- $$ = expand_member_init (current_class_ref, NULL_TREE, $2);
+ $$ = expand_member_init (NULL_TREE);
+ in_base_initializer = $$ && !DECL_P ($$);
}
- | 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, $1, $3); }
- | typename_sub LEFT_RIGHT
- { $$ = expand_member_init (current_class_ref, $1,
- void_type_node); }
+ | notype_identifier
+ { $$ = expand_member_init ($1);
+ in_base_initializer = $$ && !DECL_P ($$); }
+ | nonnested_type
+ { $$ = expand_member_init ($1);
+ in_base_initializer = $$ && !DECL_P ($$); }
+ | typename_sub
+ { $$ = expand_member_init ($1);
+ in_base_initializer = $$ && !DECL_P ($$); }
+ ;
+
+member_init:
+ begin_member_init '(' nonnull_exprlist ')'
+ { in_base_initializer = 0;
+ $$ = $1 ? build_tree_list ($1, $3) : NULL_TREE; }
+ | begin_member_init LEFT_RIGHT
+ { in_base_initializer = 0;
+ $$ = $1 ? build_tree_list ($1, void_type_node) : NULL_TREE; }
| error
- { $$ = NULL_TREE; }
+ { in_base_initializer = 0;
+ $$ = NULL_TREE; }
;
identifier:
@@ -1002,7 +1017,7 @@ identifier:
notype_identifier:
IDENTIFIER
- | PTYPENAME
+ | PTYPENAME
| NSNAME %prec EMPTY
;
@@ -1019,40 +1034,40 @@ explicit_instantiation:
end_explicit_instantiation
| TEMPLATE begin_explicit_instantiation typed_declspecs declarator
{ tree specs = strip_attrs ($3.t);
- do_decl_instantiation (specs, $4, NULL_TREE); }
+ parse_decl_instantiation (specs, $4, NULL_TREE); }
end_explicit_instantiation
| TEMPLATE begin_explicit_instantiation notype_declarator
- { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
+ { parse_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
end_explicit_instantiation
| TEMPLATE begin_explicit_instantiation constructor_declarator
- { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
+ { parse_decl_instantiation (NULL_TREE, $3, NULL_TREE); }
end_explicit_instantiation
| SCSPEC TEMPLATE begin_explicit_instantiation typespec ';'
{ do_type_instantiation ($4.t, $1, 1);
yyungetc (';', 1); }
end_explicit_instantiation
{}
- | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs
+ | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs
declarator
{ tree specs = strip_attrs ($4.t);
- do_decl_instantiation (specs, $5, $1); }
+ parse_decl_instantiation (specs, $5, $1); }
end_explicit_instantiation
{}
| SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator
- { do_decl_instantiation (NULL_TREE, $4, $1); }
+ { parse_decl_instantiation (NULL_TREE, $4, $1); }
end_explicit_instantiation
{}
| SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator
- { do_decl_instantiation (NULL_TREE, $4, $1); }
+ { parse_decl_instantiation (NULL_TREE, $4, $1); }
end_explicit_instantiation
{}
;
-begin_explicit_instantiation:
+begin_explicit_instantiation:
{ begin_explicit_instantiation(); }
;
-end_explicit_instantiation:
+end_explicit_instantiation:
{ end_explicit_instantiation(); }
;
@@ -1062,10 +1077,10 @@ end_explicit_instantiation:
template_type:
PTYPENAME '<' template_arg_list_opt template_close_bracket
- .finish_template_type
+ finish_template_type_
{ $$ = $5; }
| tTYPENAME '<' template_arg_list_opt template_close_bracket
- .finish_template_type
+ finish_template_type_
{ $$ = $5; }
| self_template_type
;
@@ -1073,29 +1088,29 @@ template_type:
apparent_template_type:
template_type
| identifier '<' template_arg_list_opt '>'
- .finish_template_type
+ finish_template_type_
{ $$ = $5; }
;
self_template_type:
SELFNAME '<' template_arg_list_opt template_close_bracket
- .finish_template_type
+ finish_template_type_
{ $$ = $5; }
;
-.finish_template_type:
- {
+finish_template_type_:
+ {
if (yychar == YYEMPTY)
yychar = YYLEX;
- $$ = finish_template_type ($<ttype>-3, $<ttype>-1,
+ $$ = finish_template_type ($<ttype>-3, $<ttype>-1,
yychar == SCOPE);
}
;
template_close_bracket:
'>'
- | RSHIFT
+ | RSHIFT
{
/* Handle `Class<Class<Type>>' without space in the `>>' */
pedwarn ("`>>' should be `> >' in template class name");
@@ -1140,7 +1155,7 @@ template_arg:
$$ = error_mark_node;
}
else
- $$ = make_unbound_class_template ($1, $3, 1);
+ $$ = make_unbound_class_template ($1, $3, tf_error | tf_parsing);
}
;
@@ -1206,11 +1221,11 @@ condition:
$<ttype>$ = parse_decl ($<ttype>2, $4, 1);
}
init
- {
+ {
parse_end_decl ($<ttype>6, $7, $4);
- $$ = convert_from_reference ($<ttype>6);
+ $$ = convert_from_reference ($<ttype>6);
if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE)
- error ("definition of array `%#D' in condition", $$);
+ error ("definition of array `%#D' in condition", $$);
}
| expr
;
@@ -1224,10 +1239,10 @@ compstmtend:
nontrivial_exprlist:
expr_no_commas ',' expr_no_commas
- { $$ = tree_cons (NULL_TREE, $$,
+ { $$ = tree_cons (NULL_TREE, $$,
build_tree_list (NULL_TREE, $3)); }
| expr_no_commas ',' error
- { $$ = tree_cons (NULL_TREE, $$,
+ { $$ = tree_cons (NULL_TREE, $$,
build_tree_list (NULL_TREE, error_mark_node)); }
| nontrivial_exprlist ',' expr_no_commas
{ chainon ($$, build_tree_list (NULL_TREE, $3)); }
@@ -1270,37 +1285,37 @@ unary_expr:
{ $$ = finish_alignof ($2);
skip_evaluation--; }
| alignof '(' type_id ')' %prec HYPERUNARY
- { $$ = finish_alignof (groktypename ($3.t));
+ { $$ = finish_alignof (groktypename ($3.t));
check_for_new_type ("alignof", $3);
skip_evaluation--; }
/* 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);
+ { $$ = 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);
+ { $$ = 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);
+ { $$ = 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);
+ { $$ = build_new ($2, $3.t, $4, $1);
check_for_new_type ("new", $3); }
| new '(' type_id ')'
%prec EMPTY
{ $$ = build_new (NULL_TREE, groktypename($3.t),
- NULL_TREE, $1);
+ NULL_TREE, $1);
check_for_new_type ("new", $3); }
| new '(' type_id ')' new_initializer
- { $$ = build_new (NULL_TREE, groktypename($3.t), $5, $1);
+ { $$ = build_new (NULL_TREE, groktypename($3.t), $5, $1);
check_for_new_type ("new", $3); }
| new new_placement '(' type_id ')' %prec EMPTY
- { $$ = build_new ($2, groktypename($4.t), NULL_TREE, $1);
+ { $$ = build_new ($2, groktypename($4.t), NULL_TREE, $1);
check_for_new_type ("new", $4); }
| new new_placement '(' type_id ')' new_initializer
- { $$ = build_new ($2, groktypename($4.t), $6, $1);
+ { $$ = build_new ($2, groktypename($4.t), $6, $1);
check_for_new_type ("new", $4); }
| delete cast_expr %prec UNARY
@@ -1337,21 +1352,12 @@ new_initializer:
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.
- This feature is now deprecated and will be removed in a future
- release. */
| '=' init
{
- if (pedantic)
- pedwarn ("ISO C++ forbids initialization of new expression with `='");
- cp_deprecated ("new initializer lists extension");
- if (TREE_CODE ($2) != TREE_LIST
- && TREE_CODE ($2) != CONSTRUCTOR)
- $$ = build_tree_list (NULL_TREE, $2);
- else
- $$ = $2;
+ /* This was previously allowed as an extension, but
+ was removed in G++ 3.3. */
+ error ("initialization of new expression with `='");
+ $$ = error_mark_node;
}
;
@@ -1362,7 +1368,7 @@ regcast_or_absdcl:
$$ = 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);
+ { $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); }
;
@@ -1372,9 +1378,9 @@ cast_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));
+ nreverse ($3));
if (pedantic)
pedwarn ("ISO C++ forbids compound literals");
/* Indicate that this was a C99 compound literal. */
@@ -1506,11 +1512,11 @@ notype_unqualified_id:
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
+ /* If lastiddecl is a BASELINK 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)
+ if (!lastiddecl || !BASELINK_P (lastiddecl))
$$ = do_identifier ($<ttype>-1, 3, NULL_TREE);
else
$$ = $<ttype>-1;
@@ -1518,10 +1524,20 @@ do_id:
;
template_id:
- PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket
- { $$ = lookup_template_function ($3, $4); }
+ PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket
+ {
+ tree template_name = $3;
+ if (TREE_CODE (template_name) == COMPONENT_REF)
+ template_name = TREE_OPERAND (template_name, 1);
+ $$ = lookup_template_function (template_name, $4);
+ }
| operator_name '<' do_id template_arg_list_opt template_close_bracket
- { $$ = lookup_template_function ($3, $4); }
+ {
+ tree template_name = $3;
+ if (TREE_CODE (template_name) == COMPONENT_REF)
+ template_name = TREE_OPERAND (template_name, 1);
+ $$ = lookup_template_function (template_name, $4);
+ }
;
object_template_id:
@@ -1529,7 +1545,7 @@ object_template_id:
{ $$ = 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 operator_name '<' template_arg_list_opt
template_close_bracket
{ $$ = lookup_template_function ($2, $4); }
;
@@ -1566,7 +1582,7 @@ notype_template_declarator:
| 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
@@ -1582,15 +1598,15 @@ primary:
{
if (TREE_CODE ($1) == BIT_NOT_EXPR)
$$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($1, 0));
- else
+ else
$$ = finish_id_expr ($1);
- }
+ }
| CONSTANT
- | boolean.literal
- | string
+ | boolean_literal
+ | STRING
{
- $$ = combine_strings ($$);
- /* combine_strings doesn't set up TYPE_MAIN_VARIANT of
+ $$ = fix_string_type ($$);
+ /* fix_string_type 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
@@ -1598,11 +1614,7 @@ primary:
TYPE_DOMAIN (TREE_TYPE ($$)));
}
| VAR_FUNC_NAME
- {
- $$ = fname_decl (C_RID_CODE ($$), $$);
- if (processing_template_decl)
- $$ = build_min_nt (LOOKUP_EXPR, DECL_NAME ($$));
- }
+ { $$ = finish_fname ($1); }
| '(' expr ')'
{ $$ = finish_parenthesized_expr ($2); }
| '(' expr_or_declarator_intern ')'
@@ -1611,15 +1623,14 @@ primary:
| '(' error ')'
{ $$ = error_mark_node; }
| '('
- { tree scope = current_scope ();
- if (!scope || TREE_CODE (scope) != FUNCTION_DECL)
+ { if (!at_function_scope_p ())
{
error ("braced-group within expression allowed only inside a function");
YYERROR;
}
if (pedantic)
- pedwarn ("ISO C++ forbids braced-groups within expressions");
- $<ttype>$ = begin_stmt_expr ();
+ pedwarn ("ISO C++ forbids braced-groups within expressions");
+ $<ttype>$ = begin_stmt_expr ();
}
compstmt_or_stmtexpr ')'
{ $$ = finish_stmt_expr ($<ttype>2); }
@@ -1627,13 +1638,13 @@ primary:
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); }
+ { $$ = parse_finish_call_expr ($1, $3, 1); }
| notype_unqualified_id LEFT_RIGHT
- { $$ = finish_call_expr ($1, NULL_TREE, 1); }
+ { $$ = parse_finish_call_expr ($1, NULL_TREE, 1); }
| primary '(' nonnull_exprlist ')'
- { $$ = finish_call_expr ($1, $3, 0); }
+ { $$ = parse_finish_call_expr ($1, $3, 0); }
| primary LEFT_RIGHT
- { $$ = finish_call_expr ($1, NULL_TREE, 0); }
+ { $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
| VA_ARG '(' expr_no_commas ',' type_id ')'
{ $$ = build_x_va_arg ($3, groktypename ($5.t));
check_for_new_type ("__builtin_va_arg", $5); }
@@ -1681,38 +1692,33 @@ primary:
check_for_new_type ("typeid", $3);
$$ = get_typeid (type); }
| global_scope IDENTIFIER
- { $$ = do_scoped_id ($2, 1); }
+ { $$ = parse_scoped_id ($2); }
| global_scope template_id
{ $$ = $2; }
| global_scope operator_name
{
got_scope = NULL_TREE;
if (TREE_CODE ($2) == IDENTIFIER_NODE)
- $$ = do_scoped_id ($2, 1);
+ $$ = parse_scoped_id ($2);
else
$$ = $2;
}
| overqualified_id %prec HYPERUNARY
{ $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
| overqualified_id '(' nonnull_exprlist ')'
- { $$ = finish_qualified_call_expr ($1, $3); }
+ { $$ = parse_finish_call_expr ($1, $3, 0); }
| overqualified_id LEFT_RIGHT
- { $$ = finish_qualified_call_expr ($1, NULL_TREE); }
+ { $$ = parse_finish_call_expr ($1, NULL_TREE, 0); }
| object object_template_id %prec UNARY
- {
- $$ = build_x_component_ref ($$, $2, NULL_TREE, 1);
- }
+ { $$ = finish_class_member_access_expr ($$, $2); }
| 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); }
+ { $$ = finish_class_member_access_expr ($$, $2); }
| object overqualified_id %prec UNARY
- { if (processing_template_decl)
- $$ = build_min_nt (COMPONENT_REF, $1, $2);
- else
- $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
+ { $$ = finish_class_member_access_expr ($1, $2); }
| object unqualified_id '(' nonnull_exprlist ')'
{ $$ = finish_object_call_expr ($2, $1, $4); }
| object unqualified_id LEFT_RIGHT
@@ -1784,20 +1790,13 @@ delete:
{ got_scope = NULL_TREE; $$ = 1; }
;
-boolean.literal:
+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 */
{
@@ -1811,7 +1810,7 @@ object:
{ got_object = TREE_TYPE ($$); }
| primary POINTSAT
{
- $$ = build_x_arrow ($$);
+ $$ = build_x_arrow ($$);
got_object = TREE_TYPE ($$);
}
;
@@ -1860,20 +1859,20 @@ fcast_or_absdcl:
/* ISO type-id (8.1) */
type_id:
typed_typespecs absdcl
- { $$.t = build_tree_list ($1.t, $2);
+ { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| nonempty_cv_qualifiers absdcl
- { $$.t = build_tree_list ($1.t, $2);
+ { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| typespec absdcl
{ $$.t = build_tree_list (build_tree_list (NULL_TREE, $1.t),
- $2);
+ $2);
$$.new_type_flag = $1.new_type_flag; }
| typed_typespecs %prec EMPTY
{ $$.t = build_tree_list ($1.t, NULL_TREE);
$$.new_type_flag = $1.new_type_flag; }
| nonempty_cv_qualifiers %prec EMPTY
- { $$.t = build_tree_list ($1.t, NULL_TREE);
+ { $$.t = build_tree_list ($1.t, NULL_TREE);
$$.new_type_flag = $1.new_type_flag; }
;
@@ -1891,23 +1890,23 @@ typed_declspecs:
typed_declspecs1:
declmods typespec
- { $$.t = tree_cons (NULL_TREE, $2.t, $1.t);
+ { $$.t = tree_cons (NULL_TREE, $2.t, $1.t);
$$.new_type_flag = $2.new_type_flag; }
| typespec reserved_declspecs %prec HYPERUNARY
- { $$.t = tree_cons (NULL_TREE, $1.t, $2);
+ { $$.t = tree_cons (NULL_TREE, $1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| typespec reserved_typespecquals reserved_declspecs
- { $$.t = tree_cons (NULL_TREE, $1.t, chainon ($2, $3));
+ { $$.t = tree_cons (NULL_TREE, $1.t, chainon ($2, $3));
$$.new_type_flag = $1.new_type_flag; }
| declmods typespec reserved_declspecs
- { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t));
+ { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t));
$$.new_type_flag = $2.new_type_flag; }
| declmods typespec reserved_typespecquals
- { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t));
+ { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t));
$$.new_type_flag = $2.new_type_flag; }
| declmods typespec reserved_typespecquals reserved_declspecs
{ $$.t = tree_cons (NULL_TREE, $2.t,
- chainon ($3, chainon ($4, $1.t)));
+ chainon ($3, chainon ($4, $1.t)));
$$.new_type_flag = $2.new_type_flag; }
;
@@ -1973,16 +1972,16 @@ declmods:
typed_typespecs:
typespec %prec EMPTY
- { $$.t = build_tree_list (NULL_TREE, $1.t);
+ { $$.t = build_tree_list (NULL_TREE, $1.t);
$$.new_type_flag = $1.new_type_flag; }
| nonempty_cv_qualifiers typespec
- { $$.t = tree_cons (NULL_TREE, $2.t, $1.t);
+ { $$.t = tree_cons (NULL_TREE, $2.t, $1.t);
$$.new_type_flag = $2.new_type_flag; }
| typespec reserved_typespecquals
- { $$.t = tree_cons (NULL_TREE, $1.t, $2);
+ { $$.t = tree_cons (NULL_TREE, $1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| nonempty_cv_qualifiers typespec reserved_typespecquals
- { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t));
+ { $$.t = tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t));
$$.new_type_flag = $2.new_type_flag; }
;
@@ -2091,8 +2090,8 @@ nomods_initdecls:
maybeasm:
/* empty */
{ $$ = NULL_TREE; }
- | asm_keyword '(' string ')'
- { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; }
+ | asm_keyword '(' STRING ')'
+ { $$ = $3; }
;
initdcl:
@@ -2119,7 +2118,7 @@ initdcl0_innards:
{ $<ttype>$ = parse_decl0 ($<ttype>-1, $<ftype>-2.t,
$<ftype>-2.lookups, $1, 1); }
/* Note how the declaration of the variable is in effect
- while its init is parsed! */
+ while its init is parsed! */
init
{ parse_end_decl ($<ttype>3, $4, $<ttype>0); }
| maybe_attribute
@@ -2127,7 +2126,7 @@ initdcl0_innards:
$<ftype>-2.lookups, $1, 0);
parse_end_decl (d, NULL_TREE, $<ttype>0); }
;
-
+
initdcl0:
declarator maybeasm initdcl0_innards
{}
@@ -2137,15 +2136,15 @@ notype_initdcl0:
notype_declarator maybeasm initdcl0_innards
{}
;
-
+
nomods_initdcl0:
notype_declarator maybeasm
{ /* Set things up as initdcl0_innards expects. */
$<ttype>$ = $2;
- $2 = $1;
+ $2 = $1;
$<ftype>1.t = NULL_TREE;
$<ftype>1.lookups = NULL_TREE; }
- initdcl0_innards
+ initdcl0_innards
{}
| constructor_declarator maybeasm maybe_attribute
{ tree d = parse_decl0 ($1, NULL_TREE, NULL_TREE, $3, 0);
@@ -2160,7 +2159,7 @@ maybe_attribute:
| attributes
{ $$ = $1; }
;
-
+
attributes:
attribute
{ $$ = $1; }
@@ -2179,7 +2178,7 @@ attribute_list:
| attribute_list ',' attrib
{ $$ = chainon ($1, $3); }
;
-
+
attrib:
/* empty */
{ $$ = NULL_TREE; }
@@ -2259,13 +2258,13 @@ pending_inline:
process_next_inline ($1);
}
| PRE_PARSED_FUNCTION_DECL maybe_return_init function_try_block
- {
- expand_body (finish_function (2));
+ {
+ expand_body (finish_function (2));
process_next_inline ($1);
}
| PRE_PARSED_FUNCTION_DECL maybe_return_init error
- {
- finish_function (2);
+ {
+ finish_function (2);
process_next_inline ($1); }
;
@@ -2311,14 +2310,14 @@ structsp:
current_enum_type = $<ttype>3;
check_for_missing_semicolon ($$.t); }
| ENUM identifier
- { $$.t = xref_tag (enum_type_node, $2, 1);
+ { $$.t = parse_xref_tag (enum_type_node, $2, 1);
$$.new_type_flag = 0; }
| ENUM complex_type_name
- { $$.t = xref_tag (enum_type_node, $2, 1);
+ { $$.t = parse_xref_tag (enum_type_node, $2, 1);
$$.new_type_flag = 0; }
| TYPENAME_KEYWORD typename_sub
{ $$.t = $2;
- $$.new_type_flag = 0;
+ $$.new_type_flag = 0;
if (!processing_template_decl)
pedwarn ("using `typename' outside of template"); }
/* C++ extensions, merged with C to avoid shift/reduce conflicts */
@@ -2327,20 +2326,28 @@ structsp:
if ($2 && $1.t != error_mark_node)
{
tree type = TREE_TYPE ($1.t);
-
+
if (TREE_CODE (type) == TYPENAME_TYPE)
- /* In a definition of a member class template,
- we will get here with an implicit typename,
- a TYPENAME_TYPE with a type. */
- type = TREE_TYPE (type);
+ {
+ if (IMPLICIT_TYPENAME_P (type))
+ /* In a definition of a member class template,
+ we will get here with an implicit typename,
+ a TYPENAME_TYPE with a type. */
+ type = TREE_TYPE (type);
+ else
+ {
+ error ("qualified name does not name a class");
+ type = error_mark_node;
+ }
+ }
maybe_process_partial_specialization (type);
- xref_basetypes (current_aggr, $1.t, type, $2);
+ xref_basetypes (type, $2);
}
- $1.t = begin_class_definition (TREE_TYPE ($1.t));
+ $1.t = begin_class_definition (TREE_TYPE ($1.t));
check_class_key (current_aggr, $1.t);
current_aggr = NULL_TREE; }
opt.component_decl_list '}' maybe_attribute
- {
+ {
int semi;
tree t;
@@ -2364,9 +2371,8 @@ structsp:
}
pending_inlines
{
- finish_inline_definitions ();
$$.t = $<ttype>8;
- $$.new_type_flag = 1;
+ $$.new_type_flag = 1;
}
| class_head_decl
{
@@ -2427,18 +2433,18 @@ class_head:
class_head_apparent_template:
aggr apparent_template_type
- {
- current_aggr = $1;
+ {
+ current_aggr = $1;
$$ = $2;
}
| aggr nested_name_specifier apparent_template_type
- {
- current_aggr = $1;
+ {
+ current_aggr = $1;
$$ = $3;
}
| aggr global_scope nested_name_specifier apparent_template_type
- {
- current_aggr = $1;
+ {
+ current_aggr = $1;
$$ = $4;
}
;
@@ -2446,14 +2452,15 @@ class_head_apparent_template:
class_head_decl:
class_head %prec EMPTY
{
- $$.t = handle_class_head (current_aggr,
- TREE_PURPOSE ($1), TREE_VALUE ($1),
- 0, &$$.new_type_flag);
+ $$.t = parse_handle_class_head (current_aggr,
+ TREE_PURPOSE ($1),
+ TREE_VALUE ($1),
+ 0, &$$.new_type_flag);
}
| aggr identifier_defn %prec EMPTY
{
current_aggr = $1;
- $$.t = TYPE_MAIN_DECL (xref_tag (current_aggr, $2, 0));
+ $$.t = TYPE_MAIN_DECL (parse_xref_tag (current_aggr, $2, 0));
$$.new_type_flag = 1;
}
| class_head_apparent_template %prec EMPTY
@@ -2467,59 +2474,54 @@ class_head_defn:
class_head '{'
{
yyungetc ('{', 1);
- $$.t = handle_class_head (current_aggr,
- TREE_PURPOSE ($1), TREE_VALUE ($1),
- 1, &$$.new_type_flag);
+ $$.t = parse_handle_class_head (current_aggr,
+ TREE_PURPOSE ($1),
+ TREE_VALUE ($1),
+ 1,
+ &$$.new_type_flag);
}
| class_head ':'
{
yyungetc (':', 1);
- $$.t = handle_class_head (current_aggr,
- TREE_PURPOSE ($1), TREE_VALUE ($1),
- 1, &$$.new_type_flag);
+ $$.t = parse_handle_class_head (current_aggr,
+ TREE_PURPOSE ($1),
+ TREE_VALUE ($1),
+ 1, &$$.new_type_flag);
}
| class_head_apparent_template '{'
{
yyungetc ('{', 1);
- $$.t = $1;
- $$.new_type_flag = 0;
- if (TREE_CODE (TREE_TYPE ($1)) == RECORD_TYPE)
- /* We might be specializing a template with a different
- class-key. */
- CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($1))
- = (current_aggr == class_type_node);
+ $$.t = handle_class_head_apparent_template
+ ($1, &$$.new_type_flag);
}
| class_head_apparent_template ':'
{
yyungetc (':', 1);
- $$.t = $1;
- $$.new_type_flag = 0;
- if (TREE_CODE (TREE_TYPE ($1)) == RECORD_TYPE)
- /* We might be specializing a template with a different
- class-key. */
- CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($1))
- = (current_aggr == class_type_node);
+ $$.t = handle_class_head_apparent_template
+ ($1, &$$.new_type_flag);
}
| aggr identifier_defn '{'
{
yyungetc ('{', 1);
current_aggr = $1;
- $$.t = handle_class_head (current_aggr,
- NULL_TREE, $2,
- 1, &$$.new_type_flag);
+ $$.t = parse_handle_class_head (current_aggr,
+ NULL_TREE, $2,
+ 1, &$$.new_type_flag);
}
| aggr identifier_defn ':'
{
yyungetc (':', 1);
current_aggr = $1;
- $$.t = handle_class_head (current_aggr,
- NULL_TREE, $2,
- 1, &$$.new_type_flag);
+ $$.t = parse_handle_class_head (current_aggr,
+ NULL_TREE, $2,
+ 1, &$$.new_type_flag);
}
| aggr '{'
{
current_aggr = $1;
- $$.t = TYPE_MAIN_DECL (xref_tag ($1, make_anon_name (), 0));
+ $$.t = TYPE_MAIN_DECL (parse_xref_tag ($1,
+ make_anon_name (),
+ 0));
$$.new_type_flag = 0;
CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($$.t))
= $1 == class_type_node;
@@ -2544,13 +2546,13 @@ base_class_list:
;
base_class:
- base_class.1
+ base_class_1
{ $$ = finish_base_specifier (access_default_node, $1); }
- | base_class_access_list see_typename base_class.1
+ | base_class_access_list see_typename base_class_1
{ $$ = finish_base_specifier ($1, $3); }
;
-base_class.1:
+base_class_1:
typename_sub
{ if (!TYPE_P ($$))
$$ = error_mark_node; }
@@ -2592,7 +2594,7 @@ base_class_access_list:
opt.component_decl_list:
| component_decl_list
| opt.component_decl_list access_specifier component_decl_list
- | opt.component_decl_list access_specifier
+ | opt.component_decl_list access_specifier
;
access_specifier:
@@ -2606,13 +2608,13 @@ access_specifier:
ARM $9.2 says that the semicolon is optional, and therefore allowed. */
component_decl_list:
component_decl
- {
+ {
finish_member_declaration ($1);
current_aggr = NULL_TREE;
reset_type_access_control ();
}
| component_decl_list component_decl
- {
+ {
finish_member_declaration ($2);
current_aggr = NULL_TREE;
reset_type_access_control ();
@@ -2626,13 +2628,13 @@ component_decl:
yyungetc ('}', 0); }
/* C++: handle constructors, destructors and inline functions */
/* note that INLINE is like a TYPESPEC */
- | fn.def2 ':' /* base_init compstmt */
+ | fn_def2 ':' /* base_init compstmt */
{ $$ = finish_method ($$); }
- | fn.def2 TRY /* base_init compstmt */
+ | fn_def2 TRY /* base_init compstmt */
{ $$ = finish_method ($$); }
- | fn.def2 RETURN_KEYWORD /* base_init compstmt */
+ | fn_def2 RETURN_KEYWORD /* base_init compstmt */
{ $$ = finish_method ($$); }
- | fn.def2 '{' /* nodecls compstmt */
+ | fn_def2 '{' /* nodecls compstmt */
{ $$ = finish_method ($$); }
| ';'
{ $$ = NULL_TREE; }
@@ -2640,7 +2642,7 @@ component_decl:
{ $$ = $2;
pedantic = $1; }
| template_header component_decl
- {
+ {
if ($2)
$$ = finish_member_template_decl ($2);
else
@@ -2650,8 +2652,8 @@ component_decl:
finish_template_decl ($1);
}
| template_header typed_declspecs ';'
- {
- $$ = finish_member_class_template ($2.t);
+ {
+ $$ = finish_member_class_template ($2.t);
finish_template_decl ($1);
}
| bad_decl
@@ -2684,10 +2686,10 @@ component_decl_1:
$$ = NULL_TREE;
}
| declmods notype_components
- {
+ {
if (!$2)
grok_x_components ($1.t);
- $$ = NULL_TREE;
+ $$ = NULL_TREE;
}
| notype_declarator maybeasm maybe_attribute maybe_init
{ $$ = grokfield ($$, NULL_TREE, $4, $2, $3); }
@@ -2723,14 +2725,14 @@ components:
/* empty: possibly anonymous */
{ $$ = 0; }
| component_declarator0
- {
+ {
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
$1 = finish_member_template_decl ($1);
- finish_member_declaration ($1);
+ finish_member_declaration ($1);
$$ = 1;
}
| components ',' component_declarator
- {
+ {
check_multiple_declarators ();
if (PROCESSING_REAL_TEMPLATE_DECL_P ())
$3 = finish_member_template_decl ($3);
@@ -2743,18 +2745,18 @@ 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);
+ finish_member_declaration ($3);
$$ = 2;
}
;
@@ -2833,10 +2835,10 @@ enumerator:
/* ISO new-type-id (5.3.4) */
new_type_id:
type_specifier_seq new_declarator
- { $$.t = build_tree_list ($1.t, $2);
+ { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| type_specifier_seq %prec EMPTY
- { $$.t = build_tree_list ($1.t, NULL_TREE);
+ { $$.t = build_tree_list ($1.t, NULL_TREE);
$$.new_type_flag = $1.new_type_flag; }
/* GNU extension to allow arrays of arbitrary types with
non-constant dimension. */
@@ -2862,13 +2864,13 @@ nonempty_cv_qualifiers:
{ $$.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);
+ { $$.t = hash_tree_cons (NULL_TREE, $2, $1.t);
$$.new_type_flag = $1.new_type_flag; }
| attributes %prec EMPTY
- { $$.t = hash_tree_cons ($1, NULL_TREE, NULL_TREE);
+ { $$.t = hash_tree_cons ($1, NULL_TREE, NULL_TREE);
$$.new_type_flag = 0; }
| nonempty_cv_qualifiers attributes %prec EMPTY
- { $$.t = hash_tree_cons ($2, NULL_TREE, $1.t);
+ { $$.t = hash_tree_cons ($2, NULL_TREE, $1.t);
$$.new_type_flag = $1.new_type_flag; }
;
@@ -2977,7 +2979,7 @@ notype_declarator_intern:
$$ = tree_cons ($1, $2, NULL_TREE);
}
;
-
+
notype_declarator:
'*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY
{ $$ = make_pointer_declarator ($2.t, $3); }
@@ -3025,7 +3027,7 @@ complex_direct_notype_declarator:
{ enter_scope_of ($2); $$ = $2;}
| global_scope notype_unqualified_id
{ $$ = build_nt (SCOPE_REF, global_namespace, $2);
- enter_scope_of ($$);
+ enter_scope_of ($$);
}
| nested_name_specifier notype_template_declarator
{ got_scope = NULL_TREE;
@@ -3078,15 +3080,15 @@ nested_name_specifier:
| nested_name_specifier nested_name_specifier_1
{ $$ = $2; }
| nested_name_specifier TEMPLATE explicit_template_type SCOPE
- { got_scope = $$
- = make_typename_type ($1, $3, tf_error); }
+ { got_scope = $$
+ = make_typename_type ($1, $3, tf_error | tf_parsing); }
/* Error handling per Core 125. */
| nested_name_specifier IDENTIFIER SCOPE
- { got_scope = $$
- = make_typename_type ($1, $2, tf_error); }
+ { got_scope = $$
+ = make_typename_type ($1, $2, tf_error | tf_parsing); }
| nested_name_specifier PTYPENAME SCOPE
- { got_scope = $$
- = make_typename_type ($1, $2, tf_error); }
+ { got_scope = $$
+ = make_typename_type ($1, $2, tf_error | tf_parsing); }
;
/* Why the @#$%^& do type_name and notype_identifier need to be expanded
@@ -3128,7 +3130,7 @@ typename_sub0:
typename_sub1 identifier %prec EMPTY
{
if (TYPE_P ($1))
- $$ = make_typename_type ($1, $2, tf_error);
+ $$ = make_typename_type ($1, $2, tf_error | tf_parsing);
else if (TREE_CODE ($2) == IDENTIFIER_NODE)
error ("`%T' is not a class or namespace", $2);
else
@@ -3141,9 +3143,9 @@ typename_sub0:
| typename_sub1 template_type %prec EMPTY
{ $$ = TREE_TYPE ($2); }
| typename_sub1 explicit_template_type %prec EMPTY
- { $$ = make_typename_type ($1, $2, tf_error); }
+ { $$ = make_typename_type ($1, $2, tf_error | tf_parsing); }
| typename_sub1 TEMPLATE explicit_template_type %prec EMPTY
- { $$ = make_typename_type ($1, $3, tf_error); }
+ { $$ = make_typename_type ($1, $3, tf_error | tf_parsing); }
;
typename_sub1:
@@ -3157,7 +3159,7 @@ typename_sub1:
| typename_sub1 typename_sub2
{
if (TYPE_P ($1))
- $$ = make_typename_type ($1, $2, tf_error);
+ $$ = make_typename_type ($1, $2, tf_error | tf_parsing);
else if (TREE_CODE ($2) == IDENTIFIER_NODE)
error ("`%T' is not a class or namespace", $2);
else
@@ -3168,11 +3170,11 @@ typename_sub1:
}
}
| typename_sub1 explicit_template_type SCOPE
- { got_scope = $$
- = make_typename_type ($1, $2, tf_error); }
+ { got_scope = $$
+ = make_typename_type ($1, $2, tf_error | tf_parsing); }
| typename_sub1 TEMPLATE explicit_template_type SCOPE
- { got_scope = $$
- = make_typename_type ($1, $3, tf_error); }
+ { got_scope = $$
+ = make_typename_type ($1, $3, tf_error | tf_parsing); }
;
/* This needs to return a TYPE_DECL for simple names so that we don't
@@ -3279,7 +3281,7 @@ absdcl_intern:
$$ = tree_cons ($1, $2, NULL_TREE);
}
;
-
+
/* ISO abstract-declarator (8.1) */
absdcl:
'*' nonempty_cv_qualifiers absdcl_intern
@@ -3365,7 +3367,7 @@ label_decls:
label_decl:
LABEL identifiers_or_typenames ';'
- {
+ {
while ($2)
{
finish_label_decl (TREE_VALUE ($2));
@@ -3377,7 +3379,7 @@ label_decl:
compstmt_or_stmtexpr:
save_lineno '{'
{ $<ttype>$ = begin_compound_stmt (0); }
- compstmtend
+ compstmtend
{ STMT_LINENO ($<ttype>3) = $1;
finish_compound_stmt (0, $<ttype>3); }
;
@@ -3400,9 +3402,9 @@ simple_if:
implicitly_scoped_stmt:
compstmt
- |
+ |
{ $<ttype>$ = begin_compound_stmt (0); }
- save_lineno simple_stmt
+ save_lineno simple_stmt
{ STMT_LINENO ($<ttype>1) = $2;
if ($3) STMT_LINENO ($3) = $2;
finish_compound_stmt (0, $<ttype>1); }
@@ -3423,9 +3425,9 @@ simple_stmt:
| simple_if ELSE
{ begin_else_clause (); }
implicitly_scoped_stmt
- {
+ {
$$ = $1;
- finish_else_clause ($1);
+ finish_else_clause ($1);
finish_if_stmt ();
}
| simple_if %prec IF
@@ -3462,7 +3464,7 @@ simple_stmt:
implicitly_scoped_stmt
{ $$ = $<ttype>2;
finish_for_stmt ($<ttype>2); }
- | SWITCH
+ | SWITCH
{ $<ttype>$ = begin_switch_stmt (); }
'(' condition ')'
{ finish_switch_cond ($4, $<ttype>2); }
@@ -3489,31 +3491,31 @@ simple_stmt:
{ $$ = finish_return_stmt (NULL_TREE); }
| RETURN_KEYWORD expr ';'
{ $$ = finish_return_stmt ($2); }
- | asm_keyword maybe_cv_qualifier '(' string ')' ';'
+ | asm_keyword maybe_cv_qualifier '(' STRING ')' ';'
{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE,
NULL_TREE);
ASM_INPUT_P ($$) = 1; }
/* This is the case with just output operands. */
- | asm_keyword maybe_cv_qualifier '(' string ':' asm_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_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':'
asm_operands ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
- | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ')' ';'
+ | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ')' ';'
{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); }
/* This is the case with clobbered registers as well. */
- | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
+ | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':'
asm_operands ':' asm_clobbers ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, $8, $10); }
- | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ':'
+ | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ':'
asm_clobbers ')' ';'
{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); }
- | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands SCOPE
+ | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands SCOPE
asm_clobbers ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); }
| GOTO '*' expr ';'
- {
+ {
if (pedantic)
pedwarn ("ISO C++ forbids computed gotos");
$$ = finish_goto_stmt ($3);
@@ -3604,7 +3606,7 @@ handler_args:
expand_start_catch_block ($2.t, $3); }
This allows reference parameters... */
| '(' parm ')'
- {
+ {
check_for_new_type ("inside exception declarations", $2);
$$ = start_handler_parms (TREE_PURPOSE ($2.t),
TREE_VALUE ($2.t));
@@ -3666,14 +3668,16 @@ asm_operand:
STRING '(' expr ')'
{ $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $3); }
| '[' identifier ']' STRING '(' expr ')'
- { $$ = build_tree_list (build_tree_list ($2, $4), $6); }
+ { $2 = build_string (IDENTIFIER_LENGTH ($2),
+ IDENTIFIER_POINTER ($2));
+ $$ = build_tree_list (build_tree_list ($2, $4), $6); }
;
asm_clobbers:
- string
- { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE);}
- | asm_clobbers ',' string
- { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
+ STRING
+ { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);}
+ | asm_clobbers ',' STRING
+ { $$ = tree_cons (NULL_TREE, $3, $1); }
;
/* This is what appears inside the parens in a function declarator.
@@ -3705,7 +3709,7 @@ complex_parmlist:
{ $$ = finish_parmlist ($1, 1); }
| type_id ELLIPSIS
{ $$ = finish_parmlist (build_tree_list (NULL_TREE,
- $1.t), 1); }
+ $1.t), 1); }
| ELLIPSIS
{ $$ = finish_parmlist (NULL_TREE, 1); }
| parms ':'
@@ -3725,7 +3729,7 @@ complex_parmlist:
parenthesis. */
yyerror ("possibly missing ')'");
$$ = finish_parmlist (build_tree_list (NULL_TREE,
- $1.t), 0);
+ $1.t), 0);
yyungetc (':', 0);
yychar = ')';
}
@@ -3777,20 +3781,20 @@ named_parm:
{ $$.new_type_flag = $1.new_type_flag;
$$.t = build_tree_list ($1.t, $2); }
| typed_typespecs declarator
- { $$.t = build_tree_list ($1.t, $2);
+ { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| typespec declarator
{ $$.t = build_tree_list (build_tree_list (NULL_TREE, $1.t),
- $2);
+ $2);
$$.new_type_flag = $1.new_type_flag; }
| typed_declspecs1 absdcl
{ $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = $1.new_type_flag; }
| typed_declspecs1 %prec EMPTY
- { $$.t = build_tree_list ($1.t, NULL_TREE);
+ { $$.t = build_tree_list ($1.t, NULL_TREE);
$$.new_type_flag = $1.new_type_flag; }
| declmods notype_declarator
- { $$.t = build_tree_list ($1.t, $2);
+ { $$.t = build_tree_list ($1.t, $2);
$$.new_type_flag = 0; }
;
@@ -3912,6 +3916,7 @@ unoperator:
got_object = TREE_VALUE (saved_scopes);
looking_for_typename = TREE_LANG_FLAG_0 (saved_scopes);
saved_scopes = TREE_CHAIN (saved_scopes);
+ $$ = got_scope;
}
;
@@ -3983,7 +3988,7 @@ operator_name:
| operator DELETE '[' ']' unoperator
{ $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); }
| operator type_specifier_seq conversion_declarator unoperator
- { $$ = frob_opname (grokoptypename ($2.t, $3)); }
+ { $$ = frob_opname (grokoptypename ($2.t, $3, $4)); }
| operator error unoperator
{ $$ = frob_opname (ansi_opname (ERROR_MARK)); }
;
@@ -4005,5 +4010,211 @@ debug_yytranslate (value)
{
return yytname[YYTRANSLATE (value)];
}
-
#endif
+
+/* Free malloced parser stacks if necessary. */
+
+void
+free_parser_stacks ()
+{
+ if (malloced_yyss)
+ {
+ free (malloced_yyss);
+ free (malloced_yyvs);
+ }
+}
+
+/* Return the value corresponding to TOKEN in the global scope. */
+
+static tree
+parse_scoped_id (token)
+ tree token;
+{
+ cxx_binding binding;
+
+ cxx_binding_clear (&binding);
+ if (!qualified_lookup_using_namespace (token, global_namespace, &binding, 0))
+ binding.value = NULL;
+ if (yychar == YYEMPTY)
+ yychar = yylex();
+
+ return do_scoped_id (token, binding.value);
+}
+
+/* AGGR may be either a type node (like class_type_node) or a
+ TREE_LIST whose TREE_PURPOSE is a list of attributes and whose
+ TREE_VALUE is a type node. Set *TAG_KIND and *ATTRIBUTES to
+ represent the information encoded. */
+
+static void
+parse_split_aggr (tree aggr, enum tag_types *tag_kind, tree *attributes)
+{
+ if (TREE_CODE (aggr) == TREE_LIST)
+ {
+ *attributes = TREE_PURPOSE (aggr);
+ aggr = TREE_VALUE (aggr);
+ }
+ else
+ *attributes = NULL_TREE;
+ *tag_kind = (enum tag_types) tree_low_cst (aggr, 1);
+}
+
+/* Like xref_tag, except that the AGGR may be either a type node (like
+ class_type_node) or a TREE_LIST whose TREE_PURPOSE is a list of
+ attributes and whose TREE_VALUE is a type node. */
+
+static tree
+parse_xref_tag (tree aggr, tree name, int globalize)
+{
+ tree attributes;
+ enum tag_types tag_kind;
+ parse_split_aggr (aggr, &tag_kind, &attributes);
+ return xref_tag (tag_kind, name, attributes, globalize);
+}
+
+/* Like handle_class_head, but AGGR may be as for parse_xref_tag. */
+
+static tree
+parse_handle_class_head (tree aggr, tree scope, tree id,
+ int defn_p, int *new_type_p)
+{
+ tree attributes;
+ enum tag_types tag_kind;
+ parse_split_aggr (aggr, &tag_kind, &attributes);
+ return handle_class_head (tag_kind, scope, id, attributes,
+ defn_p, new_type_p);
+}
+
+/* Like do_decl_instantiation, but the declarator has not yet been
+ parsed. */
+
+static void
+parse_decl_instantiation (tree declspecs, tree declarator, tree storage)
+{
+ tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL);
+ do_decl_instantiation (decl, storage);
+}
+
+/* Like begin_function_definition, but SPECS_ATTRS is a combined list
+ containing both a decl-specifier-seq and attributes. */
+
+static int
+parse_begin_function_definition (tree specs_attrs, tree declarator)
+{
+ tree specs;
+ tree attrs;
+
+ split_specs_attrs (specs_attrs, &specs, &attrs);
+ return begin_function_definition (specs, attrs, declarator);
+}
+
+/* Like finish_call_expr, but the name for FN has not yet been
+ resolved. */
+
+static tree
+parse_finish_call_expr (tree fn, tree args, int koenig)
+{
+ bool disallow_virtual;
+
+ if (TREE_CODE (fn) == OFFSET_REF)
+ return build_offset_ref_call_from_tree (fn, args);
+
+ if (TREE_CODE (fn) == SCOPE_REF)
+ {
+ tree scope = TREE_OPERAND (fn, 0);
+ tree name = TREE_OPERAND (fn, 1);
+
+ if (scope == error_mark_node || name == error_mark_node)
+ return error_mark_node;
+ if (!processing_template_decl)
+ fn = resolve_scoped_fn_name (scope, name);
+ disallow_virtual = true;
+ }
+ else
+ disallow_virtual = false;
+
+ if (koenig && TREE_CODE (fn) == IDENTIFIER_NODE)
+ {
+ tree f;
+
+ /* Do the Koenig lookup. */
+ fn = do_identifier (fn, 2, args);
+ /* If name lookup didn't find any matching declarations, we've
+ got an unbound identifier. */
+ if (TREE_CODE (fn) == IDENTIFIER_NODE)
+ {
+ /* For some reason, do_identifier does not resolve
+ conversion operator names if the only matches would be
+ template conversion operators. So, we do it here. */
+ if (IDENTIFIER_TYPENAME_P (fn) && current_class_type)
+ {
+ f = lookup_member (current_class_type, fn,
+ /*protect=*/1, /*want_type=*/0);
+ if (f)
+ return finish_call_expr (f, args,
+ /*disallow_virtual=*/false);
+ }
+ /* If the name still could not be resolved, then the program
+ is ill-formed. */
+ if (TREE_CODE (fn) == IDENTIFIER_NODE)
+ {
+ unqualified_name_lookup_error (fn);
+ return error_mark_node;
+ }
+ }
+ else if (TREE_CODE (fn) == FUNCTION_DECL
+ || DECL_FUNCTION_TEMPLATE_P (fn)
+ || TREE_CODE (fn) == OVERLOAD)
+ {
+ tree scope = DECL_CONTEXT (get_first_fn (fn));
+ if (scope && TYPE_P (scope))
+ {
+ tree access_scope;
+
+ if (DERIVED_FROM_P (scope, current_class_type)
+ && current_class_ref)
+ {
+ fn = build_baselink (lookup_base (current_class_type,
+ scope,
+ ba_any,
+ NULL),
+ TYPE_BINFO (current_class_type),
+ fn,
+ /*optype=*/NULL_TREE);
+ return finish_object_call_expr (fn,
+ current_class_ref,
+ args);
+ }
+
+
+ access_scope = current_class_type;
+ while (!DERIVED_FROM_P (scope, access_scope))
+ {
+ access_scope = TYPE_CONTEXT (access_scope);
+ while (DECL_P (access_scope))
+ access_scope = DECL_CONTEXT (access_scope);
+ }
+
+ fn = build_baselink (NULL_TREE,
+ TYPE_BINFO (access_scope),
+ fn,
+ /*optype=*/NULL_TREE);
+ }
+ }
+ }
+
+ if (TREE_CODE (fn) == COMPONENT_REF)
+ /* If the parser sees `(x->y)(bar)' we get here because the
+ parentheses confuse the parser. Treat this like
+ `x->y(bar)'. */
+ return finish_object_call_expr (TREE_OPERAND (fn, 1),
+ TREE_OPERAND (fn, 0),
+ args);
+
+ if (processing_template_decl)
+ return build_nt (CALL_EXPR, fn, args, NULL_TREE);
+
+ return build_call_from_tree (fn, args, disallow_virtual);
+}
+
+#include "gt-cp-parse.h"
OpenPOWER on IntegriCloud