From 3bd975bc00b481ce8aa5fd2ffd703c5653e6933b Mon Sep 17 00:00:00 2001 From: gdr Date: Sat, 6 Sep 2003 19:03:44 +0000 Subject: [PATCH] * cp-tree.h (add_binding): Remove declaration. * name-lookup.h (supplement_binding): Declare. * decl.c (add_binding): Move to name-lookup.c. (push_local_binding): Adjust. (push_class_binding): Likewise. (set_identifier_type_value_with_scope): Likewise. * name-lookup.c (supplement_binding): Rename from add_binding. Return a bool. Improve documentation. (set_namespace_binding): Adjust. * Make-lang.in (cp/name-lookup.o): Depend on toplev.h git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71144 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 13 ++++++++ gcc/cp/Make-lang.in | 2 +- gcc/cp/cp-tree.h | 1 - gcc/cp/decl.c | 82 ++--------------------------------------------- gcc/cp/name-lookup.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++- gcc/cp/name-lookup.h | 1 + 6 files changed, 107 insertions(+), 82 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0e657be..755168e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2003-09-06 Gabriel Dos Reis + + * cp-tree.h (add_binding): Remove declaration. + * name-lookup.h (supplement_binding): Declare. + * decl.c (add_binding): Move to name-lookup.c. + (push_local_binding): Adjust. + (push_class_binding): Likewise. + (set_identifier_type_value_with_scope): Likewise. + * name-lookup.c (supplement_binding): Rename from add_binding. + Return a bool. Improve documentation. + (set_namespace_binding): Adjust. + * Make-lang.in (cp/name-lookup.o): Depend on toplev.h + 2003-09-06 Nathan Sidwell PR c++/11794 diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 8ab0b55..1f78e81 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -282,7 +282,7 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $( cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h + $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \ $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8a2d512..394514d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3754,7 +3754,6 @@ extern void register_dtor_fn (tree); extern tmpl_spec_kind current_tmpl_spec_kind (int); extern tree cp_fname_init (const char *); extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); -extern int add_binding (cxx_binding *, tree); extern bool have_extern_spec; /* in decl2.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c11a7c5..7e87cac 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -911,82 +911,6 @@ push_binding (tree id, tree decl, cxx_scope* level) IDENTIFIER_BINDING (id) = binding; } -/* ID is already bound in the current scope. But, DECL is an - additional binding for ID in the same scope. This is the `struct - stat' hack whereby a non-typedef class-name or enum-name can be - bound at the same level as some other kind of entity. It's the - responsibility of the caller to check that inserting this name is - valid here. Returns nonzero if the new binding was successful. */ - -int -add_binding (cxx_binding *binding, tree decl) -{ - tree bval = BINDING_VALUE (binding); - int ok = 1; - - timevar_push (TV_NAME_LOOKUP); - if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) - /* The new name is the type name. */ - BINDING_TYPE (binding) = decl; - else if (!bval) - /* This situation arises when push_class_level_binding moves an - inherited type-binding out of the way to make room for a new - value binding. */ - BINDING_VALUE (binding) = decl; - else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)) - { - /* The old binding was a type name. It was placed in - BINDING_VALUE because it was thought, at the point it was - declared, to be the only entity with such a name. Move the - type name into the type slot; it is now hidden by the new - binding. */ - BINDING_TYPE (binding) = bval; - BINDING_VALUE (binding) = decl; - INHERITED_VALUE_BINDING_P (binding) = 0; - } - else if (TREE_CODE (bval) == TYPE_DECL - && TREE_CODE (decl) == TYPE_DECL - && DECL_NAME (decl) == DECL_NAME (bval) - && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval)) - /* If either type involves template parameters, we must - wait until instantiation. */ - || uses_template_parms (TREE_TYPE (decl)) - || uses_template_parms (TREE_TYPE (bval)))) - /* We have two typedef-names, both naming the same type to have - the same name. This is OK because of: - - [dcl.typedef] - - In a given scope, a typedef specifier can be used to redefine - the name of any type declared in that scope to refer to the - type to which it already refers. */ - ok = 0; - /* There can be two block-scope declarations of the same variable, - so long as they are `extern' declarations. However, there cannot - be two declarations of the same static data member: - - [class.mem] - - A member shall not be declared twice in the - member-specification. */ - else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL - && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval) - && !DECL_CLASS_SCOPE_P (decl)) - { - duplicate_decls (decl, BINDING_VALUE (binding)); - ok = 0; - } - else - { - error ("declaration of `%#D'", decl); - cp_error_at ("conflicts with previous declaration `%#D'", - BINDING_VALUE (binding)); - ok = 0; - } - - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); -} - /* Add DECL to the list of things declared in B. */ static void @@ -1040,7 +964,7 @@ push_local_binding (tree id, tree decl, int flags) if (lookup_name_current_level (id)) { /* Supplement the existing binding. */ - if (!add_binding (IDENTIFIER_BINDING (id), decl)) + if (!supplement_binding (IDENTIFIER_BINDING (id), decl)) /* It didn't work. Something else must be bound at this level. Do not add DECL to the list of things to pop later. */ @@ -1079,7 +1003,7 @@ push_class_binding (tree id, tree decl) if (binding && BINDING_SCOPE (binding) == class_binding_level) /* Supplement the existing binding. */ - result = add_binding (IDENTIFIER_BINDING (id), decl); + result = supplement_binding (IDENTIFIER_BINDING (id), decl); else /* Create a new binding. */ push_binding (id, decl, class_binding_level); @@ -2336,7 +2260,7 @@ set_identifier_type_value_with_scope (tree id, if (decl) { if (BINDING_VALUE (binding)) - add_binding (binding, decl); + supplement_binding (binding, decl); else BINDING_VALUE (binding) = decl; } diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index c07b5ff..3a16b9c 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ #include "cp-tree.h" #include "name-lookup.h" #include "timevar.h" +#include "toplev.h" /* Compute the chain index of a binding_entry given the HASH value of its name and the total COUNT of chains. COUNT is assumed to be a power @@ -298,6 +299,93 @@ cxx_binding_free (cxx_binding *binding) binding->previous = free_bindings; free_bindings = binding; } + +/* BINDING records an existing declaration for a namein the current scope. + But, DECL is another declaration for that same identifier in the + same scope. This is the `struct stat' hack whereby a non-typedef + class name or enum-name can be bound at the same level as some other + kind of entity. + 3.3.7/1 + + A class name (9.1) or enumeration name (7.2) can be hidden by the + name of an object, function, or enumerator declared in the same scope. + If a class or enumeration name and an object, function, or enumerator + are declared in the same scope (in any order) with the same name, the + class or enumeration name is hidden wherever the object, function, or + enumerator name is visible. + + It's the responsibility of the caller to check that + inserting this name is valid here. Returns nonzero if the new binding + was successful. */ + +bool +supplement_binding (cxx_binding *binding, tree decl) +{ + tree bval = binding->value; + bool ok = true; + + timevar_push (TV_NAME_LOOKUP); + if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) + /* The new name is the type name. */ + binding->type = decl; + else if (!bval) + /* This situation arises when push_class_level_binding moves an + inherited type-binding out of the way to make room for a new + value binding. */ + binding->value = decl; + else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)) + { + /* The old binding was a type name. It was placed in + BINDING_VALUE because it was thought, at the point it was + declared, to be the only entity with such a name. Move the + type name into the type slot; it is now hidden by the new + binding. */ + binding->type = bval; + binding->value = decl; + binding->value_is_inherited = false; + } + else if (TREE_CODE (bval) == TYPE_DECL + && TREE_CODE (decl) == TYPE_DECL + && DECL_NAME (decl) == DECL_NAME (bval) + && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval)) + /* If either type involves template parameters, we must + wait until instantiation. */ + || uses_template_parms (TREE_TYPE (decl)) + || uses_template_parms (TREE_TYPE (bval)))) + /* We have two typedef-names, both naming the same type to have + the same name. This is OK because of: + + [dcl.typedef] + + In a given scope, a typedef specifier can be used to redefine + the name of any type declared in that scope to refer to the + type to which it already refers. */ + ok = false; + /* There can be two block-scope declarations of the same variable, + so long as they are `extern' declarations. However, there cannot + be two declarations of the same static data member: + + [class.mem] + + A member shall not be declared twice in the + member-specification. */ + else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL + && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval) + && !DECL_CLASS_SCOPE_P (decl)) + { + duplicate_decls (decl, binding->value); + ok = false; + } + else + { + error ("declaration of `%#D'", decl); + cp_error_at ("conflicts with previous declaration `%#D'", + binding->value); + ok = false; + } + + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); +} /* Return (from the stack of) the BINDING, if any, establihsed at SCOPE. */ @@ -382,7 +470,7 @@ set_namespace_binding (tree name, tree scope, tree val) || val == error_mark_node) BINDING_VALUE (b) = val; else - add_binding (b, val); + supplement_binding (b, val); timevar_pop (TV_NAME_LOOKUP); } diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 943106e..6a0917e 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -107,6 +107,7 @@ struct cxx_binding GTY(()) extern cxx_binding *cxx_binding_make (tree, tree); extern void cxx_binding_free (cxx_binding *); +extern bool supplement_binding (cxx_binding *, tree); /* True if SCOPE designates the global scope binding contour. */ #define global_scope_p(SCOPE) \ -- 2.7.4