Commit 1d786913 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (cp_declarator): Split "name" field into qualifying_scope and unqualified_name.

	* cp-tree.h (cp_declarator): Split "name" field into
	qualifying_scope and unqualified_name.
	* decl.c (get_scope_of_declarator): Adjust accordingly.
	(grokdeclarator): Likewise.
	* decl2.c (grokfield): Likewise, and adjust call to
	do_class_using_decl.
	* name-lookup.c (do_class_using_decl): Split "decl" into
	"scope" and "name".  Remove unnecessary code.
	* name-lookup.h (do_class_using_decl): Adjust declaration.
	* parser.c (make_id_declarator): Split "id" into qualifying_scope
	and unqualified_name.
	(cp_parser_using_declaration): Adjust call to do_class_using_decl.
	(cp_parser_direct_declarator): Adjust to handle the fact that
	cp_parser_declarator_id no longer returns a SCOPE_REF.
	(cp_parser_direct_declarator): Likewise.
	(cp_parser_declarator_id): Do not create a SCOPE_REF for qualified
	names.
	(cp_parser_member_declaration): Adjust call to make_id_declarator.
	(cp_parser_check_declarator_template_parameters): Do not expect a
	SCOPE_REF.

	* decl.c (duplicate_decls): Call ggc_free on declarations we will
	not be needing any longer.

