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