d: Merge upstream dmd, druntime 4ca4140e58, phobos 454dff14d.
[official-gcc.git] / gcc / d / modules.cc
blobf2180d30546ea5b0c975aa06815c3705a831b612
1 /* modules.cc -- D module initialization and termination.
2 Copyright (C) 2013-2023 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
22 #include "dmd/declaration.h"
23 #include "dmd/identifier.h"
24 #include "dmd/module.h"
26 #include "tree.h"
27 #include "diagnostic.h"
28 #include "fold-const.h"
29 #include "tm.h"
30 #include "function.h"
31 #include "cgraph.h"
32 #include "stor-layout.h"
33 #include "toplev.h"
34 #include "target.h"
35 #include "common/common-target.h"
36 #include "stringpool.h"
38 #include "d-tree.h"
39 #include "d-target.h"
42 /* D generates module information to inform the runtime library which modules
43 need some kind of special handling. All `static this()', `static ~this()',
44 and `unittest' functions for a given module are aggregated into a single
45 function - one for each kind - and a pointer to that function is inserted
46 into the ModuleInfo instance for that module.
48 Module information for a particular module is indicated with an ABI defined
49 structure derived from ModuleInfo. ModuleInfo is a variably sized struct
50 with two fixed base fields. The first field `flags' determines what
51 information is packed immediately after the record type.
53 Like TypeInfo, the runtime library provides the definitions of the ModuleInfo
54 structure, as well as accessors for the variadic fields. So we only define
55 layout compatible POD_structs for ModuleInfo. */
57 /* The internally represented ModuleInfo and CompilerDSO types. */
58 static tree moduleinfo_type;
59 static tree compiler_dso_type;
60 static tree dso_registry_fn;
62 /* The DSO slot for use by the druntime implementation. */
63 static tree dso_slot_node;
65 /* For registering and deregistering DSOs with druntime, we have one global
66 constructor and destructor per object that calls _d_dso_registry with the
67 respective DSO record. To ensure that this is only done once, a
68 `dso_initialized' variable is introduced to guard repeated calls. */
69 static tree dso_initialized_node;
71 /* The beginning and end of the `minfo' section. */
72 static tree start_minfo_node;
73 static tree stop_minfo_node;
75 /* Record information about module initialization, termination,
76 unit testing, and thread local storage in the compilation. */
78 struct module_info
80 vec <tree, va_gc> *ctors;
81 vec <tree, va_gc> *dtors;
82 vec <tree, va_gc> *ctorgates;
84 vec <tree, va_gc> *sharedctors;
85 vec <tree, va_gc> *shareddtors;
86 vec <tree, va_gc> *sharedctorgates;
88 vec <tree, va_gc> *unitTests;
91 /* These must match the values in libdruntime/object_.d. */
93 enum module_info_flags
95 MIctorstart = 0x1,
96 MIctordone = 0x2,
97 MIstandalone = 0x4,
98 MItlsctor = 0x8,
99 MItlsdtor = 0x10,
100 MIctor = 0x20,
101 MIdtor = 0x40,
102 MIxgetMembers = 0x80,
103 MIictor = 0x100,
104 MIunitTest = 0x200,
105 MIimportedModules = 0x400,
106 MIlocalClasses = 0x800,
107 MIname = 0x1000
110 /* The ModuleInfo information structure for the module currently being compiled.
111 Assuming that only ever process one at a time. */
113 static module_info *current_moduleinfo;
115 /* When compiling with -fbuilding-libphobos-tests, this contains information
116 about the module that gets compiled in only when unittests are enabled. */
118 static module_info *current_testing_module;
120 /* The declaration of the current module being compiled. */
122 static Module *current_module_decl;
124 /* Any inline symbols that were deferred during codegen. */
125 vec<Declaration *> *deferred_inline_declarations;
127 /* Returns an internal function identified by IDENT. This is used
128 by both module initialization and dso handlers. */
130 static FuncDeclaration *
131 get_internal_fn (tree ident, const Visibility &visibility)
133 Module *mod = current_module_decl;
134 const char *name = IDENTIFIER_POINTER (ident);
136 if (!mod)
137 mod = Module::rootModule;
139 if (name[0] == '*')
141 tree s = mangle_internal_decl (mod, name + 1, "FZv");
142 name = IDENTIFIER_POINTER (s);
145 FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid,
146 Identifier::idPool (name));
147 fd->isGenerated (true);
148 fd->loc = Loc (mod->srcfile.toChars (), 1, 0);
149 fd->parent = mod;
150 fd->visibility = visibility;
151 fd->semanticRun = PASS::semantic3done;
153 return fd;
156 /* Generate an internal function identified by IDENT.
157 The function body to add is in EXPR. */
159 static tree
160 build_internal_fn (tree ident, tree expr)
162 Visibility visibility;
163 visibility.kind = Visibility::private_;
164 FuncDeclaration *fd = get_internal_fn (ident, visibility);
165 tree decl = get_symbol_decl (fd);
167 tree old_context = start_function (fd);
168 rest_of_decl_compilation (decl, 1, 0);
169 add_stmt (expr);
170 finish_function (old_context);
172 /* D static ctors, static dtors, unittests, and the ModuleInfo
173 chain function are always private. */
174 TREE_PUBLIC (decl) = 0;
175 TREE_USED (decl) = 1;
176 DECL_ARTIFICIAL (decl) = 1;
178 return decl;
181 /* Build and emit a function identified by IDENT that increments (in order)
182 all variables in GATES, then calls the list of functions in FUNCTIONS. */
184 static tree
185 build_funcs_gates_fn (tree ident, vec <tree, va_gc> *functions,
186 vec <tree, va_gc> *gates)
188 tree expr_list = NULL_TREE;
190 /* Increment gates first. */
191 for (size_t i = 0; i < vec_safe_length (gates); i++)
193 tree decl = (*gates)[i];
194 tree value = build2 (PLUS_EXPR, TREE_TYPE (decl),
195 decl, integer_one_node);
196 tree var_expr = modify_expr (decl, value);
197 expr_list = compound_expr (expr_list, var_expr);
200 /* Call Functions. */
201 for (size_t i = 0; i < vec_safe_length (functions); i++)
203 tree decl = (*functions)[i];
204 tree call_expr = build_call_expr (decl, 0);
205 expr_list = compound_expr (expr_list, call_expr);
208 if (expr_list)
209 return build_internal_fn (ident, expr_list);
211 return NULL_TREE;
214 /* Return the type for ModuleInfo, create it if it doesn't already exist. */
216 static tree
217 get_moduleinfo_type (void)
219 if (moduleinfo_type)
220 return moduleinfo_type;
222 /* Layout of ModuleInfo is:
223 uint flags;
224 uint index; */
225 tree fields = create_field_decl (d_uint_type, NULL, 1, 1);
226 DECL_CHAIN (fields) = create_field_decl (d_uint_type, NULL, 1, 1);
228 moduleinfo_type = make_node (RECORD_TYPE);
229 finish_builtin_struct (moduleinfo_type, "ModuleInfo", fields, NULL_TREE);
231 return moduleinfo_type;
234 /* Get the VAR_DECL of the ModuleInfo for DECL. If this does not yet exist,
235 create it. The ModuleInfo decl is used to keep track of constructors,
236 destructors, unittests, members, classes, and imports for the given module.
237 This is used by the D runtime for module initialization and termination. */
239 static tree
240 get_moduleinfo_decl (Module *decl)
242 if (decl->csym)
243 return decl->csym;
245 tree ident = mangle_internal_decl (decl, "__ModuleInfo", "Z");
246 tree type = get_moduleinfo_type ();
248 decl->csym = declare_extern_var (ident, type);
249 DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);
251 DECL_CONTEXT (decl->csym) = build_import_decl (decl);
252 /* Not readonly, moduleinit depends on this. */
253 TREE_READONLY (decl->csym) = 0;
255 return decl->csym;
258 /* Return the type for CompilerDSOData, create it if it doesn't exist. */
260 static tree
261 get_compiler_dso_type (void)
263 if (compiler_dso_type)
264 return compiler_dso_type;
266 /* Layout of CompilerDSOData is:
267 size_t version;
268 void** slot;
269 ModuleInfo** _minfo_beg;
270 ModuleInfo** _minfo_end;
271 FuncTable* _deh_beg;
272 FuncTable* _deh_end;
274 Note, finish_builtin_struct() expects these fields in reverse order. */
275 tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);
276 tree field = create_field_decl (ptr_type_node, NULL, 1, 1);
277 DECL_CHAIN (field) = fields;
278 fields = field;
280 field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),
281 NULL, 1, 1);
282 DECL_CHAIN (field) = fields;
283 fields = field;
284 field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),
285 NULL, 1, 1);
286 DECL_CHAIN (field) = fields;
287 fields = field;
289 field = create_field_decl (build_pointer_type (ptr_type_node), NULL, 1, 1);
290 DECL_CHAIN (field) = fields;
291 fields = field;
293 field = create_field_decl (size_type_node, NULL, 1, 1);
294 DECL_CHAIN (field) = fields;
295 fields = field;
297 compiler_dso_type = make_node (RECORD_TYPE);
298 finish_builtin_struct (compiler_dso_type, "CompilerDSOData",
299 fields, NULL_TREE);
301 return compiler_dso_type;
304 /* Returns the _d_dso_registry FUNCTION_DECL. */
306 static tree
307 get_dso_registry_fn (void)
309 if (dso_registry_fn)
310 return dso_registry_fn;
312 tree dso_type = get_compiler_dso_type ();
313 tree fntype = build_function_type_list (void_type_node,
314 build_pointer_type (dso_type),
315 NULL_TREE);
316 dso_registry_fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
317 get_identifier ("_d_dso_registry"), fntype);
318 TREE_PUBLIC (dso_registry_fn) = 1;
319 DECL_EXTERNAL (dso_registry_fn) = 1;
321 return dso_registry_fn;
324 /* Depending on CTOR_P, builds and emits eiter a constructor or destructor
325 calling _d_dso_registry if `dso_initialized' is `false' in a constructor
326 or `true' in a destructor. */
328 static tree
329 build_dso_cdtor_fn (bool ctor_p)
331 const char *name = ctor_p ? GDC_PREFIX ("dso_ctor") : GDC_PREFIX ("dso_dtor");
332 tree condition = ctor_p ? boolean_true_node : boolean_false_node;
334 /* Declaration of dso_ctor/dso_dtor is:
336 extern(C) void dso_{c,d}tor (void)
338 if (dso_initialized != condition)
340 dso_initialized = condition;
341 CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};
342 _d_dso_registry (&dso);
346 Visibility visibility;
347 visibility.kind = Visibility::public_;
348 FuncDeclaration *fd = get_internal_fn (get_identifier (name), visibility);
349 tree decl = get_symbol_decl (fd);
351 TREE_PUBLIC (decl) = 1;
352 DECL_ARTIFICIAL (decl) = 1;
353 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
354 DECL_VISIBILITY_SPECIFIED (decl) = 1;
356 /* Start laying out the body. */
357 tree old_context = start_function (fd);
358 rest_of_decl_compilation (decl, 1, 0);
360 /* if (dso_initialized != condition). */
361 tree if_cond = build_boolop (NE_EXPR, dso_initialized_node, condition);
363 /* dso_initialized = condition; */
364 tree expr_list = modify_expr (dso_initialized_node, condition);
366 /* CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo}; */
367 tree dso_type = get_compiler_dso_type ();
368 tree dso = build_local_temp (dso_type);
370 vec <constructor_elt, va_gc> *ve = NULL;
371 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_integer_cst (1, size_type_node));
372 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (dso_slot_node));
373 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (start_minfo_node));
374 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (stop_minfo_node));
376 tree assign_expr = modify_expr (dso, build_struct_literal (dso_type, ve));
377 expr_list = compound_expr (expr_list, assign_expr);
379 /* _d_dso_registry (&dso); */
380 tree call_expr = build_call_expr (get_dso_registry_fn (), 1,
381 build_address (dso));
382 expr_list = compound_expr (expr_list, call_expr);
384 add_stmt (build_vcondition (if_cond, expr_list, void_node));
385 finish_function (old_context);
387 return decl;
390 /* Build a variable used in the dso_registry code identified by NAME,
391 and data type TYPE. The variable always has VISIBILITY_HIDDEN and
392 TREE_PUBLIC flags set. */
394 static tree
395 build_dso_registry_var (const char * name, tree type)
397 tree var = declare_extern_var (get_identifier (name), type);
398 DECL_VISIBILITY (var) = VISIBILITY_HIDDEN;
399 DECL_VISIBILITY_SPECIFIED (var) = 1;
400 return var;
403 /* Place a reference to the ModuleInfo symbol MINFO for DECL into the
404 `minfo' section. Then create the global ctors/dtors to call the
405 _d_dso_registry function if necessary. */
407 static void
408 register_moduleinfo (Module *decl, tree minfo)
410 /* No defined minfo section for target. */
411 if (targetdm.d_minfo_section == NULL)
412 return;
414 if (!targetm_common.have_named_sections)
415 sorry ("%<-fmoduleinfo%> is not supported on this target");
417 /* Build the ModuleInfo reference, this is done once for every Module. */
418 tree ident = mangle_internal_decl (decl, "__moduleRef", "Z");
419 tree mref = declare_extern_var (ident, ptr_type_node);
421 /* Build the initializer and emit. Do not start section with a `.' character
422 so that the linker will provide a __start_ and __stop_ symbol to indicate
423 the start and end address of the section respectively.
424 https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html. */
425 DECL_INITIAL (mref) = build_address (minfo);
426 DECL_EXTERNAL (mref) = 0;
427 DECL_PRESERVE_P (mref) = 1;
429 set_decl_section_name (mref, targetdm.d_minfo_section);
430 symtab_node::get (mref)->implicit_section = true;
431 d_pushdecl (mref);
432 rest_of_decl_compilation (mref, 1, 0);
434 /* Only for the first D module being emitted do we need to generate a static
435 constructor and destructor for. These are only required once per shared
436 library, so it's safe to emit them only once per object file. */
437 static bool first_module = true;
438 if (!first_module)
439 return;
441 start_minfo_node = build_dso_registry_var (targetdm.d_minfo_section_start,
442 ptr_type_node);
443 rest_of_decl_compilation (start_minfo_node, 1, 0);
445 stop_minfo_node = build_dso_registry_var (targetdm.d_minfo_section_end,
446 ptr_type_node);
447 rest_of_decl_compilation (stop_minfo_node, 1, 0);
449 /* Declare dso_slot and dso_initialized. */
450 dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"),
451 ptr_type_node);
452 d_finish_decl (dso_slot_node);
454 dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
455 boolean_type_node);
456 d_finish_decl (dso_initialized_node);
458 /* Declare dso_ctor() and dso_dtor(). */
459 tree dso_ctor = build_dso_cdtor_fn (true);
460 DECL_STATIC_CONSTRUCTOR (dso_ctor) = 1;
461 decl_init_priority_insert (dso_ctor, DEFAULT_INIT_PRIORITY);
463 tree dso_dtor = build_dso_cdtor_fn (false);
464 DECL_STATIC_DESTRUCTOR (dso_dtor) = 1;
465 decl_fini_priority_insert (dso_dtor, DEFAULT_INIT_PRIORITY);
467 first_module = false;
470 /* Convenience function for layout_moduleinfo_fields. Adds a field of TYPE to
471 the moduleinfo record at OFFSET, incrementing the offset to the next field
472 position. No alignment is taken into account, all fields are packed. */
474 static void
475 layout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT &offset)
477 tree field = create_field_decl (type, NULL, 1, 1);
478 insert_aggregate_field (rec_type, field, offset);
479 offset += int_size_in_bytes (type);
482 /* Layout fields that immediately come after the moduleinfo TYPE for DECL.
483 Data relating to the module is packed into the type on an as-needed
484 basis, this is done to keep its size to a minimum. */
486 static tree
487 layout_moduleinfo_fields (Module *decl, tree type)
489 HOST_WIDE_INT offset = int_size_in_bytes (type);
490 type = copy_aggregate_type (type);
492 /* First fields added are all the function pointers. */
493 if (decl->sctor)
494 layout_moduleinfo_field (ptr_type_node, type, offset);
496 if (decl->sdtor)
497 layout_moduleinfo_field (ptr_type_node, type, offset);
499 if (decl->ssharedctor)
500 layout_moduleinfo_field (ptr_type_node, type, offset);
502 if (decl->sshareddtor)
503 layout_moduleinfo_field (ptr_type_node, type, offset);
505 if (decl->findGetMembers ())
506 layout_moduleinfo_field (ptr_type_node, type, offset);
508 if (decl->sictor)
509 layout_moduleinfo_field (ptr_type_node, type, offset);
511 if (decl->stest)
512 layout_moduleinfo_field (ptr_type_node, type, offset);
514 /* Array of module imports is laid out as a length field, followed by
515 a static array of ModuleInfo pointers. */
516 size_t aimports_dim = decl->aimports.length;
517 for (size_t i = 0; i < decl->aimports.length; i++)
519 Module *mi = decl->aimports[i];
520 if (!mi->needmoduleinfo)
521 aimports_dim--;
524 if (aimports_dim)
526 layout_moduleinfo_field (size_type_node, type, offset);
527 layout_moduleinfo_field (make_array_type (Type::tvoidptr, aimports_dim),
528 type, offset);
531 /* Array of local ClassInfo decls are laid out in the same way. */
532 ClassDeclarations aclasses;
533 getLocalClasses (decl, aclasses);
535 if (aclasses.length)
537 layout_moduleinfo_field (size_type_node, type, offset);
538 layout_moduleinfo_field (make_array_type (Type::tvoidptr,
539 aclasses.length),
540 type, offset);
543 /* Lastly, the name of the module is a static char array. */
544 size_t namelen = strlen (decl->toPrettyChars ()) + 1;
545 layout_moduleinfo_field (make_array_type (Type::tchar, namelen),
546 type, offset);
548 size_t alignsize = MAX (TYPE_ALIGN_UNIT (type),
549 TYPE_ALIGN_UNIT (ptr_type_node));
550 finish_aggregate_type (offset, alignsize, type);
552 return type;
555 /* Output the ModuleInfo for module DECL and register it with druntime. */
557 static void
558 layout_moduleinfo (Module *decl)
560 ClassDeclarations aclasses;
561 FuncDeclaration *sgetmembers;
563 getLocalClasses (decl, aclasses);
565 size_t aimports_dim = decl->aimports.length;
566 for (size_t i = 0; i < decl->aimports.length; i++)
568 Module *mi = decl->aimports[i];
569 if (!mi->needmoduleinfo)
570 aimports_dim--;
573 sgetmembers = decl->findGetMembers ();
575 size_t flags = 0;
576 if (decl->sctor)
577 flags |= MItlsctor;
578 if (decl->sdtor)
579 flags |= MItlsdtor;
580 if (decl->ssharedctor)
581 flags |= MIctor;
582 if (decl->sshareddtor)
583 flags |= MIdtor;
584 if (sgetmembers)
585 flags |= MIxgetMembers;
586 if (decl->sictor)
587 flags |= MIictor;
588 if (decl->stest)
589 flags |= MIunitTest;
590 if (aimports_dim)
591 flags |= MIimportedModules;
592 if (aclasses.length)
593 flags |= MIlocalClasses;
594 if (!decl->needmoduleinfo)
595 flags |= MIstandalone;
597 flags |= MIname;
599 tree minfo = get_moduleinfo_decl (decl);
600 tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo));
602 /* Put out the two named fields in a ModuleInfo decl:
603 uint flags;
604 uint index; */
605 vec <constructor_elt, va_gc> *minit = NULL;
607 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
608 build_integer_cst (flags, d_uint_type));
610 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
611 build_integer_cst (0, d_uint_type));
613 /* Order of appearance, depending on flags:
614 void function() tlsctor;
615 void function() tlsdtor;
616 void* function() xgetMembers;
617 void function() ctor;
618 void function() dtor;
619 void function() ictor;
620 void function() unitTest;
621 ModuleInfo*[] importedModules;
622 TypeInfo_Class[] localClasses;
623 char[N] name;
625 if (flags & MItlsctor)
626 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor));
628 if (flags & MItlsdtor)
629 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor));
631 if (flags & MIctor)
632 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
633 build_address (decl->ssharedctor));
635 if (flags & MIdtor)
636 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
637 build_address (decl->sshareddtor));
639 if (flags & MIxgetMembers)
640 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
641 build_address (get_symbol_decl (sgetmembers)));
643 if (flags & MIictor)
644 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor));
646 if (flags & MIunitTest)
647 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest));
649 if (flags & MIimportedModules)
651 vec <constructor_elt, va_gc> *elms = NULL;
652 tree satype = make_array_type (Type::tvoidptr, aimports_dim);
653 size_t idx = 0;
655 for (size_t i = 0; i < decl->aimports.length; i++)
657 Module *mi = decl->aimports[i];
658 if (mi->needmoduleinfo)
660 CONSTRUCTOR_APPEND_ELT (elms, size_int (idx),
661 build_address (get_moduleinfo_decl (mi)));
662 idx++;
666 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));
667 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
668 build_constructor (satype, elms));
671 if (flags & MIlocalClasses)
673 vec <constructor_elt, va_gc> *elms = NULL;
674 tree satype = make_array_type (Type::tvoidptr, aclasses.length);
676 for (size_t i = 0; i < aclasses.length; i++)
678 ClassDeclaration *cd = aclasses[i];
679 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
680 build_address (get_classinfo_decl (cd)));
683 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.length));
684 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
685 build_constructor (satype, elms));
688 if (flags & MIname)
690 /* Put out module name as a 0-terminated C-string, to save bytes. */
691 const char *name = decl->toPrettyChars ();
692 size_t namelen = strlen (name) + 1;
693 tree strtree = build_string (namelen, name);
694 TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen);
695 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree);
698 TREE_TYPE (minfo) = type;
699 DECL_INITIAL (minfo) = build_struct_literal (type, minit);
700 d_finish_decl (minfo);
702 /* Register the module against druntime. */
703 register_moduleinfo (decl, minfo);
706 /* Send the Module AST class DECL to GCC back-end. */
708 void
709 build_module_tree (Module *decl)
711 /* There may be more than one module per object file, but should only
712 ever compile them one at a time. */
713 assert (!current_moduleinfo && !current_module_decl);
715 module_info mi = module_info ();
716 module_info mitest = module_info ();
718 current_moduleinfo = &mi;
719 current_testing_module = &mitest;
720 current_module_decl = decl;
722 vec<Declaration *> deferred_decls = vNULL;
723 deferred_inline_declarations = &deferred_decls;
725 /* Layout module members. */
726 if (decl->members)
728 for (size_t i = 0; i < decl->members->length; i++)
730 Dsymbol *s = (*decl->members)[i];
731 build_decl_tree (s);
735 /* For libphobos-internal use only. Generate a separate module info symbol
736 that references all compiled in unittests, this allows compiling library
737 modules and linking to libphobos without having run-time conflicts because
738 of two ModuleInfo records with the same name being present in two DSOs. */
739 if (flag_building_libphobos_tests)
741 /* Associate the module info symbol with a mock module. */
742 const char *name = concat (GDC_PREFIX ("modtest__"),
743 decl->ident->toChars (), NULL);
744 Module *tm = Module::create (decl->arg.ptr, Identifier::idPool (name),
745 0, 0);
746 Dsymbols members;
748 /* Setting parent puts module in the same package as the current, to
749 avoid any symbol conflicts. */
750 tm->parent = decl->parent;
751 tm->needmoduleinfo = decl->needmoduleinfo;
752 tm->members = &members;
753 /* Register the current module as being imported by the mock module.
754 This informs run-time that there is a dependency between the two. */
755 tm->aimports.push (decl);
757 if (mitest.ctors || mitest.ctorgates)
758 tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"),
759 mitest.ctors, mitest.ctorgates);
761 if (mitest.dtors)
762 tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"),
763 mitest.dtors, NULL);
765 if (mitest.sharedctors || mitest.sharedctorgates)
766 tm->ssharedctor
767 = build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"),
768 mitest.sharedctors, mitest.sharedctorgates);
770 if (mitest.shareddtors)
771 tm->sshareddtor
772 = build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"),
773 mitest.shareddtors, NULL);
775 if (mi.unitTests)
776 tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
777 mi.unitTests, NULL);
779 mi.unitTests = NULL;
780 layout_moduleinfo (tm);
783 /* Default behavior is to always generate module info because of templates.
784 Can be switched off for not compiling against runtime library. */
785 if (global.params.useModuleInfo && Module::moduleinfo != NULL)
787 if (mi.ctors || mi.ctorgates)
788 decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"),
789 mi.ctors, mi.ctorgates);
791 if (mi.dtors)
792 decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"),
793 mi.dtors, NULL);
795 if (mi.sharedctors || mi.sharedctorgates)
796 decl->ssharedctor
797 = build_funcs_gates_fn (get_identifier ("*__modsharedctor"),
798 mi.sharedctors, mi.sharedctorgates);
800 if (mi.shareddtors)
801 decl->sshareddtor
802 = build_funcs_gates_fn (get_identifier ("*__modshareddtor"),
803 mi.shareddtors, NULL);
805 if (mi.unitTests)
806 decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
807 mi.unitTests, NULL);
809 layout_moduleinfo (decl);
812 /* Process all deferred functions after finishing module. */
813 for (size_t i = 0; i < deferred_decls.length (); ++i)
814 build_decl_tree (deferred_decls[i]);
816 current_moduleinfo = NULL;
817 current_testing_module = NULL;
818 current_module_decl = NULL;
819 deferred_inline_declarations = NULL;
822 /* Returns the current function or module context for the purpose
823 of imported_module_or_decl. */
825 tree
826 d_module_context (void)
828 if (cfun != NULL)
829 return current_function_decl;
831 gcc_assert (current_module_decl != NULL);
832 return build_import_decl (current_module_decl);
835 /* Maybe record declaration D against our module information structure. */
837 void
838 register_module_decl (Declaration *d)
840 FuncDeclaration *fd = d->isFuncDeclaration ();
841 if (fd != NULL)
843 tree decl = get_symbol_decl (fd);
845 /* Any module constructors or destructors that are only present when
846 compiling in unittests are kept track of separately so they are
847 not omitted when compiling with -fbuilding-libphobos-tests. */
848 module_info *minfo;
849 if (flag_building_libphobos_tests && !fd->isUnitTestDeclaration ()
850 && DECL_IN_UNITTEST_CONDITION_P (decl))
851 minfo = current_testing_module;
852 else
853 minfo = current_moduleinfo;
855 gcc_assert (minfo != NULL);
857 /* If a static constructor, push into the current ModuleInfo.
858 Checks for `shared' first because it derives from the non-shared
859 constructor type in the front-end. */
860 if (fd->isSharedStaticCtorDeclaration ())
861 vec_safe_push (minfo->sharedctors, decl);
862 else if (fd->isStaticCtorDeclaration ())
863 vec_safe_push (minfo->ctors, decl);
865 /* If a static destructor, do same as with constructors, but also
866 increment the destructor's vgate at construction time. */
867 if (fd->isSharedStaticDtorDeclaration ())
869 VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate;
870 if (vgate != NULL)
872 tree gate = get_symbol_decl (vgate);
873 vec_safe_push (minfo->sharedctorgates, gate);
875 vec_safe_insert (minfo->shareddtors, 0, decl);
877 else if (fd->isStaticDtorDeclaration ())
879 VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate;
880 if (vgate != NULL)
882 tree gate = get_symbol_decl (vgate);
883 vec_safe_push (minfo->ctorgates, gate);
885 vec_safe_insert (minfo->dtors, 0, decl);
888 /* If a unittest function. */
889 if (fd->isUnitTestDeclaration ())
890 vec_safe_push (minfo->unitTests, decl);
894 /* Add DECL as a declaration to emit at the end of the current module. */
896 void
897 d_defer_declaration (Declaration *decl)
899 gcc_assert (deferred_inline_declarations != NULL);
900 deferred_inline_declarations->safe_push (decl);
903 /* Wrapup all global declarations and start the final compilation. */
905 void
906 d_finish_compilation (tree *vec, int len)
908 /* Complete all generated thunks. */
909 symtab->process_same_body_aliases ();
911 /* Process all file scopes in this compilation, and the external_scope,
912 through wrapup_global_declarations. */
913 for (int i = 0; i < len; i++)
915 tree decl = vec[i];
916 wrapup_global_declarations (&decl, 1);