From 771cf8312e09c968e0c92deb2d0210cf9c28efca Mon Sep 17 00:00:00 2001 From: gdr Date: Sat, 15 Mar 2003 16:30:02 +0000 Subject: [PATCH] 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. * parse.y (parse_scoped_id): Don't type-abuse of 'id'. Allocate temporary cxx_binding on stack. Simplify. * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64405 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 58 ++++++++++++ gcc/cp/cp-tree.def | 5 -- gcc/cp/cp-tree.h | 75 +++++++++------- gcc/cp/decl.c | 258 +++++++++++++++++++++++++---------------------------- gcc/cp/decl2.c | 64 +++++++------ gcc/cp/ptree.c | 19 ++-- 6 files changed, 262 insertions(+), 217 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3caae567932..10da17a4e78 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,61 @@ +2003-03-15 + + 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 * tree.c (count_functions): Fix whitespace. diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 86103c41eef..e95d5935b70 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 db603bacb73..59699cd918c 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 1763c41aaf5..db116e1f7a8 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 fb25127da33..9937e754ab7 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 5550d00869b..305a4f135c6 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); -- 2.11.4.GIT