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:
parent
1f845b302a
commit
c87ceb139f
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user