cp-tree.h (add_binding): Remove declaration.

* 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

From-SVN: r71144
This commit is contained in:
Gabriel Dos Reis 2003-09-06 19:03:44 +00:00 committed by Gabriel Dos Reis
parent 1f845b302a
commit c87ceb139f
6 changed files with 107 additions and 82 deletions

View File

@ -1,3 +1,16 @@
2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
* 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 <nathan@codesourcery.com>
PR c++/11794

View File

@ -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)

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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) \