d: Merge upstream dmd, druntime e48bc0987d, phobos 2458e8f82.
[official-gcc.git] / gcc / d / modules.cc
blobe3c1ef9f82ece071e2bae22ec700b8f5eb38c880
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 tree moduleinfo_ptr_ptr_type =
281 build_pointer_type (build_pointer_type (get_moduleinfo_type ()));
283 field = create_field_decl (moduleinfo_ptr_ptr_type, NULL, 1, 1);
284 DECL_CHAIN (field) = fields;
285 fields = field;
286 field = create_field_decl (moduleinfo_ptr_ptr_type, NULL, 1, 1);
287 DECL_CHAIN (field) = fields;
288 fields = field;
290 field = create_field_decl (build_pointer_type (ptr_type_node), NULL, 1, 1);
291 DECL_CHAIN (field) = fields;
292 fields = field;
294 field = create_field_decl (size_type_node, NULL, 1, 1);
295 DECL_CHAIN (field) = fields;
296 fields = field;
298 compiler_dso_type = make_node (RECORD_TYPE);
299 finish_builtin_struct (compiler_dso_type, "CompilerDSOData",
300 fields, NULL_TREE);
302 return compiler_dso_type;
305 /* Returns the _d_dso_registry FUNCTION_DECL. */
307 static tree
308 get_dso_registry_fn (void)
310 if (dso_registry_fn)
311 return dso_registry_fn;
313 tree dso_type = get_compiler_dso_type ();
314 tree fntype = build_function_type_list (void_type_node,
315 build_pointer_type (dso_type),
316 NULL_TREE);
317 dso_registry_fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
318 get_identifier ("_d_dso_registry"), fntype);
319 TREE_PUBLIC (dso_registry_fn) = 1;
320 DECL_EXTERNAL (dso_registry_fn) = 1;
322 return dso_registry_fn;
325 /* Depending on CTOR_P, builds and emits eiter a constructor or destructor
326 calling _d_dso_registry if `dso_initialized' is `false' in a constructor
327 or `true' in a destructor. */
329 static tree
330 build_dso_cdtor_fn (bool ctor_p)
332 const char *name = ctor_p ? GDC_PREFIX ("dso_ctor") : GDC_PREFIX ("dso_dtor");
333 tree condition = ctor_p ? d_bool_true_node : d_bool_false_node;
335 /* Declaration of dso_ctor/dso_dtor is:
337 extern(C) void dso_{c,d}tor (void)
339 if (dso_initialized != condition)
341 dso_initialized = condition;
342 CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};
343 _d_dso_registry (&dso);
347 Visibility visibility;
348 visibility.kind = Visibility::public_;
349 FuncDeclaration *fd = get_internal_fn (get_identifier (name), visibility);
350 tree decl = get_symbol_decl (fd);
352 TREE_PUBLIC (decl) = 1;
353 DECL_ARTIFICIAL (decl) = 1;
354 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
355 DECL_VISIBILITY_SPECIFIED (decl) = 1;
357 /* Start laying out the body. */
358 tree old_context = start_function (fd);
359 rest_of_decl_compilation (decl, 1, 0);
361 /* if (dso_initialized != condition). */
362 tree if_cond = build_boolop (NE_EXPR, dso_initialized_node, condition);
364 /* dso_initialized = condition; */
365 tree expr_list = modify_expr (dso_initialized_node, condition);
367 /* CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo}; */
368 tree dso_type = get_compiler_dso_type ();
369 tree dso = build_local_temp (dso_type);
371 vec <constructor_elt, va_gc> *ve = NULL;
372 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_integer_cst (1, size_type_node));
373 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (dso_slot_node));
374 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (start_minfo_node));
375 CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (stop_minfo_node));
377 tree assign_expr = modify_expr (dso, build_struct_literal (dso_type, ve));
378 expr_list = compound_expr (expr_list, assign_expr);
380 /* _d_dso_registry (&dso); */
381 tree call_expr = build_call_expr (get_dso_registry_fn (), 1,
382 build_address (dso));
383 expr_list = compound_expr (expr_list, call_expr);
385 add_stmt (build_vcondition (if_cond, expr_list, void_node));
386 finish_function (old_context);
388 return decl;
391 /* Build a variable used in the dso_registry code identified by NAME,
392 and data type TYPE. The variable always has VISIBILITY_HIDDEN and
393 TREE_PUBLIC flags set. */
395 static tree
396 build_dso_registry_var (const char * name, tree type)
398 tree var = declare_extern_var (get_identifier (name), type);
399 DECL_VISIBILITY (var) = VISIBILITY_HIDDEN;
400 DECL_VISIBILITY_SPECIFIED (var) = 1;
401 return var;
404 /* Place a reference to the ModuleInfo symbol MINFO for DECL into the
405 `minfo' section. Then create the global ctors/dtors to call the
406 _d_dso_registry function if necessary. */
408 static void
409 register_moduleinfo (Module *decl, tree minfo)
411 /* No defined minfo section for target. */
412 if (targetdm.d_minfo_section == NULL)
413 return;
415 if (!targetm_common.have_named_sections)
416 sorry ("%<-fmoduleinfo%> is not supported on this target");
418 /* Build the ModuleInfo reference, this is done once for every Module. */
419 tree ident = mangle_internal_decl (decl, "__moduleRef", "Z");
420 tree mref = declare_extern_var (ident, ptr_type_node);
422 /* Build the initializer and emit. Do not start section with a `.' character
423 so that the linker will provide a __start_ and __stop_ symbol to indicate
424 the start and end address of the section respectively.
425 https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html. */
426 DECL_INITIAL (mref) = build_address (minfo);
427 DECL_EXTERNAL (mref) = 0;
428 DECL_PRESERVE_P (mref) = 1;
430 set_decl_section_name (mref, targetdm.d_minfo_section);
431 symtab_node::get (mref)->implicit_section = true;
432 d_pushdecl (mref);
433 rest_of_decl_compilation (mref, 1, 0);
435 /* Only for the first D module being emitted do we need to generate a static
436 constructor and destructor for. These are only required once per shared
437 library, so it's safe to emit them only once per object file. */
438 static bool first_module = true;
439 if (!first_module)
440 return;
442 start_minfo_node = build_dso_registry_var (targetdm.d_minfo_section_start,
443 ptr_type_node);
444 rest_of_decl_compilation (start_minfo_node, 1, 0);
446 stop_minfo_node = build_dso_registry_var (targetdm.d_minfo_section_end,
447 ptr_type_node);
448 rest_of_decl_compilation (stop_minfo_node, 1, 0);
450 /* Declare dso_slot and dso_initialized. */
451 dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"),
452 ptr_type_node);
453 d_finish_decl (dso_slot_node);
455 dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
456 d_bool_type);
457 d_finish_decl (dso_initialized_node);
459 /* Declare dso_ctor() and dso_dtor(). */
460 tree dso_ctor = build_dso_cdtor_fn (true);
461 DECL_STATIC_CONSTRUCTOR (dso_ctor) = 1;
462 decl_init_priority_insert (dso_ctor, DEFAULT_INIT_PRIORITY);
464 tree dso_dtor = build_dso_cdtor_fn (false);
465 DECL_STATIC_DESTRUCTOR (dso_dtor) = 1;
466 decl_fini_priority_insert (dso_dtor, DEFAULT_INIT_PRIORITY);
468 first_module = false;
471 /* Convenience function for layout_moduleinfo_fields. Adds a field of TYPE to
472 the moduleinfo record at OFFSET, incrementing the offset to the next field
473 position. No alignment is taken into account, all fields are packed. */
475 static void
476 layout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT &offset)
478 tree field = create_field_decl (type, NULL, 1, 1);
479 insert_aggregate_field (rec_type, field, offset);
480 offset += int_size_in_bytes (type);
483 /* Layout fields that immediately come after the moduleinfo TYPE for DECL.
484 Data relating to the module is packed into the type on an as-needed
485 basis, this is done to keep its size to a minimum. */
487 static tree
488 layout_moduleinfo_fields (Module *decl, tree type)
490 HOST_WIDE_INT offset = int_size_in_bytes (type);
491 type = copy_aggregate_type (type);
493 /* First fields added are all the function pointers. */
494 if (decl->sctor)
495 layout_moduleinfo_field (ptr_type_node, type, offset);
497 if (decl->sdtor)
498 layout_moduleinfo_field (ptr_type_node, type, offset);
500 if (decl->ssharedctor)
501 layout_moduleinfo_field (ptr_type_node, type, offset);
503 if (decl->sshareddtor)
504 layout_moduleinfo_field (ptr_type_node, type, offset);
506 if (decl->findGetMembers ())
507 layout_moduleinfo_field (ptr_type_node, type, offset);
509 if (decl->sictor)
510 layout_moduleinfo_field (ptr_type_node, type, offset);
512 if (decl->stest)
513 layout_moduleinfo_field (ptr_type_node, type, offset);
515 /* Array of module imports is laid out as a length field, followed by
516 a static array of ModuleInfo pointers. */
517 size_t aimports_dim = decl->aimports.length;
518 for (size_t i = 0; i < decl->aimports.length; i++)
520 Module *mi = decl->aimports[i];
521 if (!mi->needmoduleinfo)
522 aimports_dim--;
525 if (aimports_dim)
527 layout_moduleinfo_field (size_type_node, type, offset);
528 layout_moduleinfo_field (make_array_type (Type::tvoidptr, aimports_dim),
529 type, offset);
532 /* Array of local ClassInfo decls are laid out in the same way. */
533 ClassDeclarations aclasses;
534 getLocalClasses (decl, aclasses);
536 if (aclasses.length)
538 layout_moduleinfo_field (size_type_node, type, offset);
539 layout_moduleinfo_field (make_array_type (Type::tvoidptr,
540 aclasses.length),
541 type, offset);
544 /* Lastly, the name of the module is a static char array. */
545 size_t namelen = strlen (decl->toPrettyChars ()) + 1;
546 layout_moduleinfo_field (make_array_type (Type::tchar, namelen),
547 type, offset);
549 size_t alignsize = MAX (TYPE_ALIGN_UNIT (type),
550 TYPE_ALIGN_UNIT (ptr_type_node));
551 finish_aggregate_type (offset, alignsize, type);
553 return type;
556 /* Output the ModuleInfo for module DECL and register it with druntime. */
558 static void
559 layout_moduleinfo (Module *decl)
561 ClassDeclarations aclasses;
562 FuncDeclaration *sgetmembers;
564 getLocalClasses (decl, aclasses);
566 size_t aimports_dim = decl->aimports.length;
567 for (size_t i = 0; i < decl->aimports.length; i++)
569 Module *mi = decl->aimports[i];
570 if (!mi->needmoduleinfo)
571 aimports_dim--;
574 sgetmembers = decl->findGetMembers ();
576 size_t flags = 0;
577 if (decl->sctor)
578 flags |= MItlsctor;
579 if (decl->sdtor)
580 flags |= MItlsdtor;
581 if (decl->ssharedctor)
582 flags |= MIctor;
583 if (decl->sshareddtor)
584 flags |= MIdtor;
585 if (sgetmembers)
586 flags |= MIxgetMembers;
587 if (decl->sictor)
588 flags |= MIictor;
589 if (decl->stest)
590 flags |= MIunitTest;
591 if (aimports_dim)
592 flags |= MIimportedModules;
593 if (aclasses.length)
594 flags |= MIlocalClasses;
595 if (!decl->needmoduleinfo)
596 flags |= MIstandalone;
598 flags |= MIname;
600 tree minfo = get_moduleinfo_decl (decl);
601 tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo));
603 /* Put out the two named fields in a ModuleInfo decl:
604 uint flags;
605 uint index; */
606 vec <constructor_elt, va_gc> *minit = NULL;
608 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
609 build_integer_cst (flags, d_uint_type));
611 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
612 build_integer_cst (0, d_uint_type));
614 /* Order of appearance, depending on flags:
615 void function() tlsctor;
616 void function() tlsdtor;
617 void* function() xgetMembers;
618 void function() ctor;
619 void function() dtor;
620 void function() ictor;
621 void function() unitTest;
622 ModuleInfo*[] importedModules;
623 TypeInfo_Class[] localClasses;
624 char[N] name;
626 if (flags & MItlsctor)
627 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor));
629 if (flags & MItlsdtor)
630 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor));
632 if (flags & MIctor)
633 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
634 build_address (decl->ssharedctor));
636 if (flags & MIdtor)
637 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
638 build_address (decl->sshareddtor));
640 if (flags & MIxgetMembers)
641 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
642 build_address (get_symbol_decl (sgetmembers)));
644 if (flags & MIictor)
645 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor));
647 if (flags & MIunitTest)
648 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest));
650 if (flags & MIimportedModules)
652 vec <constructor_elt, va_gc> *elms = NULL;
653 tree satype = make_array_type (Type::tvoidptr, aimports_dim);
654 size_t idx = 0;
656 for (size_t i = 0; i < decl->aimports.length; i++)
658 Module *mi = decl->aimports[i];
659 if (mi->needmoduleinfo)
661 CONSTRUCTOR_APPEND_ELT (elms, size_int (idx),
662 build_address (get_moduleinfo_decl (mi)));
663 idx++;
667 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));
668 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
669 build_constructor (satype, elms));
672 if (flags & MIlocalClasses)
674 vec <constructor_elt, va_gc> *elms = NULL;
675 tree satype = make_array_type (Type::tvoidptr, aclasses.length);
677 for (size_t i = 0; i < aclasses.length; i++)
679 ClassDeclaration *cd = aclasses[i];
680 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
681 build_address (get_classinfo_decl (cd)));
684 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.length));
685 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
686 build_constructor (satype, elms));
689 if (flags & MIname)
691 /* Put out module name as a 0-terminated C-string, to save bytes. */
692 const char *name = decl->toPrettyChars ();
693 size_t namelen = strlen (name) + 1;
694 tree strtree = build_string (namelen, name);
695 TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen);
696 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree);
699 TREE_TYPE (minfo) = type;
700 DECL_INITIAL (minfo) = build_struct_literal (type, minit);
701 d_finish_decl (minfo);
703 /* Register the module against druntime. */
704 register_moduleinfo (decl, minfo);
707 /* Send the Module AST class DECL to GCC back-end. */
709 void
710 build_module_tree (Module *decl)
712 /* There may be more than one module per object file, but should only
713 ever compile them one at a time. */
714 assert (!current_moduleinfo && !current_module_decl);
716 module_info mi = module_info ();
717 module_info mitest = module_info ();
719 current_moduleinfo = &mi;
720 current_testing_module = &mitest;
721 current_module_decl = decl;
723 vec<Declaration *> deferred_decls = vNULL;
724 deferred_inline_declarations = &deferred_decls;
726 /* Layout module members. */
727 if (decl->members)
729 for (size_t i = 0; i < decl->members->length; i++)
731 Dsymbol *s = (*decl->members)[i];
732 build_decl_tree (s);
736 /* For libphobos-internal use only. Generate a separate module info symbol
737 that references all compiled in unittests, this allows compiling library
738 modules and linking to libphobos without having run-time conflicts because
739 of two ModuleInfo records with the same name being present in two DSOs. */
740 if (flag_building_libphobos_tests)
742 /* Associate the module info symbol with a mock module. */
743 const char *name = concat (GDC_PREFIX ("modtest__"),
744 decl->ident->toChars (), NULL);
745 Module *tm = Module::create (decl->arg.ptr, Identifier::idPool (name),
746 0, 0);
747 Dsymbols members;
749 /* Setting parent puts module in the same package as the current, to
750 avoid any symbol conflicts. */
751 tm->parent = decl->parent;
752 tm->needmoduleinfo = decl->needmoduleinfo;
753 tm->members = &members;
754 /* Register the current module as being imported by the mock module.
755 This informs run-time that there is a dependency between the two. */
756 tm->aimports.push (decl);
758 if (mitest.ctors || mitest.ctorgates)
759 tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"),
760 mitest.ctors, mitest.ctorgates);
762 if (mitest.dtors)
763 tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"),
764 mitest.dtors, NULL);
766 if (mitest.sharedctors || mitest.sharedctorgates)
767 tm->ssharedctor
768 = build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"),
769 mitest.sharedctors, mitest.sharedctorgates);
771 if (mitest.shareddtors)
772 tm->sshareddtor
773 = build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"),
774 mitest.shareddtors, NULL);
776 if (mi.unitTests)
777 tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
778 mi.unitTests, NULL);
780 mi.unitTests = NULL;
781 layout_moduleinfo (tm);
784 /* Default behavior is to always generate module info because of templates.
785 Can be switched off for not compiling against runtime library. */
786 if (global.params.useModuleInfo && Module::moduleinfo != NULL)
788 if (mi.ctors || mi.ctorgates)
789 decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"),
790 mi.ctors, mi.ctorgates);
792 if (mi.dtors)
793 decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"),
794 mi.dtors, NULL);
796 if (mi.sharedctors || mi.sharedctorgates)
797 decl->ssharedctor
798 = build_funcs_gates_fn (get_identifier ("*__modsharedctor"),
799 mi.sharedctors, mi.sharedctorgates);
801 if (mi.shareddtors)
802 decl->sshareddtor
803 = build_funcs_gates_fn (get_identifier ("*__modshareddtor"),
804 mi.shareddtors, NULL);
806 if (mi.unitTests)
807 decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
808 mi.unitTests, NULL);
810 layout_moduleinfo (decl);
813 /* Process all deferred functions after finishing module. */
814 for (size_t i = 0; i < deferred_decls.length (); ++i)
815 build_decl_tree (deferred_decls[i]);
817 current_moduleinfo = NULL;
818 current_testing_module = NULL;
819 current_module_decl = NULL;
820 deferred_inline_declarations = NULL;
823 /* Returns the current function or module context for the purpose
824 of imported_module_or_decl. */
826 tree
827 d_module_context (void)
829 if (cfun != NULL)
830 return current_function_decl;
832 gcc_assert (current_module_decl != NULL);
833 return build_import_decl (current_module_decl);
836 /* Maybe record declaration D against our module information structure. */
838 void
839 register_module_decl (Declaration *d)
841 FuncDeclaration *fd = d->isFuncDeclaration ();
842 if (fd != NULL)
844 tree decl = get_symbol_decl (fd);
846 /* Any module constructors or destructors that are only present when
847 compiling in unittests are kept track of separately so they are
848 not omitted when compiling with -fbuilding-libphobos-tests. */
849 module_info *minfo;
850 if (flag_building_libphobos_tests && !fd->isUnitTestDeclaration ()
851 && DECL_IN_UNITTEST_CONDITION_P (decl))
852 minfo = current_testing_module;
853 else
854 minfo = current_moduleinfo;
856 gcc_assert (minfo != NULL);
858 /* If a static constructor, push into the current ModuleInfo.
859 Checks for `shared' first because it derives from the non-shared
860 constructor type in the front-end. */
861 if (fd->isSharedStaticCtorDeclaration ())
862 vec_safe_push (minfo->sharedctors, decl);
863 else if (fd->isStaticCtorDeclaration ())
864 vec_safe_push (minfo->ctors, decl);
866 /* If a static destructor, do same as with constructors, but also
867 increment the destructor's vgate at construction time. */
868 if (fd->isSharedStaticDtorDeclaration ())
870 VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate;
871 if (vgate != NULL)
873 tree gate = get_symbol_decl (vgate);
874 vec_safe_push (minfo->sharedctorgates, gate);
876 vec_safe_insert (minfo->shareddtors, 0, decl);
878 else if (fd->isStaticDtorDeclaration ())
880 VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate;
881 if (vgate != NULL)
883 tree gate = get_symbol_decl (vgate);
884 vec_safe_push (minfo->ctorgates, gate);
886 vec_safe_insert (minfo->dtors, 0, decl);
889 /* If a unittest function. */
890 if (fd->isUnitTestDeclaration ())
891 vec_safe_push (minfo->unitTests, decl);
895 /* Add DECL as a declaration to emit at the end of the current module. */
897 void
898 d_defer_declaration (Declaration *decl)
900 gcc_assert (deferred_inline_declarations != NULL);
901 deferred_inline_declarations->safe_push (decl);
904 /* Wrapup all global declarations and start the final compilation. */
906 void
907 d_finish_compilation (tree *vec, int len)
909 /* Complete all generated thunks. */
910 symtab->process_same_body_aliases ();
912 /* Process all file scopes in this compilation, and the external_scope,
913 through wrapup_global_declarations. */
914 for (int i = 0; i < len; i++)
916 tree decl = vec[i];
917 wrapup_global_declarations (&decl, 1);