From-SVN: r92746
parent 36651afe
2004-12-29 Mark Mitchell <mark@codesourcery.com> 2004-12-30 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (cp_declarator): Split "name" field into
qualifying_scope and unqualified_name.
* decl.c (get_scope_of_declarator): Adjust accordingly.
(grokdeclarator): Likewise.
* decl2.c (grokfield): Likewise, and adjust call to
do_class_using_decl.
* name-lookup.c (do_class_using_decl): Split "decl" into
"scope" and "name". Remove unnecessary code.
* name-lookup.h (do_class_using_decl): Adjust declaration.
* parser.c (make_id_declarator): Split "id" into qualifying_scope
and unqualified_name.
(cp_parser_using_declaration): Adjust call to do_class_using_decl.
(cp_parser_direct_declarator): Adjust to handle the fact that
cp_parser_declarator_id no longer returns a SCOPE_REF.
(cp_parser_direct_declarator): Likewise.
(cp_parser_declarator_id): Do not create a SCOPE_REF for qualified
names.
(cp_parser_member_declaration): Adjust call to make_id_declarator.
(cp_parser_check_declarator_template_parameters): Do not expect a
SCOPE_REF.
* decl.c (duplicate_decls): Call ggc_free on declarations we will
not be needing any longer.
PR c++/19190 PR c++/19190
* cvt.c (convert_to_void): Do not use STRIP_NOPs. * cvt.c (convert_to_void): Do not use STRIP_NOPs.
......
...@@ -3591,9 +3591,12 @@ struct cp_declarator { ...@@ -3591,9 +3591,12 @@ struct cp_declarator {
union { union {
/* For identifiers. */ /* For identifiers. */
struct { struct {
/* The name of the function -- an IDENTIFIER_NODE, BIT_NOT_EXPR, /* If non-NULL, the qualifiying scope (a NAMESPACE_DECL or
TEMPLATE_ID_EXPR, or SCOPE_REF. */ *_TYPE) for this identifier. */
tree name; tree qualifying_scope;
/* The unqualified name of the entity -- an IDENTIFIER_NODE,
BIT_NOT_EXPR, or TEMPLATE_ID_EXPR. */
tree unqualified_name;
/* If this is the name of a function, what kind of special /* If this is the name of a function, what kind of special
function (if any). */ function (if any). */
special_function_kind sfk; special_function_kind sfk;
......
...@@ -1938,6 +1938,15 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1938,6 +1938,15 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_VISIBILITY_SPECIFIED (newdecl) = 1; DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
} }
/* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced
with that from NEWDECL below. */
if (DECL_LANG_SPECIFIC (olddecl))
{
gcc_assert (DECL_LANG_SPECIFIC (olddecl)
!= DECL_LANG_SPECIFIC (newdecl));
ggc_free (DECL_LANG_SPECIFIC (olddecl));
}
if (TREE_CODE (newdecl) == FUNCTION_DECL) if (TREE_CODE (newdecl) == FUNCTION_DECL)
{ {
int function_size; int function_size;
...@@ -1999,6 +2008,11 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -1999,6 +2008,11 @@ duplicate_decls (tree newdecl, tree olddecl)
&& TREE_STATIC (olddecl)))) && TREE_STATIC (olddecl))))
make_decl_rtl (olddecl); make_decl_rtl (olddecl);
/* The NEWDECL will no longer be needed. Because every out-of-class
declaration of a member results in a call to duplicate_decls,
freeing these nodes represents in a significant savings. */
ggc_free (newdecl);
return olddecl; return olddecl;
} }
...@@ -6327,9 +6341,8 @@ get_scope_of_declarator (const cp_declarator *declarator) ...@@ -6327,9 +6341,8 @@ get_scope_of_declarator (const cp_declarator *declarator)
/* If the declarator-id is a SCOPE_REF, the scope in which the /* If the declarator-id is a SCOPE_REF, the scope in which the
declaration occurs is the first operand. */ declaration occurs is the first operand. */
if (declarator if (declarator
&& declarator->u.id.name && declarator->u.id.qualifying_scope)
&& TREE_CODE (declarator->u.id.name) == SCOPE_REF) return declarator->u.id.qualifying_scope;
return TREE_OPERAND (declarator->u.id.name, 0);
/* Otherwise, the declarator is not a qualified name; the entity will /* Otherwise, the declarator is not a qualified name; the entity will
be declared in the current scope. */ be declared in the current scope. */
...@@ -6628,26 +6641,15 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6628,26 +6641,15 @@ grokdeclarator (const cp_declarator *declarator,
case cdk_id: case cdk_id:
{ {
tree decl = id_declarator->u.id.name; tree qualifying_scope = id_declarator->u.id.qualifying_scope;
tree decl = id_declarator->u.id.unqualified_name;
if (!decl) if (!decl)
break; break;
if (TREE_CODE (decl) == SCOPE_REF) if (qualifying_scope)
{ {
tree qualifying_scope = TREE_OPERAND (decl, 0); if (TYPE_P (qualifying_scope))
/* It is valid to write:
class C { void f(); };
typedef C D;
void D::f();
The standard is not clear about whether `typedef const C D' is
legal; as of 2002-09-15 the committee is considering
that question. EDG 3.0 allows that syntax.
Therefore, we do as well. */
if (qualifying_scope && TYPE_P (qualifying_scope))
{ {
ctype = TYPE_MAIN_VARIANT (qualifying_scope); ctype = qualifying_scope;
if (innermost_code != cdk_function if (innermost_code != cdk_function
&& current_class_type && current_class_type
&& !UNIQUELY_DERIVED_FROM_P (ctype, && !UNIQUELY_DERIVED_FROM_P (ctype,
...@@ -6655,13 +6657,11 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -6655,13 +6657,11 @@ grokdeclarator (const cp_declarator *declarator,
{ {
error ("type %qT is not derived from type %qT", error ("type %qT is not derived from type %qT",
ctype, current_class_type); ctype, current_class_type);
ctype = NULL_TREE; return error_mark_node;
} }
TREE_OPERAND (decl, 0) = ctype;
} }
else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL) else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
in_namespace = qualifying_scope; in_namespace = qualifying_scope;
decl = TREE_OPERAND (decl, 1);
} }
if (TREE_CODE (decl) == BASELINK) if (TREE_CODE (decl) == BASELINK)
decl = BASELINK_FUNCTIONS (decl); decl = BASELINK_FUNCTIONS (decl);
...@@ -7125,9 +7125,9 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7125,9 +7125,9 @@ grokdeclarator (const cp_declarator *declarator,
{ {
/* Avoid trying to get an operand off an identifier node. */ /* Avoid trying to get an operand off an identifier node. */
if (declarator->kind != cdk_id) if (declarator->kind != cdk_id)
tmp = declarator->declarator->u.id.name; tmp = declarator->declarator->u.id.unqualified_name;
else else
tmp = declarator->u.id.name; tmp = declarator->u.id.unqualified_name;
op = IDENTIFIER_OPNAME_P (tmp); op = IDENTIFIER_OPNAME_P (tmp);
if (IDENTIFIER_TYPENAME_P (tmp)) if (IDENTIFIER_TYPENAME_P (tmp))
{ {
...@@ -7192,9 +7192,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7192,9 +7192,7 @@ grokdeclarator (const cp_declarator *declarator,
unqualified_id = NULL_TREE; unqualified_id = NULL_TREE;
else else
{ {
unqualified_id = id_declarator->u.id.name; unqualified_id = id_declarator->u.id.unqualified_name;
if (TREE_CODE (unqualified_id) == SCOPE_REF)
unqualified_id = TREE_OPERAND (unqualified_id, 1);
if (TREE_CODE (unqualified_id) == BASELINK) if (TREE_CODE (unqualified_id) == BASELINK)
unqualified_id = BASELINK_FUNCTIONS (unqualified_id); unqualified_id = BASELINK_FUNCTIONS (unqualified_id);
switch (TREE_CODE (unqualified_id)) switch (TREE_CODE (unqualified_id))
...@@ -7489,17 +7487,13 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7489,17 +7487,13 @@ grokdeclarator (const cp_declarator *declarator,
/* If DECLARATOR is non-NULL, we know it is a cdk_id declarator; /* If DECLARATOR is non-NULL, we know it is a cdk_id declarator;
otherwise, we would not have exited the loop above. */ otherwise, we would not have exited the loop above. */
if (declarator if (declarator
&& TREE_CODE (declarator->u.id.name) == SCOPE_REF && declarator->u.id.qualifying_scope
/* If the qualifying scope was invalid, it will have been set to && TYPE_P (declarator->u.id.qualifying_scope))
NULL_TREE above. */
&& TREE_OPERAND (declarator->u.id.name, 0)
&& TYPE_P (TREE_OPERAND (declarator->u.id.name, 0)))
{ {
tree t; tree t;
ctype = TREE_OPERAND (declarator->u.id.name, 0); ctype = declarator->u.id.qualifying_scope;
if (TYPE_P (ctype)) ctype = TYPE_MAIN_VARIANT (ctype);
ctype = TYPE_MAIN_VARIANT (ctype);
t = ctype; t = ctype;
while (t != NULL_TREE && CLASS_TYPE_P (t)) while (t != NULL_TREE && CLASS_TYPE_P (t))
{ {
...@@ -7537,7 +7531,7 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -7537,7 +7531,7 @@ grokdeclarator (const cp_declarator *declarator,
} }
else if (TREE_CODE (type) == FUNCTION_TYPE) else if (TREE_CODE (type) == FUNCTION_TYPE)
{ {
tree sname = TREE_OPERAND (declarator->u.id.name, 1); tree sname = declarator->u.id.unqualified_name;
if (TREE_CODE (sname) == IDENTIFIER_NODE if (TREE_CODE (sname) == IDENTIFIER_NODE
&& NEW_DELETE_OPNAME_P (sname)) && NEW_DELETE_OPNAME_P (sname))
......
...@@ -830,11 +830,11 @@ grokfield (const cp_declarator *declarator, ...@@ -830,11 +830,11 @@ grokfield (const cp_declarator *declarator,
if (!declspecs->any_specifiers_p if (!declspecs->any_specifiers_p
&& declarator->kind == cdk_id && declarator->kind == cdk_id
&& TREE_CODE (declarator->u.id.name) == SCOPE_REF && declarator->u.id.qualifying_scope
&& (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1)) && TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
== IDENTIFIER_NODE))
/* Access declaration */ /* Access declaration */
return do_class_using_decl (declarator->u.id.name); return do_class_using_decl (declarator->u.id.qualifying_scope,
declarator->u.id.unqualified_name);
if (init if (init
&& TREE_CODE (init) == TREE_LIST && TREE_CODE (init) == TREE_LIST
......
...@@ -2686,34 +2686,24 @@ push_class_level_binding (tree name, tree x) ...@@ -2686,34 +2686,24 @@ push_class_level_binding (tree name, tree x)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
} }
/* Process "using SCOPE::NAME" in a class scope. Return the
USING_DECL created. */
tree tree
do_class_using_decl (tree decl) do_class_using_decl (tree scope, tree name)
{ {
tree name, value, scope, type; tree value, type;
if (TREE_CODE (decl) != SCOPE_REF if (!scope || !TYPE_P (scope))
|| !TREE_OPERAND (decl, 0)
|| !TYPE_P (TREE_OPERAND (decl, 0)))
{ {
error ("using-declaration for non-member at class scope"); error ("using-declaration for non-member at class scope");
return NULL_TREE; return NULL_TREE;
} }
scope = TREE_OPERAND (decl, 0);
name = TREE_OPERAND (decl, 1);
if (TREE_CODE (name) == BIT_NOT_EXPR) if (TREE_CODE (name) == BIT_NOT_EXPR)
{ {
error ("using-declaration cannot name destructor"); error ("using-declaration cannot name destructor");
return NULL_TREE; return NULL_TREE;
} }
if (TREE_CODE (name) == TYPE_DECL)
name = DECL_NAME (name);
else if (TREE_CODE (name) == TEMPLATE_DECL)
name = DECL_NAME (name);
else if (BASELINK_P (name))
{
tree fns = BASELINK_FUNCTIONS (name);
name = DECL_NAME (get_first_fn (fns));
}
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
......
...@@ -335,7 +335,7 @@ extern void pop_decl_namespace (void); ...@@ -335,7 +335,7 @@ extern void pop_decl_namespace (void);
extern void do_namespace_alias (tree, tree); extern void do_namespace_alias (tree, tree);
extern void do_toplevel_using_decl (tree, tree, tree); extern void do_toplevel_using_decl (tree, tree, tree);
extern void do_local_using_decl (tree, tree, tree); extern void do_local_using_decl (tree, tree, tree);
extern tree do_class_using_decl (tree); extern tree do_class_using_decl (tree, tree);
extern void do_using_directive (tree); extern void do_using_directive (tree);
extern tree lookup_arg_dependent (tree, tree, tree); extern tree lookup_arg_dependent (tree, tree, tree);
extern bool is_associated_namespace (tree, tree); extern bool is_associated_namespace (tree, tree);
......
...@@ -747,8 +747,6 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs) ...@@ -747,8 +747,6 @@ clear_decl_specs (cp_decl_specifier_seq *decl_specs)
Other parts of the front end that need to create entities (like Other parts of the front end that need to create entities (like
VAR_DECLs or FUNCTION_DECLs) should do that directly. */ VAR_DECLs or FUNCTION_DECLs) should do that directly. */
static cp_declarator *make_id_declarator
(tree);
static cp_declarator *make_call_declarator static cp_declarator *make_call_declarator
(cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree); (cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree);
static cp_declarator *make_array_declarator static cp_declarator *make_array_declarator
...@@ -792,15 +790,31 @@ make_declarator (cp_declarator_kind kind) ...@@ -792,15 +790,31 @@ make_declarator (cp_declarator_kind kind)
return declarator; return declarator;
} }
/* Make a declarator for a generalized identifier. */ /* Make a declarator for a generalized identifier. If non-NULL, the
identifier is QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is
just UNQUALIFIED_NAME. */
cp_declarator * static cp_declarator *
make_id_declarator (tree id) make_id_declarator (tree qualifying_scope, tree unqualified_name)
{ {
cp_declarator *declarator; cp_declarator *declarator;
/* It is valid to write:
class C { void f(); };
typedef C D;
void D::f();
The standard is not clear about whether `typedef const C D' is
legal; as of 2002-09-15 the committee is considering that
question. EDG 3.0 allows that syntax. Therefore, we do as
well. */
if (qualifying_scope && TYPE_P (qualifying_scope))
qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
declarator = make_declarator (cdk_id); declarator = make_declarator (cdk_id);
declarator->u.id.name = id; declarator->u.id.qualifying_scope = qualifying_scope;
declarator->u.id.unqualified_name = unqualified_name;
declarator->u.id.sfk = sfk_none; declarator->u.id.sfk = sfk_none;
return declarator; return declarator;
...@@ -10160,9 +10174,7 @@ cp_parser_using_declaration (cp_parser* parser) ...@@ -10160,9 +10174,7 @@ cp_parser_using_declaration (cp_parser* parser)
if (at_class_scope_p ()) if (at_class_scope_p ())
{ {
/* Create the USING_DECL. */ /* Create the USING_DECL. */
decl = do_class_using_decl (build_nt (SCOPE_REF, decl = do_class_using_decl (parser->scope, identifier);
parser->scope,
identifier));
/* Add it to the list of members in this class. */ /* Add it to the list of members in this class. */
finish_member_declaration (decl); finish_member_declaration (decl);
} }
...@@ -11018,33 +11030,36 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11018,33 +11030,36 @@ cp_parser_direct_declarator (cp_parser* parser,
} }
else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT) else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
{ {
tree id; tree qualifying_scope;
tree unqualified_name;
/* Parse a declarator-id */ /* Parse a declarator-id */
if (dcl_kind == CP_PARSER_DECLARATOR_EITHER) if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
cp_parser_parse_tentatively (parser); cp_parser_parse_tentatively (parser);
id = cp_parser_declarator_id (parser); unqualified_name = cp_parser_declarator_id (parser);
qualifying_scope = parser->scope;
if (dcl_kind == CP_PARSER_DECLARATOR_EITHER) if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
{ {
if (!cp_parser_parse_definitely (parser)) if (!cp_parser_parse_definitely (parser))
id = error_mark_node; unqualified_name = error_mark_node;
else if (TREE_CODE (id) != IDENTIFIER_NODE) else if (qualifying_scope
|| (TREE_CODE (unqualified_name)
!= IDENTIFIER_NODE))
{ {
cp_parser_error (parser, "expected unqualified-id"); cp_parser_error (parser, "expected unqualified-id");
id = error_mark_node; unqualified_name = error_mark_node;
} }
} }
if (id == error_mark_node) if (unqualified_name == error_mark_node)
{ {
declarator = cp_error_declarator; declarator = cp_error_declarator;
break; break;
} }
if (TREE_CODE (id) == SCOPE_REF && at_namespace_scope_p ()) if (qualifying_scope && at_namespace_scope_p ()
&& TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
{ {
tree scope = TREE_OPERAND (id, 0);
/* In the declaration of a member of a template class /* In the declaration of a member of a template class
outside of the class itself, the SCOPE will sometimes outside of the class itself, the SCOPE will sometimes
be a TYPENAME_TYPE. For example, given: be a TYPENAME_TYPE. For example, given:
...@@ -11061,40 +11076,30 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11061,40 +11076,30 @@ cp_parser_direct_declarator (cp_parser* parser,
`S<T>::R' not a type. However, if `S' is `S<T>::R' not a type. However, if `S' is
specialized, then this `i' will not be used, so there specialized, then this `i' will not be used, so there
is no harm in resolving the types here. */ is no harm in resolving the types here. */
if (TREE_CODE (scope) == TYPENAME_TYPE) tree type;
{
tree type; /* Resolve the TYPENAME_TYPE. */
type = resolve_typename_type (qualifying_scope,
/* Resolve the TYPENAME_TYPE. */ /*only_current_p=*/false);
type = resolve_typename_type (scope, /* If that failed, the declarator is invalid. */
/*only_current_p=*/false); if (type == error_mark_node)
/* If that failed, the declarator is invalid. */ error ("%<%T::%D%> is not a type",
if (type == error_mark_node) TYPE_CONTEXT (qualifying_scope),
error ("%<%T::%D%> is not a type", TYPE_IDENTIFIER (qualifying_scope));
TYPE_CONTEXT (scope), qualifying_scope = type;
TYPE_IDENTIFIER (scope));
/* Build a new DECLARATOR. */
id = build_nt (SCOPE_REF, type, TREE_OPERAND (id, 1));
}
} }
declarator = make_id_declarator (id); declarator = make_id_declarator (qualifying_scope,
if (id) unqualified_name);
if (unqualified_name)
{ {
tree class_type; tree class_type;
tree unqualified_name;
if (TREE_CODE (id) == SCOPE_REF if (qualifying_scope
&& CLASS_TYPE_P (TREE_OPERAND (id, 0))) && CLASS_TYPE_P (qualifying_scope))
{ class_type = qualifying_scope;
class_type = TREE_OPERAND (id, 0);
unqualified_name = TREE_OPERAND (id, 1);
}
else else
{ class_type = current_class_type;
class_type = current_class_type;
unqualified_name = id;
}
if (class_type) if (class_type)
{ {
...@@ -11111,7 +11116,7 @@ cp_parser_direct_declarator (cp_parser* parser, ...@@ -11111,7 +11116,7 @@ cp_parser_direct_declarator (cp_parser* parser,
if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none) if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
*ctor_dtor_or_conv_p = -1; *ctor_dtor_or_conv_p = -1;
if (TREE_CODE (id) == SCOPE_REF if (qualifying_scope
&& TREE_CODE (unqualified_name) == TYPE_DECL && TREE_CODE (unqualified_name) == TYPE_DECL
&& CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name))) && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
{ {
...@@ -11333,8 +11338,6 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser) ...@@ -11333,8 +11338,6 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
static tree static tree
cp_parser_declarator_id (cp_parser* parser) cp_parser_declarator_id (cp_parser* parser)
{ {
tree id_expression;
/* The expression must be an id-expression. Assume that qualified /* The expression must be an id-expression. Assume that qualified
names are the names of types so that: names are the names of types so that:
...@@ -11349,20 +11352,11 @@ cp_parser_declarator_id (cp_parser* parser) ...@@ -11349,20 +11352,11 @@ cp_parser_declarator_id (cp_parser* parser)
int S<T>::R<T>::i = 3; int S<T>::R<T>::i = 3;
will work, too. */ will work, too. */
id_expression = cp_parser_id_expression (parser, return cp_parser_id_expression (parser,
/*template_keyword_p=*/false, /*template_keyword_p=*/false,
/*check_dependency_p=*/false, /*check_dependency_p=*/false,
/*template_p=*/NULL, /*template_p=*/NULL,
/*declarator_p=*/true); /*declarator_p=*/true);
/* If the name was qualified, create a SCOPE_REF to represent
that. */
if (parser->scope)
{
id_expression = build_nt (SCOPE_REF, parser->scope, id_expression);
parser->scope = NULL_TREE;
}
return id_expression;
} }
/* Parse a type-id. /* Parse a type-id.
...@@ -13064,7 +13058,8 @@ cp_parser_member_declaration (cp_parser* parser) ...@@ -13064,7 +13058,8 @@ cp_parser_member_declaration (cp_parser* parser)
/* Create the bitfield declaration. */ /* Create the bitfield declaration. */
decl = grokbitfield (identifier decl = grokbitfield (identifier
? make_id_declarator (identifier) ? make_id_declarator (NULL_TREE,
identifier)
: NULL, : NULL,
&decl_specifiers, &decl_specifiers,
width); width);
...@@ -14383,13 +14378,13 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -14383,13 +14378,13 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
switch (declarator->kind) switch (declarator->kind)
{ {
case cdk_id: case cdk_id:
if (TREE_CODE (declarator->u.id.name) == SCOPE_REF) if (declarator->u.id.qualifying_scope)
{ {
tree scope; tree scope;
tree member; tree member;
scope = TREE_OPERAND (declarator->u.id.name, 0); scope = declarator->u.id.qualifying_scope;
member = TREE_OPERAND (declarator->u.id.name, 1); member = declarator->u.id.unqualified_name;
while (scope && CLASS_TYPE_P (scope)) while (scope && CLASS_TYPE_P (scope))
{ {
...@@ -14412,10 +14407,10 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser, ...@@ -14412,10 +14407,10 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
scope = TYPE_CONTEXT (scope); scope = TYPE_CONTEXT (scope);
} }
} }
else if (TREE_CODE (declarator->u.id.unqualified_name)
/* If the DECLARATOR has the form `X<y>' then it uses one == TEMPLATE_ID_EXPR)
additional level of template parameters. */ /* If the DECLARATOR has the form `X<y>' then it uses one
if (TREE_CODE (declarator->u.id.name) == TEMPLATE_ID_EXPR) additional level of template parameters. */
++num_templates; ++num_templates;
return cp_parser_check_template_parameters (parser, return cp_parser_check_template_parameters (parser,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment