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