aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-12-30 23:29:33 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-12-30 23:29:33 +0000
commit1d786913b3e013765d108640d6f6ee03c63fcea2 (patch)
tree80c424b73600d77daa433461d979103437d7196b /gcc
parent36651afeec5fca8d1a0f00775b1586b1669f211f (diff)
downloadgcc-1d786913b3e013765d108640d6f6ee03c63fcea2.zip
gcc-1d786913b3e013765d108640d6f6ee03c63fcea2.tar.gz
gcc-1d786913b3e013765d108640d6f6ee03c63fcea2.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog26
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/decl.c66
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/cp/name-lookup.c22
-rw-r--r--gcc/cp/name-lookup.h2
-rw-r--r--gcc/cp/parser.c137
7 files changed, 138 insertions, 132 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4be3133..cad590d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c6d47c9..1309db3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7a839d7..61f2d64 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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))
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 231939d..0df5b25 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 0ee9dfe..7f1ba91 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -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);
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 5c64521..13ac459 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -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);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 2a72a5e..ccc6473 100644
--- a/gcc/cp/parser.c
+++ b/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,