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