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