mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
36651afeec
commit
1d786913b3
|
|
@ -1,4 +1,28 @@
|
|||
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
|
||||
* cvt.c (convert_to_void): Do not use STRIP_NOPs.
|
||||
|
|
|
|||
|
|
@ -3591,9 +3591,12 @@ struct cp_declarator {
|
|||
union {
|
||||
/* For identifiers. */
|
||||
struct {
|
||||
/* The name of the function -- an IDENTIFIER_NODE, BIT_NOT_EXPR,
|
||||
TEMPLATE_ID_EXPR, or SCOPE_REF. */
|
||||
tree name;
|
||||
/* If non-NULL, the qualifiying scope (a NAMESPACE_DECL or
|
||||
*_TYPE) for this identifier. */
|
||||
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
|
||||
function (if any). */
|
||||
special_function_kind sfk;
|
||||
|
|
|
|||
|
|
@ -1938,6 +1938,15 @@ duplicate_decls (tree newdecl, tree olddecl)
|
|||
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)
|
||||
{
|
||||
int function_size;
|
||||
|
|
@ -1999,6 +2008,11 @@ duplicate_decls (tree newdecl, tree olddecl)
|
|||
&& TREE_STATIC (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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
declaration occurs is the first operand. */
|
||||
if (declarator
|
||||
&& declarator->u.id.name
|
||||
&& TREE_CODE (declarator->u.id.name) == SCOPE_REF)
|
||||
return TREE_OPERAND (declarator->u.id.name, 0);
|
||||
&& declarator->u.id.qualifying_scope)
|
||||
return declarator->u.id.qualifying_scope;
|
||||
|
||||
/* Otherwise, the declarator is not a qualified name; the entity will
|
||||
be declared in the current scope. */
|
||||
|
|
@ -6628,26 +6641,15 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
|
||||
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)
|
||||
break;
|
||||
if (TREE_CODE (decl) == SCOPE_REF)
|
||||
if (qualifying_scope)
|
||||
{
|
||||
tree qualifying_scope = TREE_OPERAND (decl, 0);
|
||||
|
||||
/* 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))
|
||||
if (TYPE_P (qualifying_scope))
|
||||
{
|
||||
ctype = TYPE_MAIN_VARIANT (qualifying_scope);
|
||||
ctype = qualifying_scope;
|
||||
if (innermost_code != cdk_function
|
||||
&& current_class_type
|
||||
&& !UNIQUELY_DERIVED_FROM_P (ctype,
|
||||
|
|
@ -6655,13 +6657,11 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
{
|
||||
error ("type %qT is not derived from type %qT",
|
||||
ctype, current_class_type);
|
||||
ctype = NULL_TREE;
|
||||
return error_mark_node;
|
||||
}
|
||||
TREE_OPERAND (decl, 0) = ctype;
|
||||
}
|
||||
else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
|
||||
in_namespace = qualifying_scope;
|
||||
decl = TREE_OPERAND (decl, 1);
|
||||
}
|
||||
if (TREE_CODE (decl) == BASELINK)
|
||||
decl = BASELINK_FUNCTIONS (decl);
|
||||
|
|
@ -7125,9 +7125,9 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
{
|
||||
/* Avoid trying to get an operand off an identifier node. */
|
||||
if (declarator->kind != cdk_id)
|
||||
tmp = declarator->declarator->u.id.name;
|
||||
tmp = declarator->declarator->u.id.unqualified_name;
|
||||
else
|
||||
tmp = declarator->u.id.name;
|
||||
tmp = declarator->u.id.unqualified_name;
|
||||
op = IDENTIFIER_OPNAME_P (tmp);
|
||||
if (IDENTIFIER_TYPENAME_P (tmp))
|
||||
{
|
||||
|
|
@ -7192,9 +7192,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
unqualified_id = NULL_TREE;
|
||||
else
|
||||
{
|
||||
unqualified_id = id_declarator->u.id.name;
|
||||
if (TREE_CODE (unqualified_id) == SCOPE_REF)
|
||||
unqualified_id = TREE_OPERAND (unqualified_id, 1);
|
||||
unqualified_id = id_declarator->u.id.unqualified_name;
|
||||
if (TREE_CODE (unqualified_id) == BASELINK)
|
||||
unqualified_id = BASELINK_FUNCTIONS (unqualified_id);
|
||||
switch (TREE_CODE (unqualified_id))
|
||||
|
|
@ -7489,17 +7487,13 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
/* If DECLARATOR is non-NULL, we know it is a cdk_id declarator;
|
||||
otherwise, we would not have exited the loop above. */
|
||||
if (declarator
|
||||
&& TREE_CODE (declarator->u.id.name) == SCOPE_REF
|
||||
/* If the qualifying scope was invalid, it will have been set to
|
||||
NULL_TREE above. */
|
||||
&& TREE_OPERAND (declarator->u.id.name, 0)
|
||||
&& TYPE_P (TREE_OPERAND (declarator->u.id.name, 0)))
|
||||
&& declarator->u.id.qualifying_scope
|
||||
&& TYPE_P (declarator->u.id.qualifying_scope))
|
||||
{
|
||||
tree t;
|
||||
|
||||
ctype = TREE_OPERAND (declarator->u.id.name, 0);
|
||||
if (TYPE_P (ctype))
|
||||
ctype = TYPE_MAIN_VARIANT (ctype);
|
||||
ctype = declarator->u.id.qualifying_scope;
|
||||
ctype = TYPE_MAIN_VARIANT (ctype);
|
||||
t = ctype;
|
||||
while (t != NULL_TREE && CLASS_TYPE_P (t))
|
||||
{
|
||||
|
|
@ -7537,7 +7531,7 @@ grokdeclarator (const cp_declarator *declarator,
|
|||
}
|
||||
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
|
||||
&& NEW_DELETE_OPNAME_P (sname))
|
||||
|
|
|
|||
|
|
@ -830,11 +830,11 @@ grokfield (const cp_declarator *declarator,
|
|||
|
||||
if (!declspecs->any_specifiers_p
|
||||
&& declarator->kind == cdk_id
|
||||
&& TREE_CODE (declarator->u.id.name) == SCOPE_REF
|
||||
&& (TREE_CODE (TREE_OPERAND (declarator->u.id.name, 1))
|
||||
== IDENTIFIER_NODE))
|
||||
&& declarator->u.id.qualifying_scope
|
||||
&& TREE_CODE (declarator->u.id.unqualified_name) == IDENTIFIER_NODE)
|
||||
/* 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
|
||||
&& TREE_CODE (init) == TREE_LIST
|
||||
|
|
|
|||
|
|
@ -2686,34 +2686,24 @@ push_class_level_binding (tree name, tree x)
|
|||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
|
||||
}
|
||||
|
||||
/* Process "using SCOPE::NAME" in a class scope. Return the
|
||||
USING_DECL created. */
|
||||
|
||||
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
|
||||
|| !TREE_OPERAND (decl, 0)
|
||||
|| !TYPE_P (TREE_OPERAND (decl, 0)))
|
||||
if (!scope || !TYPE_P (scope))
|
||||
{
|
||||
error ("using-declaration for non-member at class scope");
|
||||
return NULL_TREE;
|
||||
}
|
||||
scope = TREE_OPERAND (decl, 0);
|
||||
name = TREE_OPERAND (decl, 1);
|
||||
if (TREE_CODE (name) == BIT_NOT_EXPR)
|
||||
{
|
||||
error ("using-declaration cannot name destructor");
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ extern void pop_decl_namespace (void);
|
|||
extern void do_namespace_alias (tree, tree);
|
||||
extern void do_toplevel_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 tree lookup_arg_dependent (tree, tree, tree);
|
||||
extern bool is_associated_namespace (tree, tree);
|
||||
|
|
|
|||
137
gcc/cp/parser.c
137
gcc/cp/parser.c
|
|
@ -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
|
||||
VAR_DECLs or FUNCTION_DECLs) should do that directly. */
|
||||
|
||||
static cp_declarator *make_id_declarator
|
||||
(tree);
|
||||
static cp_declarator *make_call_declarator
|
||||
(cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree);
|
||||
static cp_declarator *make_array_declarator
|
||||
|
|
@ -792,15 +790,31 @@ make_declarator (cp_declarator_kind kind)
|
|||
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 *
|
||||
make_id_declarator (tree id)
|
||||
static cp_declarator *
|
||||
make_id_declarator (tree qualifying_scope, tree unqualified_name)
|
||||
{
|
||||
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->u.id.name = id;
|
||||
declarator->u.id.qualifying_scope = qualifying_scope;
|
||||
declarator->u.id.unqualified_name = unqualified_name;
|
||||
declarator->u.id.sfk = sfk_none;
|
||||
|
||||
return declarator;
|
||||
|
|
@ -10160,9 +10174,7 @@ cp_parser_using_declaration (cp_parser* parser)
|
|||
if (at_class_scope_p ())
|
||||
{
|
||||
/* Create the USING_DECL. */
|
||||
decl = do_class_using_decl (build_nt (SCOPE_REF,
|
||||
parser->scope,
|
||||
identifier));
|
||||
decl = do_class_using_decl (parser->scope, identifier);
|
||||
/* Add it to the list of members in this class. */
|
||||
finish_member_declaration (decl);
|
||||
}
|
||||
|
|
@ -11018,33 +11030,36 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
}
|
||||
else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
|
||||
{
|
||||
tree id;
|
||||
tree qualifying_scope;
|
||||
tree unqualified_name;
|
||||
|
||||
/* Parse a declarator-id */
|
||||
if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
|
||||
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 (!cp_parser_parse_definitely (parser))
|
||||
id = error_mark_node;
|
||||
else if (TREE_CODE (id) != IDENTIFIER_NODE)
|
||||
unqualified_name = error_mark_node;
|
||||
else if (qualifying_scope
|
||||
|| (TREE_CODE (unqualified_name)
|
||||
!= IDENTIFIER_NODE))
|
||||
{
|
||||
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;
|
||||
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
|
||||
outside of the class itself, the SCOPE will sometimes
|
||||
be a TYPENAME_TYPE. For example, given:
|
||||
|
|
@ -11061,40 +11076,30 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
`S<T>::R' not a type. However, if `S' is
|
||||
specialized, then this `i' will not be used, so there
|
||||
is no harm in resolving the types here. */
|
||||
if (TREE_CODE (scope) == TYPENAME_TYPE)
|
||||
{
|
||||
tree type;
|
||||
|
||||
/* Resolve the TYPENAME_TYPE. */
|
||||
type = resolve_typename_type (scope,
|
||||
/*only_current_p=*/false);
|
||||
/* If that failed, the declarator is invalid. */
|
||||
if (type == error_mark_node)
|
||||
error ("%<%T::%D%> is not a type",
|
||||
TYPE_CONTEXT (scope),
|
||||
TYPE_IDENTIFIER (scope));
|
||||
/* Build a new DECLARATOR. */
|
||||
id = build_nt (SCOPE_REF, type, TREE_OPERAND (id, 1));
|
||||
}
|
||||
tree type;
|
||||
|
||||
/* Resolve the TYPENAME_TYPE. */
|
||||
type = resolve_typename_type (qualifying_scope,
|
||||
/*only_current_p=*/false);
|
||||
/* If that failed, the declarator is invalid. */
|
||||
if (type == error_mark_node)
|
||||
error ("%<%T::%D%> is not a type",
|
||||
TYPE_CONTEXT (qualifying_scope),
|
||||
TYPE_IDENTIFIER (qualifying_scope));
|
||||
qualifying_scope = type;
|
||||
}
|
||||
|
||||
declarator = make_id_declarator (id);
|
||||
if (id)
|
||||
declarator = make_id_declarator (qualifying_scope,
|
||||
unqualified_name);
|
||||
if (unqualified_name)
|
||||
{
|
||||
tree class_type;
|
||||
tree unqualified_name;
|
||||
|
||||
if (TREE_CODE (id) == SCOPE_REF
|
||||
&& CLASS_TYPE_P (TREE_OPERAND (id, 0)))
|
||||
{
|
||||
class_type = TREE_OPERAND (id, 0);
|
||||
unqualified_name = TREE_OPERAND (id, 1);
|
||||
}
|
||||
if (qualifying_scope
|
||||
&& CLASS_TYPE_P (qualifying_scope))
|
||||
class_type = qualifying_scope;
|
||||
else
|
||||
{
|
||||
class_type = current_class_type;
|
||||
unqualified_name = id;
|
||||
}
|
||||
class_type = current_class_type;
|
||||
|
||||
if (class_type)
|
||||
{
|
||||
|
|
@ -11111,7 +11116,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
|||
|
||||
if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
|
||||
*ctor_dtor_or_conv_p = -1;
|
||||
if (TREE_CODE (id) == SCOPE_REF
|
||||
if (qualifying_scope
|
||||
&& TREE_CODE (unqualified_name) == TYPE_DECL
|
||||
&& CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
|
||||
{
|
||||
|
|
@ -11333,8 +11338,6 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
|
|||
static tree
|
||||
cp_parser_declarator_id (cp_parser* parser)
|
||||
{
|
||||
tree id_expression;
|
||||
|
||||
/* The expression must be an id-expression. Assume that qualified
|
||||
names are the names of types so that:
|
||||
|
||||
|
|
@ -11349,20 +11352,11 @@ cp_parser_declarator_id (cp_parser* parser)
|
|||
int S<T>::R<T>::i = 3;
|
||||
|
||||
will work, too. */
|
||||
id_expression = cp_parser_id_expression (parser,
|
||||
/*template_keyword_p=*/false,
|
||||
/*check_dependency_p=*/false,
|
||||
/*template_p=*/NULL,
|
||||
/*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;
|
||||
return cp_parser_id_expression (parser,
|
||||
/*template_keyword_p=*/false,
|
||||
/*check_dependency_p=*/false,
|
||||
/*template_p=*/NULL,
|
||||
/*declarator_p=*/true);
|
||||
}
|
||||
|
||||
/* Parse a type-id.
|
||||
|
|
@ -13064,7 +13058,8 @@ cp_parser_member_declaration (cp_parser* parser)
|
|||
|
||||
/* Create the bitfield declaration. */
|
||||
decl = grokbitfield (identifier
|
||||
? make_id_declarator (identifier)
|
||||
? make_id_declarator (NULL_TREE,
|
||||
identifier)
|
||||
: NULL,
|
||||
&decl_specifiers,
|
||||
width);
|
||||
|
|
@ -14383,13 +14378,13 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
|
|||
switch (declarator->kind)
|
||||
{
|
||||
case cdk_id:
|
||||
if (TREE_CODE (declarator->u.id.name) == SCOPE_REF)
|
||||
if (declarator->u.id.qualifying_scope)
|
||||
{
|
||||
tree scope;
|
||||
tree member;
|
||||
|
||||
scope = TREE_OPERAND (declarator->u.id.name, 0);
|
||||
member = TREE_OPERAND (declarator->u.id.name, 1);
|
||||
scope = declarator->u.id.qualifying_scope;
|
||||
member = declarator->u.id.unqualified_name;
|
||||
|
||||
while (scope && CLASS_TYPE_P (scope))
|
||||
{
|
||||
|
|
@ -14412,10 +14407,10 @@ cp_parser_check_declarator_template_parameters (cp_parser* parser,
|
|||
scope = TYPE_CONTEXT (scope);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the DECLARATOR has the form `X<y>' then it uses one
|
||||
additional level of template parameters. */
|
||||
if (TREE_CODE (declarator->u.id.name) == TEMPLATE_ID_EXPR)
|
||||
else if (TREE_CODE (declarator->u.id.unqualified_name)
|
||||
== TEMPLATE_ID_EXPR)
|
||||
/* If the DECLARATOR has the form `X<y>' then it uses one
|
||||
additional level of template parameters. */
|
||||
++num_templates;
|
||||
|
||||
return cp_parser_check_template_parameters (parser,
|
||||
|
|
|
|||
Loading…
Reference in New Issue