struct module_info
{
+ tree ctor_decl;
vec <tree, va_gc> *ctors;
+ tree dtor_decl;
vec <tree, va_gc> *dtors;
vec <tree, va_gc> *ctorgates;
+ tree sharedctor_decl;
vec <tree, va_gc> *sharedctors;
+ tree shareddtor_decl;
vec <tree, va_gc> *shareddtors;
vec <tree, va_gc> *sharedctorgates;
+ tree standalonector_decl;
vec <tree, va_gc> *standalonectors;
+ tree unittest_decl;
vec <tree, va_gc> *unitTests;
};
basis, this is done to keep its size to a minimum. */
static tree
-layout_moduleinfo_fields (Module *decl, tree type)
+layout_moduleinfo_fields (Module *decl, module_info &mi, tree type)
{
HOST_WIDE_INT offset = int_size_in_bytes (type);
type = copy_aggregate_type (type);
/* First fields added are all the function pointers. */
- if (decl->sctor)
+ if (mi.ctor_decl)
layout_moduleinfo_field (ptr_type_node, type, offset);
- if (decl->sdtor)
+ if (mi.dtor_decl)
layout_moduleinfo_field (ptr_type_node, type, offset);
- if (decl->ssharedctor)
+ if (mi.sharedctor_decl)
layout_moduleinfo_field (ptr_type_node, type, offset);
- if (decl->sshareddtor)
+ if (mi.shareddtor_decl)
layout_moduleinfo_field (ptr_type_node, type, offset);
if (dmd::findGetMembers (decl))
layout_moduleinfo_field (ptr_type_node, type, offset);
- if (decl->sictor)
+ if (mi.standalonector_decl)
layout_moduleinfo_field (ptr_type_node, type, offset);
- if (decl->stest)
+ if (mi.unittest_decl)
layout_moduleinfo_field (ptr_type_node, type, offset);
/* Array of module imports is laid out as a length field, followed by
/* Output the ModuleInfo for module DECL and register it with druntime. */
static void
-layout_moduleinfo (Module *decl)
+layout_moduleinfo (Module *decl, module_info &mi)
{
ClassDeclarations aclasses;
FuncDeclaration *sgetmembers;
sgetmembers = dmd::findGetMembers (decl);
size_t flags = 0;
- if (decl->sctor)
+ if (mi.ctor_decl)
flags |= MItlsctor;
- if (decl->sdtor)
+ if (mi.dtor_decl)
flags |= MItlsdtor;
- if (decl->ssharedctor)
+ if (mi.sharedctor_decl)
flags |= MIctor;
- if (decl->sshareddtor)
+ if (mi.shareddtor_decl)
flags |= MIdtor;
if (sgetmembers)
flags |= MIxgetMembers;
- if (decl->sictor)
+ if (mi.standalonector_decl)
flags |= MIictor;
- if (decl->stest)
+ if (mi.unittest_decl)
flags |= MIunitTest;
if (aimports_dim)
flags |= MIimportedModules;
flags |= MIname;
tree minfo = get_moduleinfo_decl (decl);
- tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo));
+ tree type = layout_moduleinfo_fields (decl, mi, TREE_TYPE (minfo));
/* Put out the two named fields in a ModuleInfo decl:
uint flags;
char[N] name;
*/
if (flags & MItlsctor)
- CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor));
+ CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (mi.ctor_decl));
if (flags & MItlsdtor)
- CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor));
+ CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (mi.dtor_decl));
if (flags & MIctor)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
- build_address (decl->ssharedctor));
+ build_address (mi.sharedctor_decl));
if (flags & MIdtor)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
- build_address (decl->sshareddtor));
+ build_address (mi.shareddtor_decl));
if (flags & MIxgetMembers)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
build_address (get_symbol_decl (sgetmembers)));
if (flags & MIictor)
- CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor));
+ CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
+ build_address (mi.standalonector_decl));
if (flags & MIunitTest)
- CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest));
+ CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (mi.unittest_decl));
if (flags & MIimportedModules)
{
tm->aimports.push (decl);
if (mitest.ctors || mitest.ctorgates)
- tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"),
- mitest.ctors, mitest.ctorgates);
+ mitest.ctor_decl
+ = build_funcs_gates_fn (get_identifier ("*__modtestctor"),
+ mitest.ctors, mitest.ctorgates);
if (mitest.dtors)
- tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"),
- mitest.dtors, NULL);
+ mitest.dtor_decl
+ = build_funcs_gates_fn (get_identifier ("*__modtestdtor"),
+ mitest.dtors, NULL);
if (mi.standalonectors)
- tm->sictor
+ mitest.standalonector_decl
= build_funcs_gates_fn (get_identifier ("*__modtestsharedictor"),
mi.standalonectors, NULL);
if (mitest.sharedctors || mitest.sharedctorgates)
- tm->ssharedctor
+ mitest.sharedctor_decl
= build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"),
mitest.sharedctors, mitest.sharedctorgates);
if (mitest.shareddtors)
- tm->sshareddtor
+ mitest.shareddtor_decl
= build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"),
mitest.shareddtors, NULL);
if (mi.unitTests)
- tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
- mi.unitTests, NULL);
+ mitest.unittest_decl
+ = build_funcs_gates_fn (get_identifier ("*__modtest"),
+ mi.unitTests, NULL);
mi.unitTests = NULL;
- layout_moduleinfo (tm);
+ layout_moduleinfo (tm, mitest);
}
/* Default behavior is to always generate module info because of templates.
if (global.params.useModuleInfo && Module::moduleinfo != NULL)
{
if (mi.ctors || mi.ctorgates)
- decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"),
- mi.ctors, mi.ctorgates);
+ mi.ctor_decl = build_funcs_gates_fn (get_identifier ("*__modctor"),
+ mi.ctors, mi.ctorgates);
if (mi.dtors)
- decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"),
- mi.dtors, NULL);
+ mi.dtor_decl = build_funcs_gates_fn (get_identifier ("*__moddtor"),
+ mi.dtors, NULL);
if (mi.standalonectors)
- decl->sictor
+ mi.standalonector_decl
= build_funcs_gates_fn (get_identifier ("*__modsharedictor"),
mi.standalonectors, NULL);
if (mi.sharedctors || mi.sharedctorgates)
- decl->ssharedctor
+ mi.sharedctor_decl
= build_funcs_gates_fn (get_identifier ("*__modsharedctor"),
mi.sharedctors, mi.sharedctorgates);
if (mi.shareddtors)
- decl->sshareddtor
+ mi.shareddtor_decl
= build_funcs_gates_fn (get_identifier ("*__modshareddtor"),
mi.shareddtors, NULL);
if (mi.unitTests)
- decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
- mi.unitTests, NULL);
+ mi.unittest_decl = build_funcs_gates_fn (get_identifier ("*__modtest"),
+ mi.unitTests, NULL);
- layout_moduleinfo (decl);
+ layout_moduleinfo (decl, mi);
}
/* Process all deferred functions after finishing module. */
d_finish_decl (decl);
}
+/* Cached instance of class `__cpp_type_info_ptr`. */
+
+static hash_map<ClassDeclaration *, tree> *cpp_type_info_ptrs;
+
/* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet
exist, create it. The __cpp_type_info_ptr decl is then initialized with a
pointer to the C++ type_info for the given class. */
tree
get_cpp_typeinfo_decl (ClassDeclaration *decl)
{
- gcc_assert (decl->isCPPclass ());
+ hash_map_maybe_create<hm_ggc> (cpp_type_info_ptrs);
- if (decl->cpp_type_info_ptr_sym)
- return decl->cpp_type_info_ptr_sym;
+ if (tree *tiptr = cpp_type_info_ptrs->get (decl))
+ return *tiptr;
+
+ gcc_assert (decl->isCPPclass ());
if (!tinfo_types[TK_CPPTI_TYPE])
make_internal_typeinfo (TK_CPPTI_TYPE,
tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", "");
tree type = tinfo_types[TK_CPPTI_TYPE];
- decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type);
- DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL);
+ tree cpp_type_info = declare_extern_var (ident, type);
+ cpp_type_info_ptrs->put (decl, cpp_type_info);
+ DECL_LANG_SPECIFIC (cpp_type_info) = build_lang_decl (NULL);
/* Class is a reference, want the record type. */
- DECL_CONTEXT (decl->cpp_type_info_ptr_sym)
- = TREE_TYPE (build_ctype (decl->type));
- TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;
+ DECL_CONTEXT (cpp_type_info) = TREE_TYPE (build_ctype (decl->type));
+ TREE_READONLY (cpp_type_info) = 1;
/* Layout the initializer and emit the symbol. */
layout_cpp_typeinfo (decl);
- return decl->cpp_type_info_ptr_sym;
+ return cpp_type_info;
}
/* Get the exact TypeInfo for TYPE, if it doesn't exist, create it. */