xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/d/modules.cc (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* modules.cc -- D module initialization and termination.
2    Copyright (C) 2013-2019 Free Software Foundation, Inc.
3 
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.
8 
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.
13 
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/>.  */
17 
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21 
22 #include "dmd/declaration.h"
23 #include "dmd/identifier.h"
24 #include "dmd/module.h"
25 
26 #include "tree.h"
27 #include "fold-const.h"
28 #include "tm.h"
29 #include "function.h"
30 #include "cgraph.h"
31 #include "stor-layout.h"
32 #include "toplev.h"
33 #include "target.h"
34 #include "common/common-target.h"
35 #include "stringpool.h"
36 
37 #include "d-tree.h"
38 
39 
40 /* D generates module information to inform the runtime library which modules
41    need some kind of special handling.  All `static this()', `static ~this()',
42    and `unittest' functions for a given module are aggregated into a single
43    function - one for each kind - and a pointer to that function is inserted
44    into the ModuleInfo instance for that module.
45 
46    Module information for a particular module is indicated with an ABI defined
47    structure derived from ModuleInfo.  ModuleInfo is a variably sized struct
48    with two fixed base fields.  The first field `flags' determines what
49    information is packed immediately after the record type.
50 
51    Like TypeInfo, the runtime library provides the definitions of the ModuleInfo
52    structure, as well as accessors for the variadic fields.  So we only define
53    layout compatible POD_structs for ModuleInfo.  */
54 
55 /* The internally represented ModuleInfo and CompilerDSO types.  */
56 static tree moduleinfo_type;
57 static tree compiler_dso_type;
58 static tree dso_registry_fn;
59 
60 /* The DSO slot for use by the druntime implementation.  */
61 static tree dso_slot_node;
62 
63 /* For registering and deregistering DSOs with druntime, we have one global
64    constructor and destructor per object that calls _d_dso_registry with the
65    respective DSO record.  To ensure that this is only done once, a
66    `dso_initialized' variable is introduced to guard repeated calls.  */
67 static tree dso_initialized_node;
68 
69 /* The beginning and end of the `minfo' section.  */
70 static tree start_minfo_node;
71 static tree stop_minfo_node;
72 
73 /* Record information about module initialization, termination,
74    unit testing, and thread local storage in the compilation.  */
75 
76 struct GTY(()) module_info
77 {
78   vec<tree, va_gc> *ctors;
79   vec<tree, va_gc> *dtors;
80   vec<tree, va_gc> *ctorgates;
81 
82   vec<tree, va_gc> *sharedctors;
83   vec<tree, va_gc> *shareddtors;
84   vec<tree, va_gc> *sharedctorgates;
85 
86   vec<tree, va_gc> *unitTests;
87 };
88 
89 /* These must match the values in libdruntime/object_.d.  */
90 
91 enum module_info_flags
92 {
93   MIctorstart	    = 0x1,
94   MIctordone	    = 0x2,
95   MIstandalone	    = 0x4,
96   MItlsctor	    = 0x8,
97   MItlsdtor	    = 0x10,
98   MIctor	    = 0x20,
99   MIdtor	    = 0x40,
100   MIxgetMembers	    = 0x80,
101   MIictor	    = 0x100,
102   MIunitTest	    = 0x200,
103   MIimportedModules = 0x400,
104   MIlocalClasses    = 0x800,
105   MIname	    = 0x1000
106 };
107 
108 /* The ModuleInfo information structure for the module currently being compiled.
109    Assuming that only ever process one at a time.  */
110 
111 static module_info *current_moduleinfo;
112 
113 /* When compiling with -fbuilding-libphobos-tests, this contains information
114    about the module that gets compiled in only when unittests are enabled.  */
115 
116 static module_info *current_testing_module;
117 
118 /* The declaration of the current module being compiled.  */
119 
120 static Module *current_module_decl;
121 
122 /* Static constructors and destructors (not D `static this').  */
123 
124 static GTY(()) vec<tree, va_gc> *static_ctor_list;
125 static GTY(()) vec<tree, va_gc> *static_dtor_list;
126 
127 /* Returns an internal function identified by IDENT.  This is used
128    by both module initialization and dso handlers.  */
129 
130 static FuncDeclaration *
131 get_internal_fn (tree ident)
132 {
133   Module *mod = current_module_decl;
134   const char *name = IDENTIFIER_POINTER (ident);
135 
136   if (!mod)
137     mod = Module::rootModule;
138 
139   if (name[0] == '*')
140     {
141       tree s = mangle_internal_decl (mod, name + 1, "FZv");
142       name = IDENTIFIER_POINTER (s);
143     }
144 
145   FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid,
146 						   Identifier::idPool (name));
147   fd->loc = Loc (mod->srcfile->toChars (), 1, 0);
148   fd->parent = mod;
149   fd->protection.kind = PROTprivate;
150   fd->semanticRun = PASSsemantic3done;
151 
152   return fd;
153 }
154 
155 /* Generate an internal function identified by IDENT.
156    The function body to add is in EXPR.  */
157 
158 static tree
159 build_internal_fn (tree ident, tree expr)
160 {
161   FuncDeclaration *fd = get_internal_fn (ident);
162   tree decl = get_symbol_decl (fd);
163 
164   tree old_context = start_function (fd);
165   rest_of_decl_compilation (decl, 1, 0);
166   add_stmt (expr);
167   finish_function (old_context);
168 
169   /* D static ctors, static dtors, unittests, and the ModuleInfo
170      chain function are always private.  */
171   TREE_PUBLIC (decl) = 0;
172   TREE_USED (decl) = 1;
173   DECL_ARTIFICIAL (decl) = 1;
174 
175   return decl;
176 }
177 
178 /* Build and emit a function identified by IDENT that increments (in order)
179    all variables in GATES, then calls the list of functions in FUNCTIONS.  */
180 
181 static tree
182 build_funcs_gates_fn (tree ident, vec<tree, va_gc> *functions,
183 		      vec<tree, va_gc> *gates)
184 {
185   tree expr_list = NULL_TREE;
186 
187   /* Increment gates first.  */
188   for (size_t i = 0; i < vec_safe_length (gates); i++)
189     {
190       tree decl = (*gates)[i];
191       tree value = build2 (PLUS_EXPR, TREE_TYPE (decl),
192 			   decl, integer_one_node);
193       tree var_expr = modify_expr (decl, value);
194       expr_list = compound_expr (expr_list, var_expr);
195     }
196 
197   /* Call Functions.  */
198   for (size_t i = 0; i < vec_safe_length (functions); i++)
199     {
200       tree decl = (*functions)[i];
201       tree call_expr = build_call_expr (decl, 0);
202       expr_list = compound_expr (expr_list, call_expr);
203     }
204 
205   if (expr_list)
206     return build_internal_fn (ident, expr_list);
207 
208   return NULL_TREE;
209 }
210 
211 /* Return the type for ModuleInfo, create it if it doesn't already exist.  */
212 
213 static tree
214 get_moduleinfo_type (void)
215 {
216   if (moduleinfo_type)
217     return moduleinfo_type;
218 
219   /* Layout of ModuleInfo is:
220 	uint flags;
221 	uint index;  */
222   tree fields = create_field_decl (d_uint_type, NULL, 1, 1);
223   DECL_CHAIN (fields) = create_field_decl (d_uint_type, NULL, 1, 1);
224 
225   moduleinfo_type = make_node (RECORD_TYPE);
226   finish_builtin_struct (moduleinfo_type, "ModuleInfo", fields, NULL_TREE);
227 
228   return moduleinfo_type;
229 }
230 
231 /* Get the VAR_DECL of the ModuleInfo for DECL.  If this does not yet exist,
232    create it.  The ModuleInfo decl is used to keep track of constructors,
233    destructors, unittests, members, classes, and imports for the given module.
234    This is used by the D runtime for module initialization and termination.  */
235 
236 static tree
237 get_moduleinfo_decl (Module *decl)
238 {
239   if (decl->csym)
240     return decl->csym;
241 
242   tree ident = mangle_internal_decl (decl, "__ModuleInfo", "Z");
243   tree type = get_moduleinfo_type ();
244 
245   decl->csym = declare_extern_var (ident, type);
246   DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);
247 
248   DECL_CONTEXT (decl->csym) = build_import_decl (decl);
249   /* Not readonly, moduleinit depends on this.  */
250   TREE_READONLY (decl->csym) = 0;
251 
252   return decl->csym;
253 }
254 
255 /* Return the type for CompilerDSOData, create it if it doesn't exist.  */
256 
257 static tree
258 get_compiler_dso_type (void)
259 {
260   if (compiler_dso_type)
261     return compiler_dso_type;
262 
263   /* Layout of CompilerDSOData is:
264 	size_t version;
265 	void** slot;
266 	ModuleInfo** _minfo_beg;
267 	ModuleInfo** _minfo_end;
268 	FuncTable* _deh_beg;
269 	FuncTable* _deh_end;
270 
271      Note, finish_builtin_struct() expects these fields in reverse order.  */
272   tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);
273   tree field = create_field_decl (ptr_type_node, NULL, 1, 1);
274   DECL_CHAIN (field) = fields;
275   fields = field;
276 
277   field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),
278 			     NULL, 1, 1);
279   DECL_CHAIN (field) = fields;
280   fields = field;
281   field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),
282 			     NULL, 1, 1);
283   DECL_CHAIN (field) = fields;
284   fields = field;
285 
286   field = create_field_decl (build_pointer_type (ptr_type_node), NULL, 1, 1);
287   DECL_CHAIN (field) = fields;
288   fields = field;
289 
290   field = create_field_decl (size_type_node, NULL, 1, 1);
291   DECL_CHAIN (field) = fields;
292   fields = field;
293 
294   compiler_dso_type = make_node (RECORD_TYPE);
295   finish_builtin_struct (compiler_dso_type, "CompilerDSOData",
296 			 fields, NULL_TREE);
297 
298   return compiler_dso_type;
299 }
300 
301 /* Returns the _d_dso_registry FUNCTION_DECL.  */
302 
303 static tree
304 get_dso_registry_fn (void)
305 {
306   if (dso_registry_fn)
307     return dso_registry_fn;
308 
309   tree dso_type = get_compiler_dso_type ();
310   tree fntype = build_function_type_list (void_type_node,
311 					  build_pointer_type (dso_type),
312 					  NULL_TREE);
313   dso_registry_fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
314 				get_identifier ("_d_dso_registry"), fntype);
315   TREE_PUBLIC (dso_registry_fn) = 1;
316   DECL_EXTERNAL (dso_registry_fn) = 1;
317 
318   return dso_registry_fn;
319 }
320 
321 /* Depending on CTOR_P, builds and emits eiter a constructor or destructor
322    calling _d_dso_registry if `dso_initialized' is `false' in a constructor
323    or `true' in a destructor.  */
324 
325 static tree
326 build_dso_cdtor_fn (bool ctor_p)
327 {
328   const char *name = ctor_p ? GDC_PREFIX ("dso_ctor") : GDC_PREFIX ("dso_dtor");
329   tree condition = ctor_p ? boolean_true_node : boolean_false_node;
330 
331   /* Declaration of dso_ctor/dso_dtor is:
332 
333      extern(C) void dso_{c,d}tor (void)
334      {
335 	if (dso_initialized != condition)
336 	{
337 	    dso_initialized = condition;
338 	    CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};
339 	    _d_dso_registry (&dso);
340 	}
341     }
342    */
343   FuncDeclaration *fd = get_internal_fn (get_identifier (name));
344   tree decl = get_symbol_decl (fd);
345 
346   TREE_PUBLIC (decl) = 1;
347   DECL_ARTIFICIAL (decl) = 1;
348   DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
349   DECL_VISIBILITY_SPECIFIED (decl) = 1;
350 
351   d_comdat_linkage (decl);
352 
353   /* Start laying out the body.  */
354   tree old_context = start_function (fd);
355   rest_of_decl_compilation (decl, 1, 0);
356 
357   /* if (dso_initialized != condition).  */
358   tree if_cond = build_boolop (NE_EXPR, dso_initialized_node, condition);
359 
360   /* dso_initialized = condition;  */
361   tree expr_list = modify_expr (dso_initialized_node, condition);
362 
363   /* CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};  */
364   tree dso_type = get_compiler_dso_type ();
365   tree dso = build_local_temp (dso_type);
366 
367   vec<constructor_elt, va_gc> *ve = NULL;
368   CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_integer_cst (1, size_type_node));
369   CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (dso_slot_node));
370   CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (start_minfo_node));
371   CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (stop_minfo_node));
372 
373   tree assign_expr = modify_expr (dso, build_struct_literal (dso_type, ve));
374   expr_list = compound_expr (expr_list, assign_expr);
375 
376   /* _d_dso_registry (&dso);  */
377   tree call_expr = build_call_expr (get_dso_registry_fn (), 1,
378 				    build_address (dso));
379   expr_list = compound_expr (expr_list, call_expr);
380 
381   add_stmt (build_vcondition (if_cond, expr_list, void_node));
382   finish_function (old_context);
383 
384   return decl;
385 }
386 
387 /* Build a variable used in the dso_registry code identified by NAME,
388    and data type TYPE.  The variable always has VISIBILITY_HIDDEN and
389    TREE_PUBLIC flags set.  */
390 
391 static tree
392 build_dso_registry_var (const char * name, tree type)
393 {
394   tree var = declare_extern_var (get_identifier (name), type);
395   DECL_VISIBILITY (var) = VISIBILITY_HIDDEN;
396   DECL_VISIBILITY_SPECIFIED (var) = 1;
397   return var;
398 }
399 
400 /* Place a reference to the ModuleInfo symbol MINFO for DECL into the
401    `minfo' section.  Then create the global ctors/dtors to call the
402    _d_dso_registry function if necessary.  */
403 
404 static void
405 register_moduleinfo (Module *decl, tree minfo)
406 {
407   gcc_assert (targetm_common.have_named_sections);
408 
409   /* Build the ModuleInfo reference, this is done once for every Module.  */
410   tree ident = mangle_internal_decl (decl, "__moduleRef", "Z");
411   tree mref = declare_extern_var (ident, ptr_type_node);
412 
413   /* Build the initializer and emit.  Do not start section with a `.' character
414      so that the linker will provide a __start_ and __stop_ symbol to indicate
415      the start and end address of the section respectively.
416      https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html.  */
417   DECL_INITIAL (mref) = build_address (minfo);
418   DECL_EXTERNAL (mref) = 0;
419   DECL_PRESERVE_P (mref) = 1;
420 
421   set_decl_section_name (mref, "minfo");
422   d_pushdecl (mref);
423   rest_of_decl_compilation (mref, 1, 0);
424 
425   /* Only for the first D module being emitted do we need to generate a static
426      constructor and destructor for.  These are only required once per shared
427      library, so it's safe to emit them only once per object file.  */
428   static bool first_module = true;
429   if (!first_module)
430     return;
431 
432   start_minfo_node = build_dso_registry_var ("__start_minfo", ptr_type_node);
433   rest_of_decl_compilation (start_minfo_node, 1, 0);
434 
435   stop_minfo_node = build_dso_registry_var ("__stop_minfo", ptr_type_node);
436   rest_of_decl_compilation (stop_minfo_node, 1, 0);
437 
438   /* Declare dso_slot and dso_initialized.  */
439   dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"),
440 					  ptr_type_node);
441   DECL_EXTERNAL (dso_slot_node) = 0;
442   d_comdat_linkage (dso_slot_node);
443   rest_of_decl_compilation (dso_slot_node, 1, 0);
444 
445   dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
446 						 boolean_type_node);
447   DECL_EXTERNAL (dso_initialized_node) = 0;
448   d_comdat_linkage (dso_initialized_node);
449   rest_of_decl_compilation (dso_initialized_node, 1, 0);
450 
451   /* Declare dso_ctor() and dso_dtor().  */
452   tree dso_ctor = build_dso_cdtor_fn (true);
453   vec_safe_push (static_ctor_list, dso_ctor);
454 
455   tree dso_dtor = build_dso_cdtor_fn (false);
456   vec_safe_push (static_dtor_list, dso_dtor);
457 
458   first_module = false;
459 }
460 
461 /* Convenience function for layout_moduleinfo_fields.  Adds a field of TYPE to
462    the moduleinfo record at OFFSET, incrementing the offset to the next field
463    position.  No alignment is taken into account, all fields are packed.  */
464 
465 static void
466 layout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT& offset)
467 {
468   tree field = create_field_decl (type, NULL, 1, 1);
469   insert_aggregate_field (rec_type, field, offset);
470   offset += int_size_in_bytes (type);
471 }
472 
473 /* Layout fields that immediately come after the moduleinfo TYPE for DECL.
474    Data relating to the module is packed into the type on an as-needed
475    basis, this is done to keep its size to a minimum.  */
476 
477 static tree
478 layout_moduleinfo_fields (Module *decl, tree type)
479 {
480   HOST_WIDE_INT offset = int_size_in_bytes (type);
481   type = copy_aggregate_type (type);
482 
483   /* First fields added are all the function pointers.  */
484   if (decl->sctor)
485     layout_moduleinfo_field (ptr_type_node, type, offset);
486 
487   if (decl->sdtor)
488     layout_moduleinfo_field (ptr_type_node, type, offset);
489 
490   if (decl->ssharedctor)
491     layout_moduleinfo_field (ptr_type_node, type, offset);
492 
493   if (decl->sshareddtor)
494     layout_moduleinfo_field (ptr_type_node, type, offset);
495 
496   if (decl->findGetMembers ())
497     layout_moduleinfo_field (ptr_type_node, type, offset);
498 
499   if (decl->sictor)
500     layout_moduleinfo_field (ptr_type_node, type, offset);
501 
502   if (decl->stest)
503     layout_moduleinfo_field (ptr_type_node, type, offset);
504 
505   /* Array of module imports is laid out as a length field, followed by
506      a static array of ModuleInfo pointers.  */
507   size_t aimports_dim = decl->aimports.dim;
508   for (size_t i = 0; i < decl->aimports.dim; i++)
509     {
510       Module *mi = decl->aimports[i];
511       if (!mi->needmoduleinfo)
512 	aimports_dim--;
513     }
514 
515   if (aimports_dim)
516     {
517       layout_moduleinfo_field (size_type_node, type, offset);
518       layout_moduleinfo_field (make_array_type (Type::tvoidptr, aimports_dim),
519 			       type, offset);
520     }
521 
522   /* Array of local ClassInfo decls are laid out in the same way.  */
523   ClassDeclarations aclasses;
524   for (size_t i = 0; i < decl->members->dim; i++)
525     {
526       Dsymbol *member = (*decl->members)[i];
527       member->addLocalClass (&aclasses);
528     }
529 
530   if (aclasses.dim)
531     {
532       layout_moduleinfo_field (size_type_node, type, offset);
533       layout_moduleinfo_field (make_array_type (Type::tvoidptr, aclasses.dim),
534 			       type, offset);
535     }
536 
537   /* Lastly, the name of the module is a static char array.  */
538   size_t namelen = strlen (decl->toPrettyChars ()) + 1;
539   layout_moduleinfo_field (make_array_type (Type::tchar, namelen),
540 			   type, offset);
541 
542   size_t alignsize = MAX (TYPE_ALIGN_UNIT (type),
543 			  TYPE_ALIGN_UNIT (ptr_type_node));
544   finish_aggregate_type (offset, alignsize, type, NULL);
545 
546   return type;
547 }
548 
549 /* Output the ModuleInfo for module DECL and register it with druntime.  */
550 
551 static void
552 layout_moduleinfo (Module *decl)
553 {
554   ClassDeclarations aclasses;
555   FuncDeclaration *sgetmembers;
556 
557   for (size_t i = 0; i < decl->members->dim; i++)
558     {
559       Dsymbol *member = (*decl->members)[i];
560       member->addLocalClass (&aclasses);
561     }
562 
563   size_t aimports_dim = decl->aimports.dim;
564   for (size_t i = 0; i < decl->aimports.dim; i++)
565     {
566       Module *mi = decl->aimports[i];
567       if (!mi->needmoduleinfo)
568 	aimports_dim--;
569     }
570 
571   sgetmembers = decl->findGetMembers ();
572 
573   size_t flags = 0;
574   if (decl->sctor)
575     flags |= MItlsctor;
576   if (decl->sdtor)
577     flags |= MItlsdtor;
578   if (decl->ssharedctor)
579     flags |= MIctor;
580   if (decl->sshareddtor)
581     flags |= MIdtor;
582   if (sgetmembers)
583     flags |= MIxgetMembers;
584   if (decl->sictor)
585     flags |= MIictor;
586   if (decl->stest)
587     flags |= MIunitTest;
588   if (aimports_dim)
589     flags |= MIimportedModules;
590   if (aclasses.dim)
591     flags |= MIlocalClasses;
592   if (!decl->needmoduleinfo)
593     flags |= MIstandalone;
594 
595   flags |= MIname;
596 
597   tree minfo = get_moduleinfo_decl (decl);
598   tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo));
599 
600   /* Put out the two named fields in a ModuleInfo decl:
601 	uint flags;
602 	uint index;  */
603   vec<constructor_elt, va_gc> *minit = NULL;
604 
605   CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
606 			  build_integer_cst (flags, d_uint_type));
607 
608   CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
609 			  build_integer_cst (0, d_uint_type));
610 
611   /* Order of appearance, depending on flags:
612 	void function() tlsctor;
613 	void function() tlsdtor;
614 	void* function() xgetMembers;
615 	void function() ctor;
616 	void function() dtor;
617 	void function() ictor;
618 	void function() unitTest;
619 	ModuleInfo*[] importedModules;
620 	TypeInfo_Class[] localClasses;
621 	char[N] name;
622    */
623   if (flags & MItlsctor)
624     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor));
625 
626   if (flags & MItlsdtor)
627     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor));
628 
629   if (flags & MIctor)
630     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
631 			    build_address (decl->ssharedctor));
632 
633   if (flags & MIdtor)
634     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
635 			    build_address (decl->sshareddtor));
636 
637   if (flags & MIxgetMembers)
638     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
639 			    build_address (get_symbol_decl (sgetmembers)));
640 
641   if (flags & MIictor)
642     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor));
643 
644   if (flags & MIunitTest)
645     CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest));
646 
647   if (flags & MIimportedModules)
648     {
649       vec<constructor_elt, va_gc> *elms = NULL;
650       tree satype = make_array_type (Type::tvoidptr, aimports_dim);
651       size_t idx = 0;
652 
653       for (size_t i = 0; i < decl->aimports.dim; i++)
654 	{
655 	  Module *mi = decl->aimports[i];
656 	  if (mi->needmoduleinfo)
657 	    {
658 	      CONSTRUCTOR_APPEND_ELT (elms, size_int (idx),
659 				      build_address (get_moduleinfo_decl (mi)));
660 	      idx++;
661 	    }
662 	}
663 
664       CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));
665       CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
666 			      build_constructor (satype, elms));
667     }
668 
669   if (flags & MIlocalClasses)
670     {
671       vec<constructor_elt, va_gc> *elms = NULL;
672       tree satype = make_array_type (Type::tvoidptr, aclasses.dim);
673 
674       for (size_t i = 0; i < aclasses.dim; i++)
675 	{
676 	  ClassDeclaration *cd = aclasses[i];
677 	  CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
678 				  build_address (get_classinfo_decl (cd)));
679 	}
680 
681       CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.dim));
682       CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
683 			      build_constructor (satype, elms));
684     }
685 
686   if (flags & MIname)
687     {
688       /* Put out module name as a 0-terminated C-string, to save bytes.  */
689       const char *name = decl->toPrettyChars ();
690       size_t namelen = strlen (name) + 1;
691       tree strtree = build_string (namelen, name);
692       TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen);
693       CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree);
694     }
695 
696   TREE_TYPE (minfo) = type;
697   DECL_INITIAL (minfo) = build_struct_literal (type, minit);
698   d_finish_decl (minfo);
699 
700   /* Register the module against druntime.  */
701   register_moduleinfo (decl, minfo);
702 }
703 
704 /* Send the Module AST class DECL to GCC back-end.  */
705 
706 void
707 build_module_tree (Module *decl)
708 {
709   /* There may be more than one module per object file, but should only
710      ever compile them one at a time.  */
711   assert (!current_moduleinfo && !current_module_decl);
712 
713   module_info mi = module_info ();
714   module_info mitest = module_info ();
715 
716   current_moduleinfo = &mi;
717   current_testing_module = &mitest;
718   current_module_decl = decl;
719 
720   /* Layout module members.  */
721   if (decl->members)
722     {
723       for (size_t i = 0; i < decl->members->dim; i++)
724 	{
725 	  Dsymbol *s = (*decl->members)[i];
726 	  build_decl_tree (s);
727 	}
728     }
729 
730   /* For libphobos-internal use only.  Generate a separate module info symbol
731      that references all compiled in unittests, this allows compiling library
732      modules and linking to libphobos without having run-time conflicts because
733      of two ModuleInfo records with the same name being present in two DSOs.  */
734   if (flag_building_libphobos_tests)
735     {
736       /* Associate the module info symbol with a mock module.  */
737       const char *name = concat (GDC_PREFIX ("modtest__"),
738 				 decl->ident->toChars (), NULL);
739       Module *tm = Module::create (decl->arg, Identifier::idPool (name), 0, 0);
740       Dsymbols members;
741 
742       /* Setting parent puts module in the same package as the current, to
743 	 avoid any symbol conflicts.  */
744       tm->parent = decl->parent;
745       tm->needmoduleinfo = decl->needmoduleinfo;
746       tm->members = &members;
747       /* Register the current module as being imported by the mock module.
748 	 This informs run-time that there is a dependency between the two.  */
749       tm->aimports.push (decl);
750 
751       if (mitest.ctors || mitest.ctorgates)
752 	tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"),
753 					  mitest.ctors, mitest.ctorgates);
754 
755       if (mitest.dtors)
756 	tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"),
757 					  mitest.dtors, NULL);
758 
759       if (mitest.sharedctors || mitest.sharedctorgates)
760 	tm->ssharedctor
761 	  = build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"),
762 				  mitest.sharedctors, mitest.sharedctorgates);
763 
764       if (mitest.shareddtors)
765 	tm->sshareddtor
766 	  = build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"),
767 				  mitest.shareddtors, NULL);
768 
769       if (mi.unitTests)
770 	tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
771 					  mi.unitTests, NULL);
772 
773       mi.unitTests = NULL;
774       layout_moduleinfo (tm);
775     }
776 
777   /* Default behavior is to always generate module info because of templates.
778      Can be switched off for not compiling against runtime library.  */
779   if (global.params.useModuleInfo
780       && Module::moduleinfo != NULL
781       && decl->ident != Identifier::idPool ("__entrypoint"))
782     {
783       if (mi.ctors || mi.ctorgates)
784 	decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"),
785 					    mi.ctors, mi.ctorgates);
786 
787       if (mi.dtors)
788 	decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"),
789 					    mi.dtors, NULL);
790 
791       if (mi.sharedctors || mi.sharedctorgates)
792 	decl->ssharedctor
793 	  = build_funcs_gates_fn (get_identifier ("*__modsharedctor"),
794 				  mi.sharedctors, mi.sharedctorgates);
795 
796       if (mi.shareddtors)
797 	decl->sshareddtor
798 	  = build_funcs_gates_fn (get_identifier ("*__modshareddtor"),
799 				  mi.shareddtors, NULL);
800 
801       if (mi.unitTests)
802 	decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
803 					    mi.unitTests, NULL);
804 
805       layout_moduleinfo (decl);
806     }
807 
808   current_moduleinfo = NULL;
809   current_testing_module = NULL;
810   current_module_decl = NULL;
811 }
812 
813 /* Returns the current function or module context for the purpose
814    of imported_module_or_decl.  */
815 
816 tree
817 d_module_context (void)
818 {
819   if (cfun != NULL)
820     return current_function_decl;
821 
822   gcc_assert (current_module_decl != NULL);
823   return build_import_decl (current_module_decl);
824 }
825 
826 /* Maybe record declaration D against our module information structure.  */
827 
828 void
829 register_module_decl (Declaration *d)
830 {
831   FuncDeclaration *fd = d->isFuncDeclaration ();
832   if (fd != NULL)
833     {
834       tree decl = get_symbol_decl (fd);
835 
836       /* Any module constructors or destructors that are only present when
837 	 compiling in unittests are kept track of separately so they are
838 	 not omitted when compiling with -fbuilding-libphobos-tests.  */
839       module_info *minfo;
840       if (flag_building_libphobos_tests && !fd->isUnitTestDeclaration ()
841 	  && DECL_IN_UNITTEST_CONDITION_P (decl))
842 	minfo = current_testing_module;
843       else
844 	minfo = current_moduleinfo;
845 
846       gcc_assert (minfo != NULL);
847 
848       /* If a static constructor, push into the current ModuleInfo.
849 	 Checks for `shared' first because it derives from the non-shared
850 	 constructor type in the front-end.  */
851       if (fd->isSharedStaticCtorDeclaration ())
852 	vec_safe_push (minfo->sharedctors, decl);
853       else if (fd->isStaticCtorDeclaration ())
854 	vec_safe_push (minfo->ctors, decl);
855 
856       /* If a static destructor, do same as with constructors, but also
857 	 increment the destructor's vgate at construction time.  */
858       if (fd->isSharedStaticDtorDeclaration ())
859 	{
860 	  VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate;
861 	  if (vgate != NULL)
862 	    {
863 	      tree gate = get_symbol_decl (vgate);
864 	      vec_safe_push (minfo->sharedctorgates, gate);
865 	    }
866 	  vec_safe_insert (minfo->shareddtors, 0, decl);
867 	}
868       else if (fd->isStaticDtorDeclaration ())
869 	{
870 	  VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate;
871 	  if (vgate != NULL)
872 	    {
873 	      tree gate = get_symbol_decl (vgate);
874 	      vec_safe_push (minfo->ctorgates, gate);
875 	    }
876 	  vec_safe_insert (minfo->dtors, 0, decl);
877 	}
878 
879       /* If a unittest function.  */
880       if (fd->isUnitTestDeclaration ())
881 	vec_safe_push (minfo->unitTests, decl);
882     }
883 }
884 
885 /* Wrapup all global declarations and start the final compilation.  */
886 
887 void
888 d_finish_compilation (tree *vec, int len)
889 {
890   /* Complete all generated thunks.  */
891   symtab->process_same_body_aliases ();
892 
893   /* Process all file scopes in this compilation, and the external_scope,
894      through wrapup_global_declarations.  */
895   for (int i = 0; i < len; i++)
896     {
897       tree decl = vec[i];
898       wrapup_global_declarations (&decl, 1);
899     }
900 
901   /* If the target does not directly support static constructors,
902      static_ctor_list contains a list of all static constructors defined
903      so far.  This routine will create a function to call all of those
904      and is picked up by collect2.  */
905   if (static_ctor_list)
906     {
907       tree decl = build_funcs_gates_fn (get_file_function_name ("I"),
908 					static_ctor_list, NULL);
909       DECL_STATIC_CONSTRUCTOR (decl) = 1;
910       decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY);
911     }
912 
913   if (static_dtor_list)
914     {
915       tree decl = build_funcs_gates_fn (get_file_function_name ("D"),
916 					static_dtor_list, NULL);
917       DECL_STATIC_DESTRUCTOR (decl) = 1;
918       decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY);
919     }
920 }
921 
922 
923 #include "gt-d-modules.h"
924