d: Refactor for changes to dmd front-end inteface

There are a number of interface changes being made to the dmd front-end
interface. This makes any necessary refactorings ahead of the merge to
reduce the size of the diff.

gcc/d/ChangeLog:

	* decl.cc (DeclVisitor::visit (EnumDeclaration *)): Treat sinit member
	field as a generic pointer.
	(enum_initializer_decl): Likewise.
	* expr.cc (ExprVisitor::visit (ArrayLiteralExp *)): Compute static
	array length separately from creating type.
	* modules.cc (struct module_info): Add ctor_decl, dtor_decl,
	sharedctor_decl, shareddtor_decl, standalonector_decl, and
	unittest_decl.
	(layout_moduleinfo_fields): Add mi argument. Use it to check whether
	module helpers have been generated.
	(layout_moduleinfo): Likewise.
	(build_module_tree): Cache generated module helpers in module_info.
	* typeinfo.cc (cpp_type_info_ptrs): New variable.
	(get_cpp_typeinfo_decl): Cache generated C++ type_info references in
	cpp_type_info_ptrs.
	* types.cc (TypeVisitor::visit (TypeEnum *)): Separate getting
	front-end member value from building its CST tree.
This commit is contained in:
Iain Buclaw
2026-01-30 09:06:39 +01:00
parent 9f0f81c515
commit 6f3d4f1258
5 changed files with 84 additions and 61 deletions

View File

@@ -731,9 +731,10 @@ public:
if (tc->sym->members && !dmd::isZeroInit (d->type))
{
/* Generate static initializer. */
d->sinit = enum_initializer_decl (d);
DECL_INITIAL (d->sinit) = build_expr (tc->sym->defaultval, true);
d_finish_decl (d->sinit);
tree sinit = enum_initializer_decl (d);
d->sinit = sinit;
DECL_INITIAL (sinit) = build_expr (tc->sym->defaultval, true);
d_finish_decl (sinit);
}
d->semanticRun (PASS::obj);
@@ -2454,20 +2455,21 @@ tree
enum_initializer_decl (EnumDeclaration *decl)
{
if (decl->sinit)
return decl->sinit;
return (tree) decl->sinit;
gcc_assert (decl->ident);
tree type = build_ctype (decl->type);
tree ident = mangle_internal_decl (decl, "__init", "Z");
decl->sinit = declare_extern_var (ident, type);
DECL_LANG_SPECIFIC (decl->sinit) = build_lang_decl (NULL);
tree sinit = declare_extern_var (ident, type);
DECL_LANG_SPECIFIC (sinit) = build_lang_decl (NULL);
DECL_CONTEXT (decl->sinit) = d_decl_context (decl);
TREE_READONLY (decl->sinit) = 1;
DECL_CONTEXT (sinit) = d_decl_context (decl);
TREE_READONLY (sinit) = 1;
return decl->sinit;
decl->sinit = sinit;
return sinit;
}
/* Return an anonymous static variable of type TYPE, initialized with INIT,

View File

@@ -2582,7 +2582,10 @@ public:
/* Implicitly convert void[n] to ubyte[n]. */
if (tb->ty == TY::Tsarray && tb->nextOf ()->toBasetype ()->ty == TY::Tvoid)
tb = dmd::sarrayOf (Type::tuns8, tb->isTypeSArray ()->dim->toUInteger ());
{
dinteger_t ndim = tb->isTypeSArray ()->dim->toUInteger ();
tb = dmd::sarrayOf (Type::tuns8, ndim);
}
gcc_assert (tb->ty == TY::Tarray || tb->ty == TY::Tsarray
|| tb->ty == TY::Tpointer);

View File

@@ -78,15 +78,21 @@ static tree stop_minfo_node;
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;
};
@@ -487,31 +493,31 @@ layout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT &offset)
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
@@ -558,7 +564,7 @@ layout_moduleinfo_fields (Module *decl, tree type)
/* 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;
@@ -576,19 +582,19 @@ layout_moduleinfo (Module *decl)
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;
@@ -600,7 +606,7 @@ layout_moduleinfo (Module *decl)
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;
@@ -626,28 +632,29 @@ layout_moduleinfo (Module *decl)
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)
{
@@ -758,34 +765,37 @@ build_module_tree (Module *decl)
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.
@@ -793,33 +803,33 @@ build_module_tree (Module *decl)
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. */

View File

@@ -1521,6 +1521,10 @@ layout_cpp_typeinfo (ClassDeclaration *cd)
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. */
@@ -1528,10 +1532,12 @@ layout_cpp_typeinfo (ClassDeclaration *cd)
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,
@@ -1541,18 +1547,18 @@ get_cpp_typeinfo_decl (ClassDeclaration *decl)
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. */

View File

@@ -1154,7 +1154,9 @@ public:
continue;
tree ident = get_identifier (member->ident->toChars ());
tree value = build_integer_cst (member->value ()->toInteger (),
Expression *evalue = member->value ();
tree value = build_integer_cst (evalue->toInteger (),
basetype);
/* Build an identifier for the enumeration constant. */