diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-12-30 23:29:33 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-12-30 23:29:33 +0000 |
commit | 1d786913b3e013765d108640d6f6ee03c63fcea2 (patch) | |
tree | 80c424b73600d77daa433461d979103437d7196b | |
parent | 36651afeec5fca8d1a0f00775b1586b1669f211f (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cp/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 9 | ||||
-rw-r--r-- | gcc/cp/decl.c | 66 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 22 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 137 |
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, |