aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog58
-rw-r--r--gcc/cp/cp-tree.def5
-rw-r--r--gcc/cp/cp-tree.h75
-rw-r--r--gcc/cp/decl.c258
-rw-r--r--gcc/cp/decl2.c64
-rw-r--r--gcc/cp/ptree.c19
6 files changed, 262 insertions, 217 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3caae56..10da17a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,61 @@
+2003-03-15 <gcc@integrable-solutions.net>
+
+ Compile-time improvement: 2/n.
+ * cp-tree.h (struct cxx_binding): New datatype;
+ (struct lang_identifier): Use it.
+ (LOCAL_BINDING_P): Adjust definition.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ (IDENTIFIER_VALUE): Likewise.
+ (struct tree_binding): Remove.
+ (TS_CP_BINDING): Likewise.
+ ((union lang_tree_node): Remove field "binding".
+ (cxx_binding_clear): New macro.
+ (binding_for_name): Adjust return type.
+ (qualified_lookup_using_namespace): Adjust prototype.
+ (lookup_using_namespace): Adjust prototype.
+ (cxx_scope_find_binding_for_name): Declare.
+ * cp-tree.def: Remove CPLUS_BINDING definition.
+ * decl.c (push_binding): Adjust local variable type.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (free_bindings): Adjust type.
+ (find_binding): Adjust return type, add a third parameter. Remove
+ non-useful assertion now that we use static typing.
+ (cxx_scope_find_binding_for_name): New function.
+ (binding_for_name): Use it. Adjust local variable type. Simplify.
+ (namespace_binding): Simplify.
+ (set_namespace_binding): Likewise.
+ (set_identifier_type_value_with_scope): Adjust local variable type.
+ (lookup_tag): Don't type-abuse of local variable 'old'.
+ (lookup_namespace_name): Likewise. Allocate binding on stack.
+ (select_decl): Adjust prototype.
+ (unqualified_namespace_lookup): Allocate binding on stack.
+ Don't type-abuse of local variable 'val'.
+ (lookup_name_real): Likewise.
+ (maybe_inject_for_scope_var): Adjust local variable type.
+ (cp_tree_node_structure): Remove CPLUS_BINDING case label.
+ (namespace_binding): Adjust logic, simplify.
+ (BINDING_LEVEL): Adjust definition.
+ (push_class_level_binding): Adjust local variable type.
+ (struct cxx_saved_binding): Adjust field 'binding' type.
+ * decl2.c (ambiguous_decl): Adjust prototype.
+ (lookup_using_namespace): Adjust local variable type.
+ (qualified_lookup_using_namespace): Catch type error and correct
+ ensueing logic error.
+ (do_nonmember_using_decl): Adjust local variable type. Allocate
+ temporary cxx_binding on stack.
+ (do_toplevel_using_decl): Adjust local variable type.
+ * ptree.c (cxx_print_cxx_binding): New function.
+ (cxx_print_identifier): Use it.
+ (cxx_print_xnode): Delete CPLUS_BINDING case label.
+
2003-03-15 Roger Sayle <roger@eyesopen.com>
* tree.c (count_functions): Fix whitespace.
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 86103c4..e95d593 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -222,11 +222,6 @@ DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 2)
the template may be a LOOKUP_EXPR. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
-/* An association between name and entity. Parameters are the scope
- and the (non-type) value. TREE_TYPE indicates the type bound to
- the name. */
-DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2)
-
/* A list-like node for chaining overloading candidates. TREE_TYPE is
the original name, and the parameter is the FUNCTION_DECL. */
DEFTREECODE (OVERLOAD, "overload", 'x', 1)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index db603ba..59699cd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -44,7 +44,6 @@ struct diagnostic_context;
DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
TREE_INDIRECT_USING (in NAMESPACE_DECL).
- LOCAL_BINDING_P (in CPLUS_BINDING)
ICS_USER_FLAG (in _CONV)
CLEANUP_P (in TRY_BLOCK)
AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
@@ -56,14 +55,12 @@ struct diagnostic_context;
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
(TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out).
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE).
- INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
ICS_ELLIPSIS_FLAG (in _CONV)
BINFO_DEPENDENT_BASE_P (in BINFO)
DECL_INITIALIZED_P (in VAR_DECL)
2: IDENTIFIER_OPNAME_P.
TYPE_POLYMORPHIC_P (in _TYPE)
ICS_THIS_FLAG (in _CONV)
- BINDING_HAS_LEVEL_P (in CPLUS_BINDING)
BINFO_LOST_PRIMARY_P (in BINFO)
TREE_PARMLIST (in TREE_LIST)
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
@@ -225,14 +222,41 @@ struct diagnostic_context;
/* Datatype used to temporarily save C++ bindings (for implicit
instantiations purposes and like). Implemented in decl.c. */
typedef struct cxx_saved_binding cxx_saved_binding;
+
+/* Datatype that represents binding established by a declaration between
+ a name and a C++ entity. */
+typedef struct cxx_binding cxx_binding;
+
+/* (GC-)allocate a cxx_binding object. */
+#define cxx_binding_make() (ggc_alloc (sizeof (cxx_binding)))
+
+/* Zero out a cxx_binding pointed to by B. */
+#define cxx_binding_clear(B) memset ((B), 0, sizeof (cxx_binding))
+
+struct cxx_binding GTY(())
+{
+ /* Link to chain together various bindings for this name. */
+ cxx_binding *previous;
+ /* The non-type entity this name is bound to. */
+ tree value;
+ /* The type entity this name is bound to. */
+ tree type;
+ union tree_binding_u {
+ tree GTY ((tag ("0"))) scope;
+ struct cp_binding_level * GTY ((tag ("1"))) level;
+ } GTY ((desc ("%0.has_level"))) scope;
+ unsigned has_level : 1;
+ unsigned value_is_inherited : 1;
+ unsigned is_local : 1;
+};
/* Language-dependent contents of an identifier. */
struct lang_identifier GTY(())
{
struct c_common_identifier c_common;
- tree namespace_bindings;
- tree bindings;
+ cxx_binding *namespace_bindings;
+ cxx_binding *bindings;
tree class_value;
tree class_template_info;
struct lang_id2 *x;
@@ -275,30 +299,28 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
/* Nonzero if this binding is for a local scope, as opposed to a class
or namespace scope. */
-#define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0 (NODE)
+#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
/* Nonzero if BINDING_VALUE is from a base class of the class which is
currently being defined. */
-#define INHERITED_VALUE_BINDING_P(NODE) TREE_LANG_FLAG_1 (NODE)
+#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
/* For a binding between a name and an entity at a non-local scope,
defines the scope where the binding is declared. (Either a class
_TYPE node, or a NAMESPACE_DECL.) This macro should be used only
for namespace-level bindings; on the IDENTIFIER_BINDING list
BINDING_LEVEL is used instead. */
-#define BINDING_SCOPE(NODE) \
- (((struct tree_binding*)CPLUS_BINDING_CHECK (NODE))->scope.scope)
+#define BINDING_SCOPE(NODE) ((NODE)->scope.scope)
/* Nonzero if NODE has BINDING_LEVEL, rather than BINDING_SCOPE. */
-#define BINDING_HAS_LEVEL_P(NODE) TREE_LANG_FLAG_2 (NODE)
+#define BINDING_HAS_LEVEL_P(NODE) ((NODE)->has_level)
/* This is the declaration bound to the name. Possible values:
variable, overloaded function, namespace, template, enumerator. */
-#define BINDING_VALUE(NODE) \
- (((struct tree_binding*)CPLUS_BINDING_CHECK (NODE))->value)
+#define BINDING_VALUE(NODE) ((NODE)->value)
/* If name is bound to a type, this is the type (struct, union, enum). */
-#define BINDING_TYPE(NODE) TREE_TYPE (NODE)
+#define BINDING_TYPE(NODE) ((NODE)->type)
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
namespace_binding ((NODE), global_namespace)
@@ -332,17 +354,6 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
&& DECL_NAME (NODE) != NULL_TREE \
&& MAIN_NAME_P (DECL_NAME (NODE)))
-
-struct tree_binding GTY(())
-{
- struct tree_common common;
- union tree_binding_u {
- tree GTY ((tag ("0"))) scope;
- struct cp_binding_level * GTY ((tag ("1"))) level;
- } GTY ((desc ("BINDING_HAS_LEVEL_P ((tree)&%0)"))) scope;
- tree value;
-};
-
/* The overloaded FUNCTION_DECL. */
#define OVL_FUNCTION(NODE) \
(((struct tree_overload*)OVERLOAD_CHECK (NODE))->function)
@@ -420,8 +431,8 @@ struct tree_srcloc GTY(())
#define IDENTIFIER_TEMPLATE(NODE) \
(LANG_IDENTIFIER_CAST (NODE)->class_template_info)
-/* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the
- identifier. It's TREE_CHAIN is the next outermost binding. Each
+/* The IDENTIFIER_BINDING is the innermost cxx_binding for the
+ identifier. It's PREVIOUS is the next outermost binding. Each
BINDING_VALUE is a DECL for the associated declaration. Thus,
name lookup consists simply of pulling off the node at the front
of the list (modulo oddities for looking up the names of types,
@@ -433,9 +444,7 @@ struct tree_srcloc GTY(())
/* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or
NULL_TREE if there is no binding. */
#define IDENTIFIER_VALUE(NODE) \
- (IDENTIFIER_BINDING (NODE) \
- ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) \
- : NULL_TREE)
+ (IDENTIFIER_BINDING (NODE) ? IDENTIFIER_BINDING (NODE)->value : NULL)
/* If IDENTIFIER_CLASS_VALUE is set, then NODE is bound in the current
class, and IDENTIFIER_CLASS_VALUE is the value binding. This is
@@ -540,7 +549,6 @@ union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
desc ("tree_node_structure (&%h)"))) generic;
struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;
- struct tree_binding GTY ((tag ("TS_CP_BINDING"))) binding;
struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink;
struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper;
@@ -3705,7 +3713,7 @@ extern tree declare_local_label (tree);
extern tree define_label (const char *, int, tree);
extern void check_goto (tree);
extern void define_case_label (void);
-extern tree binding_for_name (tree, tree);
+extern cxx_binding *binding_for_name (tree, tree);
extern tree namespace_binding (tree, tree);
extern void set_namespace_binding (tree, tree, tree);
extern tree lookup_namespace_name (tree, tree);
@@ -3722,8 +3730,8 @@ extern tree namespace_ancestor (tree, tree);
extern bool is_ancestor (tree, tree);
extern tree unqualified_namespace_lookup (tree, int, tree *);
extern tree check_for_out_of_scope_variable (tree);
-extern bool lookup_using_namespace (tree, tree, tree, tree, int, tree *);
-extern bool qualified_lookup_using_namespace (tree, tree, tree, int);
+extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *);
+extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
extern tree build_library_fn (tree, tree);
extern tree build_library_fn_ptr (const char *, tree);
extern tree build_cp_library_fn_ptr (const char *, tree);
@@ -3795,6 +3803,7 @@ extern int nonstatic_local_decl_p (tree);
extern tree declare_global_var (tree, tree);
extern void register_dtor_fn (tree);
extern tmpl_spec_kind current_tmpl_spec_kind (int);
+extern cxx_binding *cxx_scope_find_binding_for_name (tree, tree);
extern tree cp_fname_init (const char *);
extern bool have_extern_spec;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1763c41..db116e1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -98,8 +98,8 @@ static void push_binding (tree, tree, struct cp_binding_level*);
static int add_binding (tree, tree);
static void pop_binding (tree, tree);
static tree local_variable_p_walkfn (tree *, int *, void *);
-static tree find_binding (tree, tree);
-static tree select_decl (tree, int);
+static cxx_binding *find_binding (tree, tree, cxx_binding *);
+static tree select_decl (cxx_binding *, int);
static int lookup_flags (int, int);
static tree qualify_lookup (tree, int);
static tree record_builtin_java_type (const char *, int);
@@ -887,33 +887,31 @@ finish_scope (void)
/* For a binding between a name and an entity at a block scope,
this is the `struct cp_binding_level' for the block. */
-#define BINDING_LEVEL(NODE) \
- (((struct tree_binding*)(NODE))->scope.level)
+#define BINDING_LEVEL(NODE) ((NODE)->scope.level)
-/* A free list of CPLUS_BINDING nodes, connected by their
+/* A free list of cxx_binding nodes, connected by their
TREE_CHAINs. */
-static GTY((deletable (""))) tree free_bindings;
+static GTY((deletable (""))) cxx_binding *free_bindings;
/* Make DECL the innermost binding for ID. The LEVEL is the binding
level at which this declaration is being bound. */
static void
-push_binding (tree id,
- tree decl,
- struct cp_binding_level* level)
+push_binding (tree id, tree decl, struct cp_binding_level* level)
{
- tree binding;
+ cxx_binding *binding;
if (free_bindings)
{
binding = free_bindings;
- free_bindings = TREE_CHAIN (binding);
+ free_bindings = binding->previous;
}
else
- binding = make_node (CPLUS_BINDING);
+ binding = cxx_binding_make ();
/* Now, fill in the binding information. */
+ binding->previous = IDENTIFIER_BINDING (id);
BINDING_VALUE (binding) = decl;
BINDING_TYPE (binding) = NULL_TREE;
BINDING_LEVEL (binding) = level;
@@ -922,7 +920,6 @@ push_binding (tree id,
BINDING_HAS_LEVEL_P (binding) = 1;
/* And put it on the front of the list of bindings for ID. */
- TREE_CHAIN (binding) = IDENTIFIER_BINDING (id);
IDENTIFIER_BINDING (id) = binding;
}
@@ -935,7 +932,7 @@ push_binding (tree id,
static int
add_binding (tree id, tree decl)
{
- tree binding = IDENTIFIER_BINDING (id);
+ cxx_binding *binding = IDENTIFIER_BINDING (id);
int ok = 1;
timevar_push (TV_NAME_LOOKUP);
@@ -1079,7 +1076,7 @@ int
push_class_binding (tree id, tree decl)
{
int result = 1;
- tree binding = IDENTIFIER_BINDING (id);
+ cxx_binding *binding = IDENTIFIER_BINDING (id);
tree context;
timevar_push (TV_NAME_LOOKUP);
@@ -1134,7 +1131,7 @@ push_class_binding (tree id, tree decl)
static void
pop_binding (tree id, tree decl)
{
- tree binding;
+ cxx_binding *binding;
if (id == NULL_TREE)
/* It's easiest to write the loops that call this function without
@@ -1146,7 +1143,7 @@ pop_binding (tree id, tree decl)
binding = IDENTIFIER_BINDING (id);
/* The name should be bound. */
- my_friendly_assert (binding != NULL_TREE, 0);
+ my_friendly_assert (binding != NULL, 0);
/* The DECL will be either the ordinary binding or the type
binding for this identifier. Remove that binding. */
@@ -1161,10 +1158,10 @@ pop_binding (tree id, tree decl)
{
/* We're completely done with the innermost binding for this
identifier. Unhook it from the list of bindings. */
- IDENTIFIER_BINDING (id) = TREE_CHAIN (binding);
+ IDENTIFIER_BINDING (id) = binding->previous;
/* Add it to the free list. */
- TREE_CHAIN (binding) = free_bindings;
+ binding->previous = free_bindings;
free_bindings = binding;
/* Clear the BINDING_LEVEL so the garbage collector doesn't walk
@@ -1376,8 +1373,8 @@ poplevel (int keep, int reverse, int functionbody)
if (leaving_for_scope && TREE_CODE (link) == VAR_DECL
&& DECL_NAME (link))
{
- tree outer_binding
- = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link)));
+ cxx_binding *outer_binding
+ = IDENTIFIER_BINDING (DECL_NAME (link))->previous;
tree ns_binding;
if (!outer_binding)
@@ -1432,7 +1429,7 @@ poplevel (int keep, int reverse, int functionbody)
current_binding_level->level_chain->
dead_vars_from_for);
- /* Although we don't pop the CPLUS_BINDING, we do clear
+ /* Although we don't pop the cxx_binding, we do clear
its BINDING_LEVEL since the level is going away now. */
BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link)))
= 0;
@@ -1657,15 +1654,15 @@ poplevel_class (void)
shadowed;
shadowed = TREE_CHAIN (shadowed))
{
- tree t;
-
- t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
- while (t && BINDING_LEVEL (t) != b)
- t = TREE_CHAIN (t);
+ cxx_binding *binding;
+
+ binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
+ while (binding && BINDING_LEVEL (binding) != b)
+ binding = binding->previous;
- if (t)
+ if (binding)
IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
- = BINDING_VALUE (t);
+ = BINDING_VALUE (binding);
}
}
else
@@ -2023,90 +2020,88 @@ print_binding_stack (void)
/* Namespace binding access routines: The namespace_bindings field of
the identifier is polymorphic, with three possible values:
- NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node
- indicating the BINDING_VALUE of global_namespace. */
+ NULL_TREE, a list of "cxx_binding"s. */
/* Check whether the a binding for the name to scope is known.
Assumes that the bindings of the name are already a list
of bindings. Returns the binding found, or NULL_TREE. */
-static tree
-find_binding (tree name, tree scope)
+static inline cxx_binding *
+find_binding (tree name, tree scope, cxx_binding *front)
{
- tree iter, prev = NULL_TREE;
+ cxx_binding *iter;
+ cxx_binding *prev = NULL;
timevar_push (TV_NAME_LOOKUP);
scope = ORIGINAL_NAMESPACE (scope);
- for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter;
- iter = TREE_CHAIN (iter))
+ for (iter = front; iter != NULL; iter = iter->previous)
{
- my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374);
if (BINDING_SCOPE (iter) == scope)
{
/* Move binding found to the front of the list, so
subsequent lookups will find it faster. */
if (prev)
{
- TREE_CHAIN (prev) = TREE_CHAIN (iter);
- TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ prev->previous = iter->previous;
+ iter->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, iter);
}
prev = iter;
}
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL);
+}
+
+/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
+cxx_binding *
+cxx_scope_find_binding_for_name (tree scope, tree name)
+{
+ cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ if (b)
+ {
+ scope = ORIGINAL_NAMESPACE (scope);
+ /* Fold-in case where NAME is used only once. */
+ if (scope == BINDING_SCOPE (b) && b->previous == NULL)
+ return b;
+ return find_binding (name, scope, b);
+ }
+ return b;
}
/* Always returns a binding for name in scope. If the
namespace_bindings is not a list, convert it to one first.
If no binding is found, make a new one. */
-tree
+cxx_binding *
binding_for_name (tree name, tree scope)
{
- tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- tree result;
+ cxx_binding *result;
scope = ORIGINAL_NAMESPACE (scope);
-
- if (b && TREE_CODE (b) != CPLUS_BINDING)
- {
- /* Get rid of optimization for global scope. */
- IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE;
- BINDING_VALUE (binding_for_name (name, global_namespace)) = b;
- b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- }
- if (b && (result = find_binding (name, scope)))
+ result = cxx_scope_find_binding_for_name (scope, name);
+ if (result)
return result;
/* Not found, make a new one. */
- result = make_node (CPLUS_BINDING);
- TREE_CHAIN (result) = b;
- IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
- BINDING_SCOPE (result) = scope;
+ result = cxx_binding_make ();
+ result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
BINDING_TYPE (result) = NULL_TREE;
BINDING_VALUE (result) = NULL_TREE;
+ BINDING_SCOPE (result) = scope;
+ IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
return result;
}
-/* Return the binding value for name in scope, considering that
- namespace_binding may or may not be a list of CPLUS_BINDINGS. */
+/* Return the binding value for name in scope. */
tree
namespace_binding (tree name, tree scope)
{
- tree b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- if (b == NULL_TREE)
- return NULL_TREE;
- if (scope == NULL_TREE)
- scope = global_namespace;
- if (TREE_CODE (b) != CPLUS_BINDING)
- return (scope == global_namespace) ? b : NULL_TREE;
- name = find_binding (name,scope);
- if (name == NULL_TREE)
- return name;
- return BINDING_VALUE (name);
+ cxx_binding *b =
+ cxx_scope_find_binding_for_name (scope ? scope : global_namespace, name);
+
+ return b ? b->value : NULL_TREE;
}
/* Set the binding value for name in scope. If modifying the binding
@@ -2115,21 +2110,11 @@ namespace_binding (tree name, tree scope)
void
set_namespace_binding (tree name, tree scope, tree val)
{
- tree b;
+ cxx_binding *b;
timevar_push (TV_NAME_LOOKUP);
if (scope == NULL_TREE)
scope = global_namespace;
-
- if (scope == global_namespace)
- {
- b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING)
- {
- IDENTIFIER_NAMESPACE_BINDINGS (name) = val;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
- }
- }
b = binding_for_name (name, scope);
BINDING_VALUE (b) = val;
timevar_pop (TV_NAME_LOOKUP);
@@ -2267,7 +2252,7 @@ struct cxx_saved_binding GTY(())
/* The name of the current binding. */
tree identifier;
/* The binding we're saving. */
- tree binding;
+ cxx_binding *binding;
tree class_value;
tree real_type_value;
};
@@ -2315,7 +2300,7 @@ store_bindings (tree names, cxx_saved_binding *old_bindings)
saved->binding = IDENTIFIER_BINDING (id);
saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
- IDENTIFIER_BINDING (id) = NULL_TREE;
+ IDENTIFIER_BINDING (id) = NULL;
IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
old_bindings = saved;
skip_it:
@@ -2455,7 +2440,7 @@ set_identifier_type_value_with_scope (tree id,
}
else
{
- tree binding = binding_for_name (id, current_namespace);
+ cxx_binding *binding = binding_for_name (id, current_namespace);
BINDING_TYPE (binding) = type;
/* Store marker instead of real type. */
type = global_type_node;
@@ -4328,7 +4313,7 @@ maybe_push_decl (tree decl)
void
push_class_level_binding (tree name, tree x)
{
- tree binding;
+ cxx_binding *binding;
timevar_push (TV_NAME_LOOKUP);
/* The class_binding_level will be NULL if x is a template
parameter name in a member template. */
@@ -4570,7 +4555,7 @@ push_overloaded_decl (tree decl, int flags)
*d = tree_cons (NULL_TREE, new_binding,
TREE_CHAIN (*d));
- /* And update the CPLUS_BINDING node. */
+ /* And update the cxx_binding node. */
BINDING_VALUE (IDENTIFIER_BINDING (name))
= new_binding;
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
@@ -5236,10 +5221,8 @@ follow_tag_typedef (tree type)
reported. */
static tree
-lookup_tag (enum tree_code form,
- tree name,
- struct cp_binding_level* binding_level,
- int thislevel_only)
+lookup_tag (enum tree_code form, tree name,
+ struct cp_binding_level* binding_level, int thislevel_only)
{
register struct cp_binding_level *level;
/* Nonzero if, we should look past a template parameter level, even
@@ -5262,18 +5245,22 @@ lookup_tag (enum tree_code form,
/* Do namespace lookup. */
for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
{
- tree old = binding_for_name (name, tail);
+ cxx_binding *binding =
+ cxx_scope_find_binding_for_name (tail, name);
+ tree old;
/* If we just skipped past a template parameter level,
even though THISLEVEL_ONLY, and we find a template
class declaration, then we use the _TYPE node for the
template. See the example below. */
if (thislevel_only && !allow_template_parms_p
- && old && BINDING_VALUE (old)
- && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old)))
- old = TREE_TYPE (BINDING_VALUE (old));
- else
- old = BINDING_TYPE (old);
+ && binding && BINDING_VALUE (binding)
+ && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding)))
+ old = TREE_TYPE (BINDING_VALUE (binding));
+ else if (binding)
+ old = BINDING_TYPE (binding);
+ else
+ old = NULL_TREE;
if (old)
{
@@ -5373,6 +5360,7 @@ lookup_namespace_name (tree namespace, tree name)
{
tree val;
tree template_id = NULL_TREE;
+ cxx_binding binding;
timevar_push (TV_NAME_LOOKUP);
my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
@@ -5402,13 +5390,13 @@ lookup_namespace_name (tree namespace, tree name)
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
- val = make_node (CPLUS_BINDING);
- if (!qualified_lookup_using_namespace (name, namespace, val, 0))
+ cxx_binding_clear (&binding);
+ if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- if (BINDING_VALUE (val))
+ if (binding.value)
{
- val = BINDING_VALUE (val);
+ val = binding.value;
if (template_id)
{
@@ -5723,7 +5711,7 @@ make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
/* Select the right _DECL from multiple choices. */
static tree
-select_decl (tree binding, int flags)
+select_decl (cxx_binding *binding, int flags)
{
tree val;
val = BINDING_VALUE (binding);
@@ -5759,44 +5747,42 @@ select_decl (tree binding, int flags)
tree
unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
{
- tree b = make_node (CPLUS_BINDING);
tree initial = current_decl_namespace ();
tree scope = initial;
tree siter;
struct cp_binding_level *level;
tree val = NULL_TREE;
+ cxx_binding binding;
timevar_push (TV_NAME_LOOKUP);
+ cxx_binding_clear (&binding);
if (spacesp)
*spacesp = NULL_TREE;
for (; !val; scope = CP_DECL_CONTEXT (scope))
{
+ cxx_binding *b = cxx_scope_find_binding_for_name (scope, name);
if (spacesp)
*spacesp = tree_cons (scope, NULL_TREE, *spacesp);
- val = binding_for_name (name, scope);
/* Ignore anticipated built-in functions. */
- if (val && BINDING_VALUE (val)
- && DECL_P (BINDING_VALUE (val))
- && DECL_LANG_SPECIFIC (BINDING_VALUE (val))
- && DECL_ANTICIPATED (BINDING_VALUE (val)))
- {
- BINDING_VALUE (b) = NULL_TREE;
- BINDING_TYPE (b) = NULL_TREE;
- }
- else
+ if (b && BINDING_VALUE (b)
+ && DECL_P (BINDING_VALUE (b))
+ && DECL_LANG_SPECIFIC (BINDING_VALUE (b))
+ && DECL_ANTICIPATED (BINDING_VALUE (b)))
+ /* Keep binding cleared. */;
+ else if (b)
{
/* Initialize binding for this context. */
- BINDING_VALUE (b) = BINDING_VALUE (val);
- BINDING_TYPE (b) = BINDING_TYPE (val);
+ binding.value = BINDING_VALUE (b);
+ binding.type = BINDING_TYPE (b);
}
/* Add all _DECLs seen through local using-directives. */
for (level = current_binding_level;
!level->namespace_p;
level = level->level_chain)
- if (!lookup_using_namespace (name, b, level->using_directives,
+ if (!lookup_using_namespace (name, &binding, level->using_directives,
scope, flags, spacesp))
/* Give up because of error. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@@ -5806,7 +5792,8 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
siter = initial;
while (1)
{
- if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter),
+ if (!lookup_using_namespace (name, &binding,
+ DECL_NAMESPACE_USING (siter),
scope, flags, spacesp))
/* Give up because of error. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
@@ -5814,7 +5801,7 @@ unqualified_namespace_lookup (tree name, int flags, tree* spacesp)
siter = CP_DECL_CONTEXT (siter);
}
- val = select_decl (b, flags);
+ val = select_decl (&binding, flags);
if (scope == global_namespace)
break;
}
@@ -5864,15 +5851,15 @@ lookup_qualified_name (tree scope, tree name, bool is_type_p, int flags)
{
if (TREE_CODE (scope) == NAMESPACE_DECL)
{
- tree val;
+ cxx_binding binding;
- val = make_node (CPLUS_BINDING);
+ cxx_binding_clear (&binding);
flags |= LOOKUP_COMPLAIN;
if (is_type_p)
flags |= LOOKUP_PREFER_TYPES;
- if (!qualified_lookup_using_namespace (name, scope, val, flags))
+ if (!qualified_lookup_using_namespace (name, scope, &binding, flags))
return NULL_TREE;
- return select_decl (val, flags);
+ return select_decl (&binding, flags);
}
else
return lookup_member (scope, name, 0, is_type_p);
@@ -5951,13 +5938,10 @@ check_for_out_of_scope_variable (tree decl)
using IDENTIFIER_CLASS_VALUE. */
tree
-lookup_name_real (tree name,
- int prefer_type,
- int nonclass,
- int namespaces_only,
- int flags)
+lookup_name_real (tree name, int prefer_type, int nonclass,
+ int namespaces_only, int flags)
{
- tree t;
+ cxx_binding *iter;
tree val = NULL_TREE;
timevar_push (TV_NAME_LOOKUP);
@@ -5997,20 +5981,20 @@ lookup_name_real (tree name,
if (current_class_type == NULL_TREE)
nonclass = 1;
- for (t = IDENTIFIER_BINDING (name); t; t = TREE_CHAIN (t))
+ for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
{
tree binding;
- if (!LOCAL_BINDING_P (t) && nonclass)
+ if (!LOCAL_BINDING_P (iter) && nonclass)
/* We're not looking for class-scoped bindings, so keep going. */
continue;
/* If this is the kind of thing we're looking for, we're done. */
- if (qualify_lookup (BINDING_VALUE (t), flags))
- binding = BINDING_VALUE (t);
+ if (qualify_lookup (BINDING_VALUE (iter), flags))
+ binding = BINDING_VALUE (iter);
else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (BINDING_TYPE (t), flags))
- binding = BINDING_TYPE (t);
+ && qualify_lookup (BINDING_TYPE (iter), flags))
+ binding = BINDING_TYPE (iter);
else
binding = NULL_TREE;
@@ -6024,7 +6008,7 @@ lookup_name_real (tree name,
/* Now lookup in namespace scopes. */
if (!val)
{
- t = unqualified_namespace_lookup (name, flags, 0);
+ tree t = unqualified_namespace_lookup (name, flags, 0);
if (t)
val = t;
}
@@ -7996,12 +7980,11 @@ maybe_inject_for_scope_var (tree decl)
Otherwise, we need to preserve the temp slot for decl to last
into the outer binding level. */
- tree outer_binding
- = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl)));
+ cxx_binding *outer_binding
+ = IDENTIFIER_BINDING (DECL_NAME (decl))->previous;
if (outer_binding && BINDING_LEVEL (outer_binding) == outer
- && (TREE_CODE (BINDING_VALUE (outer_binding))
- == VAR_DECL)
+ && (TREE_CODE (BINDING_VALUE (outer_binding)) == VAR_DECL)
&& DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
{
BINDING_VALUE (outer_binding)
@@ -14505,7 +14488,6 @@ cp_tree_node_structure (union lang_tree_node * t)
{
case DEFAULT_ARG: return TS_CP_DEFAULT_ARG;
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
- case CPLUS_BINDING: return TS_CP_BINDING;
case OVERLOAD: return TS_CP_OVERLOAD;
case TEMPLATE_PARM_INDEX: return TS_CP_TPI;
case PTRMEM_CST: return TS_CP_PTRMEM;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index fb25127..9937e75 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -63,7 +63,7 @@ static void mark_vtable_entries (tree);
static void grok_function_init (tree, tree);
static bool maybe_emit_vtables (tree);
static void add_using_namespace (tree, tree, bool);
-static tree ambiguous_decl (tree, tree, tree,int);
+static cxx_binding *ambiguous_decl (tree, cxx_binding *, cxx_binding *, int);
static tree build_anon_union_vars (tree);
static bool acceptable_java_type (tree);
static void output_vtable_inherit (tree);
@@ -3497,11 +3497,11 @@ merge_functions (tree s1, tree s2)
XXX In what way should I treat extern declarations?
XXX I don't want to repeat the entire duplicate_decls here */
-static tree
-ambiguous_decl (tree name, tree old, tree new, int flags)
+static cxx_binding *
+ambiguous_decl (tree name, cxx_binding *old, cxx_binding *new, int flags)
{
tree val, type;
- my_friendly_assert (old != NULL_TREE, 393);
+ my_friendly_assert (old != NULL, 393);
/* Copy the value. */
val = BINDING_VALUE (new);
if (val)
@@ -3536,12 +3536,8 @@ ambiguous_decl (tree name, tree old, tree new, int flags)
BINDING_VALUE (old) = val;
else if (val && val != BINDING_VALUE (old))
{
- if (is_overloaded_fn (BINDING_VALUE (old))
- && is_overloaded_fn (val))
- {
- BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old),
- val);
- }
+ if (is_overloaded_fn (BINDING_VALUE (old)) && is_overloaded_fn (val))
+ BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old), val);
else
{
/* Some declarations are functions, some are not. */
@@ -3587,23 +3583,23 @@ ambiguous_decl (tree name, tree old, tree new, int flags)
Returns false on errors. */
bool
-lookup_using_namespace (tree name, tree val, tree usings, tree scope,
+lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
int flags, tree *spacesp)
{
tree iter;
- tree val1;
timevar_push (TV_NAME_LOOKUP);
/* Iterate over all used namespaces in current, searching for using
directives of scope. */
for (iter = usings; iter; iter = TREE_CHAIN (iter))
if (TREE_VALUE (iter) == scope)
{
- if (spacesp)
- *spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE,
- *spacesp);
- val1 = binding_for_name (name, TREE_PURPOSE (iter));
- /* Resolve ambiguities. */
- val = ambiguous_decl (name, val, val1, flags);
+ cxx_binding *val1 =
+ cxx_scope_find_binding_for_name (TREE_PURPOSE (iter), name);
+ if (spacesp)
+ *spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE, *spacesp);
+ /* Resolve ambiguities. */
+ if (val1)
+ val = ambiguous_decl (name, val, val1, flags);
}
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
BINDING_VALUE (val) != error_mark_node);
@@ -3611,11 +3607,11 @@ lookup_using_namespace (tree name, tree val, tree usings, tree scope,
/* [namespace.qual]
Accepts the NAME to lookup and its qualifying SCOPE.
- Returns the name/type pair found into the CPLUS_BINDING RESULT,
+ Returns the name/type pair found into the cxx_binding *RESULT,
or false on error. */
bool
-qualified_lookup_using_namespace (tree name, tree scope, tree result,
+qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
int flags)
{
/* Maintain a list of namespaces visited... */
@@ -3626,11 +3622,12 @@ qualified_lookup_using_namespace (tree name, tree scope, tree result,
timevar_push (TV_NAME_LOOKUP);
/* Look through namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
- while (scope && (result != error_mark_node))
+ while (scope && result->value != error_mark_node)
{
+ cxx_binding *binding = cxx_scope_find_binding_for_name (scope, name);
seen = tree_cons (scope, NULL_TREE, seen);
- result = ambiguous_decl (name, result,
- binding_for_name (name, scope), flags);
+ if (binding)
+ result = ambiguous_decl (name, result, binding, flags);
if (!BINDING_VALUE (result) && !BINDING_TYPE (result))
/* Consider using directives. */
for (usings = DECL_NAMESPACE_USING (scope); usings;
@@ -3647,7 +3644,7 @@ qualified_lookup_using_namespace (tree name, tree scope, tree result,
else
scope = NULL_TREE; /* If there never was a todo list. */
}
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result != error_mark_node);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
}
/* [namespace.memdef]/2 */
@@ -4203,22 +4200,22 @@ static void
do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
tree *newval, tree *newtype)
{
- tree decls;
+ cxx_binding decls;
*newval = *newtype = NULL_TREE;
- decls = make_node (CPLUS_BINDING);
- if (!qualified_lookup_using_namespace (name, scope, decls, 0))
+ cxx_binding_clear (&decls);
+ if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
/* Lookup error */
return;
- if (!BINDING_VALUE (decls) && !BINDING_TYPE (decls))
+ if (!decls.value && !decls.type)
{
error ("`%D' not declared", name);
return;
}
/* Check for using functions. */
- if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls)))
+ if (decls.value && is_overloaded_fn (decls.value))
{
tree tmp, tmp1;
@@ -4230,7 +4227,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
}
*newval = oldval;
- for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
+ for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
{
tree new_fn = OVL_CURRENT (tmp);
@@ -4290,12 +4287,12 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
}
else
{
- *newval = BINDING_VALUE (decls);
+ *newval = decls.value;
if (oldval && !decls_match (*newval, oldval))
error ("`%D' is already declared in this scope", name);
}
- *newtype = BINDING_TYPE (decls);
+ *newtype = decls.type;
if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
{
error ("using declaration `%D' introduced ambiguous type `%T'",
@@ -4309,8 +4306,9 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
void
do_toplevel_using_decl (tree decl)
{
- tree scope, name, binding;
+ tree scope, name;
tree oldval, oldtype, newval, newtype;
+ cxx_binding *binding;
decl = validate_nonmember_using_decl (decl, &scope, &name);
if (decl == NULL_TREE)
diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c
index 5550d00..305a4f1 100644
--- a/gcc/cp/ptree.c
+++ b/gcc/cp/ptree.c
@@ -153,12 +153,21 @@ cxx_print_type (FILE *file, tree node, int indent)
}
}
+
+static void
+cxx_print_binding (FILE *stream, cxx_binding *binding, const char *prefix)
+{
+ fprintf (stream, "%s <", prefix);
+ fprintf (stream, HOST_PTR_PRINTF, (char *) binding);
+ fprintf (stream, ">");
+}
+
void
cxx_print_identifier (FILE *file, tree node, int indent)
{
- print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + 4);
+ cxx_print_binding (file, IDENTIFIER_NAMESPACE_BINDINGS (node), "bindings");
print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4);
- print_node (file, "local bindings", IDENTIFIER_BINDING (node), indent + 4);
+ cxx_print_binding (file, IDENTIFIER_BINDING (node), "local bindings");
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
@@ -170,12 +179,6 @@ cxx_print_xnode (FILE *file, tree node, int indent)
{
switch (TREE_CODE (node))
{
- case CPLUS_BINDING:
- fprintf (file, " scope ");
- fprintf (file, HOST_PTR_PRINTF, BINDING_SCOPE (node));
- print_node (file, "value", BINDING_VALUE (node), indent+4);
- print_node (file, "chain", TREE_CHAIN (node), indent+4);
- break;
case OVERLOAD:
print_node (file, "function", OVL_FUNCTION (node), indent+4);
print_node (file, "chain", TREE_CHAIN (node), indent+4);