mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:40:32 +08:00
c++: Kill nested_udts
During the implementation of modules I added myself a note to implement nested_udt handling. It wasn't obvious to me what they were for and nothing seemed to be broken in ignoring them. I figured something would eventually pop up and I'd add support. Nothing popped up. Investigating on trunk discovered 3 places where we look at the nested-udts. I couldn't figure how the one in lookup_field_r was needed -- surely the regular lookup would find the type. It turned out that code was unreachable. So we can delete it. Next in do_type_instantiation, we walk the nested-utd table instantiating types. But those types are also on the TYPE_FIELDS list, which we've just iterated over. So I can move the handling into that loop. The final use is in handling structs that have a typedef name for linkage purposes. Again, we can just iterate over TYPE_FIELDS. (As commented, we probably don't need to do even that, as a DR, whose number I forget, requires such structs to only have C-like things in them. But I didn't go that far. Having removed all the uses of nested-udts, I can remove their creation from name-lookup, and as the only instance of a binding_table object, we can remove all that code too. gcc/cp/ * cp-tree.h (struct lang_type): Delete nested_udts field. (CLASSTYPE_NESTED_UTDS): Delete. * name-lookup.h (binding_table, binding_entry): Delete typedefs. (bt_foreach_proc): Likewise. (struct binding_entry_s): Delete. (SCOPE_DEFAULT_HT_SIZE, CLASS_SCOPE_HT_SIZE) (NAMESPACE_ORDINARY_HT_SIZE, NAMESPACE_STD_HT_SIZE) (GLOBAL_SCOPE_HT_SIZE): Delete. (binding_table_foreach, binding_table_find): Delete declarations. * name-lookup.c (ENTRY_INDEX): Delete. (free_binding_entry): Delete. (binding_entry_make, binding_entry_free): Delete. (struct binding_table_s): Delete. (binding_table_construct, binding_table_free): Delete. (binding_table_new, binding_table_expand): Delete. (binding_table_insert, binding_table_find): Delete. (binding_table_foreach): Delete. (maybe_process_template_type_declaration): Delete CLASSTYPE_NESTED_UTDS insertion. (do_pushtag): Likewise. * decl2.c (bt_reset_linkage_1): Fold into reset_type_linkage_1. (reset_type_linkage_2, bt_reset_linkage_2): Fold into reset_type_linkage. * pt.c (instantiate_class_template_1): Delete NESTED_UTDs comment. (bt_instantiate_type_proc): Delete. (do_type_instantiation): Instantiate implicit typedef fields. Delete NESTED_UTD walk. * search.c (lookup_field_r): Delete unreachable NESTED_UTD search.
This commit is contained in:
parent
88f8b3dda5
commit
54380d42e6
@ -2219,7 +2219,6 @@ struct GTY(()) lang_type {
|
||||
tree vtables;
|
||||
tree typeinfo_var;
|
||||
vec<tree, va_gc> *vbases;
|
||||
binding_table nested_udts;
|
||||
tree as_base;
|
||||
vec<tree, va_gc> *pure_virtuals;
|
||||
tree friend_classes;
|
||||
@ -2372,12 +2371,6 @@ struct GTY(()) lang_type {
|
||||
#define CLASSTYPE_DESTRUCTOR(NODE) \
|
||||
(get_class_binding_direct (NODE, dtor_identifier))
|
||||
|
||||
/* A dictionary of the nested user-defined-types (class-types, or enums)
|
||||
found within this class. This table includes nested member class
|
||||
templates. */
|
||||
#define CLASSTYPE_NESTED_UTDS(NODE) \
|
||||
(LANG_TYPE_CLASS_CHECK (NODE)->nested_udts)
|
||||
|
||||
/* Nonzero if NODE has a primary base class, i.e., a base class with
|
||||
which it shares the virtual function table pointer. */
|
||||
#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \
|
||||
|
@ -2894,9 +2894,8 @@ constrain_class_visibility (tree type)
|
||||
/* Functions for adjusting the visibility of a tagged type and its nested
|
||||
types and declarations when it gets a name for linkage purposes from a
|
||||
typedef. */
|
||||
|
||||
static void bt_reset_linkage_1 (binding_entry, void *);
|
||||
static void bt_reset_linkage_2 (binding_entry, void *);
|
||||
// FIXME: It is now a DR for such a class type to contain anything
|
||||
// other than C. So at minium most of this can probably be deleted.
|
||||
|
||||
/* First reset the visibility of all the types. */
|
||||
|
||||
@ -2905,13 +2904,9 @@ reset_type_linkage_1 (tree type)
|
||||
{
|
||||
set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
|
||||
if (CLASS_TYPE_P (type))
|
||||
binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
|
||||
bt_reset_linkage_1, NULL);
|
||||
}
|
||||
static void
|
||||
bt_reset_linkage_1 (binding_entry b, void */*data*/)
|
||||
{
|
||||
reset_type_linkage_1 (b->type);
|
||||
for (tree member = TYPE_FIELDS (type); member; member = DECL_CHAIN (member))
|
||||
if (DECL_IMPLICIT_TYPEDEF_P (member))
|
||||
reset_type_linkage_1 (TREE_TYPE (member));
|
||||
}
|
||||
|
||||
/* Then reset the visibility of any static data members or member
|
||||
@ -2930,9 +2925,10 @@ reset_decl_linkage (tree decl)
|
||||
tentative_decl_linkage (decl);
|
||||
}
|
||||
|
||||
static void
|
||||
reset_type_linkage_2 (tree type)
|
||||
void
|
||||
reset_type_linkage (tree type)
|
||||
{
|
||||
reset_type_linkage_1 (type);
|
||||
if (CLASS_TYPE_P (type))
|
||||
{
|
||||
if (tree vt = CLASSTYPE_VTABLES (type))
|
||||
@ -2955,24 +2951,12 @@ reset_type_linkage_2 (tree type)
|
||||
tree mem = STRIP_TEMPLATE (m);
|
||||
if (TREE_CODE (mem) == VAR_DECL || TREE_CODE (mem) == FUNCTION_DECL)
|
||||
reset_decl_linkage (mem);
|
||||
else if (DECL_IMPLICIT_TYPEDEF_P (mem))
|
||||
reset_type_linkage (TREE_TYPE (mem));
|
||||
}
|
||||
binding_table_foreach (CLASSTYPE_NESTED_UTDS (type),
|
||||
bt_reset_linkage_2, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
bt_reset_linkage_2 (binding_entry b, void */*data*/)
|
||||
{
|
||||
reset_type_linkage_2 (b->type);
|
||||
}
|
||||
void
|
||||
reset_type_linkage (tree type)
|
||||
{
|
||||
reset_type_linkage_1 (type);
|
||||
reset_type_linkage_2 (type);
|
||||
}
|
||||
|
||||
/* Set up our initial idea of what the linkage of DECL should be. */
|
||||
|
||||
void
|
||||
|
@ -1738,16 +1738,6 @@ insert_late_enum_def_bindings (tree klass, tree enumtype)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
of 2. */
|
||||
|
||||
#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
|
||||
|
||||
/* A free list of "binding_entry"s awaiting for re-use. */
|
||||
|
||||
static GTY((deletable)) binding_entry free_binding_entry = NULL;
|
||||
|
||||
/* The binding oracle; see cp-tree.h. */
|
||||
|
||||
cp_binding_oracle_function *cp_binding_oracle;
|
||||
@ -1770,180 +1760,6 @@ query_oracle (tree name)
|
||||
cp_binding_oracle (CP_ORACLE_IDENTIFIER, name);
|
||||
}
|
||||
|
||||
/* Create a binding_entry object for (NAME, TYPE). */
|
||||
|
||||
static inline binding_entry
|
||||
binding_entry_make (tree name, tree type)
|
||||
{
|
||||
binding_entry entry;
|
||||
|
||||
if (free_binding_entry)
|
||||
{
|
||||
entry = free_binding_entry;
|
||||
free_binding_entry = entry->chain;
|
||||
}
|
||||
else
|
||||
entry = ggc_alloc<binding_entry_s> ();
|
||||
|
||||
entry->name = name;
|
||||
entry->type = type;
|
||||
entry->chain = NULL;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* Put ENTRY back on the free list. */
|
||||
#if 0
|
||||
static inline void
|
||||
binding_entry_free (binding_entry entry)
|
||||
{
|
||||
entry->name = NULL;
|
||||
entry->type = NULL;
|
||||
entry->chain = free_binding_entry;
|
||||
free_binding_entry = entry;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The datatype used to implement the mapping from names to types at
|
||||
a given scope. */
|
||||
struct GTY(()) binding_table_s {
|
||||
/* Array of chains of "binding_entry"s */
|
||||
binding_entry * GTY((length ("%h.chain_count"))) chain;
|
||||
|
||||
/* The number of chains in this table. This is the length of the
|
||||
member "chain" considered as an array. */
|
||||
size_t chain_count;
|
||||
|
||||
/* Number of "binding_entry"s in this table. */
|
||||
size_t entry_count;
|
||||
};
|
||||
|
||||
/* Construct TABLE with an initial CHAIN_COUNT. */
|
||||
|
||||
static inline void
|
||||
binding_table_construct (binding_table table, size_t chain_count)
|
||||
{
|
||||
table->chain_count = chain_count;
|
||||
table->entry_count = 0;
|
||||
table->chain = ggc_cleared_vec_alloc<binding_entry> (table->chain_count);
|
||||
}
|
||||
|
||||
/* Make TABLE's entries ready for reuse. */
|
||||
#if 0
|
||||
static void
|
||||
binding_table_free (binding_table table)
|
||||
{
|
||||
size_t i;
|
||||
size_t count;
|
||||
|
||||
if (table == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0, count = table->chain_count; i < count; ++i)
|
||||
{
|
||||
binding_entry temp = table->chain[i];
|
||||
while (temp != NULL)
|
||||
{
|
||||
binding_entry entry = temp;
|
||||
temp = entry->chain;
|
||||
binding_entry_free (entry);
|
||||
}
|
||||
table->chain[i] = NULL;
|
||||
}
|
||||
table->entry_count = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate a table with CHAIN_COUNT, assumed to be a power of two. */
|
||||
|
||||
static inline binding_table
|
||||
binding_table_new (size_t chain_count)
|
||||
{
|
||||
binding_table table = ggc_alloc<binding_table_s> ();
|
||||
table->chain = NULL;
|
||||
binding_table_construct (table, chain_count);
|
||||
return table;
|
||||
}
|
||||
|
||||
/* Expand TABLE to twice its current chain_count. */
|
||||
|
||||
static void
|
||||
binding_table_expand (binding_table table)
|
||||
{
|
||||
const size_t old_chain_count = table->chain_count;
|
||||
const size_t old_entry_count = table->entry_count;
|
||||
const size_t new_chain_count = 2 * old_chain_count;
|
||||
binding_entry *old_chains = table->chain;
|
||||
size_t i;
|
||||
|
||||
binding_table_construct (table, new_chain_count);
|
||||
for (i = 0; i < old_chain_count; ++i)
|
||||
{
|
||||
binding_entry entry = old_chains[i];
|
||||
for (; entry != NULL; entry = old_chains[i])
|
||||
{
|
||||
const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
|
||||
const size_t j = ENTRY_INDEX (hash, new_chain_count);
|
||||
|
||||
old_chains[i] = entry->chain;
|
||||
entry->chain = table->chain[j];
|
||||
table->chain[j] = entry;
|
||||
}
|
||||
}
|
||||
table->entry_count = old_entry_count;
|
||||
}
|
||||
|
||||
/* Insert a binding for NAME to TYPE into TABLE. */
|
||||
|
||||
static void
|
||||
binding_table_insert (binding_table table, tree name, tree type)
|
||||
{
|
||||
const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
|
||||
const size_t i = ENTRY_INDEX (hash, table->chain_count);
|
||||
binding_entry entry = binding_entry_make (name, type);
|
||||
|
||||
entry->chain = table->chain[i];
|
||||
table->chain[i] = entry;
|
||||
++table->entry_count;
|
||||
|
||||
if (3 * table->chain_count < 5 * table->entry_count)
|
||||
binding_table_expand (table);
|
||||
}
|
||||
|
||||
/* Return the binding_entry, if any, that maps NAME. */
|
||||
|
||||
binding_entry
|
||||
binding_table_find (binding_table table, tree name)
|
||||
{
|
||||
const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
|
||||
binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
|
||||
|
||||
while (entry != NULL && entry->name != name)
|
||||
entry = entry->chain;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* Apply PROC -- with DATA -- to all entries in TABLE. */
|
||||
|
||||
void
|
||||
binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
|
||||
{
|
||||
size_t chain_count;
|
||||
size_t i;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
|
||||
chain_count = table->chain_count;
|
||||
for (i = 0; i < chain_count; ++i)
|
||||
{
|
||||
binding_entry entry = table->chain[i];
|
||||
for (; entry != NULL; entry = entry->chain)
|
||||
proc (entry, data);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ENABLE_SCOPE_CHECKING
|
||||
# define ENABLE_SCOPE_CHECKING 0
|
||||
#else
|
||||
@ -6884,10 +6700,6 @@ maybe_process_template_type_declaration (tree type, int is_friend,
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
/* This may change after the call to push_template_decl, but
|
||||
we want the original value. */
|
||||
tree name = DECL_NAME (decl);
|
||||
|
||||
decl = push_template_decl (decl, is_friend);
|
||||
if (decl == error_mark_node)
|
||||
return error_mark_node;
|
||||
@ -6906,17 +6718,8 @@ maybe_process_template_type_declaration (tree type, int is_friend,
|
||||
finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
|
||||
|
||||
if (!COMPLETE_TYPE_P (current_class_type))
|
||||
{
|
||||
maybe_add_class_template_decl_list (current_class_type,
|
||||
type, /*friend_p=*/0);
|
||||
/* Put this UTD in the table of UTDs for the class. */
|
||||
if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
|
||||
CLASSTYPE_NESTED_UTDS (current_class_type) =
|
||||
binding_table_new (SCOPE_DEFAULT_HT_SIZE);
|
||||
|
||||
binding_table_insert
|
||||
(CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
|
||||
}
|
||||
maybe_add_class_template_decl_list (current_class_type,
|
||||
type, /*friend_p=*/0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7077,17 +6880,8 @@ do_pushtag (tree name, tree type, TAG_how how)
|
||||
|
||||
if (b->kind == sk_class
|
||||
&& !COMPLETE_TYPE_P (current_class_type))
|
||||
{
|
||||
maybe_add_class_template_decl_list (current_class_type,
|
||||
type, /*friend_p=*/0);
|
||||
|
||||
if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL)
|
||||
CLASSTYPE_NESTED_UTDS (current_class_type)
|
||||
= binding_table_new (SCOPE_DEFAULT_HT_SIZE);
|
||||
|
||||
binding_table_insert
|
||||
(CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
|
||||
}
|
||||
maybe_add_class_template_decl_list (current_class_type,
|
||||
type, /*friend_p=*/0);
|
||||
|
||||
decl = TYPE_NAME (type);
|
||||
gcc_assert (TREE_CODE (decl) == TYPE_DECL);
|
||||
|
@ -23,29 +23,6 @@ along with GCC; see the file COPYING3. If not see
|
||||
|
||||
#include "c-family/c-common.h"
|
||||
|
||||
/* The type of dictionary used to map names to types declared at
|
||||
a given scope. */
|
||||
typedef struct binding_table_s *binding_table;
|
||||
typedef struct binding_entry_s *binding_entry;
|
||||
|
||||
/* The type of a routine repeatedly called by binding_table_foreach. */
|
||||
typedef void (*bt_foreach_proc) (binding_entry, void *);
|
||||
|
||||
struct GTY(()) binding_entry_s {
|
||||
binding_entry chain;
|
||||
tree name;
|
||||
tree type;
|
||||
};
|
||||
|
||||
/* These macros indicate the initial chains count for binding_table. */
|
||||
#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
|
||||
#define CLASS_SCOPE_HT_SIZE (1 << 3)
|
||||
#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
|
||||
#define NAMESPACE_STD_HT_SIZE (1 << 8)
|
||||
#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
|
||||
|
||||
extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
|
||||
extern binding_entry binding_table_find (binding_table, tree);
|
||||
|
||||
/* The datatype used to implement C++ scope. */
|
||||
struct cp_binding_level;
|
||||
|
32
gcc/cp/pt.c
32
gcc/cp/pt.c
@ -11851,7 +11851,6 @@ instantiate_class_template_1 (tree type)
|
||||
Ignore it; it will be regenerated when needed. */
|
||||
continue;
|
||||
|
||||
/* Build new CLASSTYPE_NESTED_UTDS. */
|
||||
bool class_template_p = (TREE_CODE (t) != ENUMERAL_TYPE
|
||||
&& TYPE_LANG_SPECIFIC (t)
|
||||
&& CLASSTYPE_IS_TEMPLATE (t));
|
||||
@ -12009,10 +12008,10 @@ instantiate_class_template_1 (tree type)
|
||||
TREE_TYPE (r) = error_mark_node;
|
||||
}
|
||||
|
||||
/* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
|
||||
such a thing will already have been added to the field
|
||||
list by tsubst_enum in finish_member_declaration in the
|
||||
CLASSTYPE_NESTED_UTDS case above. */
|
||||
/* If it is a TYPE_DECL for a class-scoped
|
||||
ENUMERAL_TYPE, such a thing will already have
|
||||
been added to the field list by tsubst_enum
|
||||
in finish_member_declaration case above. */
|
||||
if (!(TREE_CODE (r) == TYPE_DECL
|
||||
&& TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
|
||||
&& DECL_ARTIFICIAL (r)))
|
||||
@ -24959,19 +24958,6 @@ mark_class_instantiated (tree t, int extern_p)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called from do_type_instantiation through binding_table_foreach to
|
||||
do recursive instantiation for the type bound in ENTRY. */
|
||||
static void
|
||||
bt_instantiate_type_proc (binding_entry entry, void *data)
|
||||
{
|
||||
tree storage = tree (data);
|
||||
|
||||
if (CLASS_TYPE_P (entry->type)
|
||||
&& CLASSTYPE_TEMPLATE_INFO (entry->type)
|
||||
&& !uses_template_parms (CLASSTYPE_TI_ARGS (entry->type)))
|
||||
do_type_instantiation (entry->type, storage, 0);
|
||||
}
|
||||
|
||||
/* Perform an explicit instantiation of template class T. STORAGE, if
|
||||
non-null, is the RID for extern, inline or static. COMPLAIN is
|
||||
nonzero if this is called from the parser, zero if called recursively,
|
||||
@ -25095,10 +25081,14 @@ do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
|
||||
instantiate_decl (fld, /*defer_ok=*/true,
|
||||
/*expl_inst_class_mem_p=*/true);
|
||||
}
|
||||
else if (DECL_IMPLICIT_TYPEDEF_P (fld))
|
||||
{
|
||||
tree type = TREE_TYPE (fld);
|
||||
|
||||
if (CLASSTYPE_NESTED_UTDS (t))
|
||||
binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
|
||||
bt_instantiate_type_proc, storage);
|
||||
if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
|
||||
&& !uses_template_parms (CLASSTYPE_TI_ARGS (type)))
|
||||
do_type_instantiation (type, storage, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given a function DECL, which is a specialization of TMPL, modify
|
||||
|
@ -977,17 +977,6 @@ lookup_field_r (tree binfo, void *data)
|
||||
|
||||
nval = get_class_binding (type, lfi->name, lfi->want_type);
|
||||
|
||||
/* If we're looking up a type (as with an elaborated type specifier)
|
||||
we ignore all non-types we find. */
|
||||
if (lfi->want_type && nval && !DECL_DECLARES_TYPE_P (nval))
|
||||
{
|
||||
nval = NULL_TREE;
|
||||
if (CLASSTYPE_NESTED_UTDS (type))
|
||||
if (binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
|
||||
lfi->name))
|
||||
nval = TYPE_MAIN_DECL (e->type);
|
||||
}
|
||||
|
||||
/* If there is no declaration with the indicated name in this type,
|
||||
then there's nothing to do. */
|
||||
if (!nval)
|
||||
|
Loading…
x
Reference in New Issue
Block a user