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;
#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) \
/* 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. */
{
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
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))
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
}
}
-/* 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;
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);
- }
-}
-\f
#ifndef ENABLE_SCOPE_CHECKING
# define ENABLE_SCOPE_CHECKING 0
#else
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;
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);
}
}
}
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);
#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);
\f
/* The datatype used to implement C++ scope. */
struct cp_binding_level;
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));
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)))
}
}
-/* 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,
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
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)