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