1 /* modules.cc -- D module initialization and termination. 2 Copyright (C) 2013-2019 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 "fold-const.h" 28 #include "tm.h" 29 #include "function.h" 30 #include "cgraph.h" 31 #include "stor-layout.h" 32 #include "toplev.h" 33 #include "target.h" 34 #include "common/common-target.h" 35 #include "stringpool.h" 36 37 #include "d-tree.h" 38 39 40 /* D generates module information to inform the runtime library which modules 41 need some kind of special handling. All `static this()', `static ~this()', 42 and `unittest' functions for a given module are aggregated into a single 43 function - one for each kind - and a pointer to that function is inserted 44 into the ModuleInfo instance for that module. 45 46 Module information for a particular module is indicated with an ABI defined 47 structure derived from ModuleInfo. ModuleInfo is a variably sized struct 48 with two fixed base fields. The first field `flags' determines what 49 information is packed immediately after the record type. 50 51 Like TypeInfo, the runtime library provides the definitions of the ModuleInfo 52 structure, as well as accessors for the variadic fields. So we only define 53 layout compatible POD_structs for ModuleInfo. */ 54 55 /* The internally represented ModuleInfo and CompilerDSO types. */ 56 static tree moduleinfo_type; 57 static tree compiler_dso_type; 58 static tree dso_registry_fn; 59 60 /* The DSO slot for use by the druntime implementation. */ 61 static tree dso_slot_node; 62 63 /* For registering and deregistering DSOs with druntime, we have one global 64 constructor and destructor per object that calls _d_dso_registry with the 65 respective DSO record. To ensure that this is only done once, a 66 `dso_initialized' variable is introduced to guard repeated calls. */ 67 static tree dso_initialized_node; 68 69 /* The beginning and end of the `minfo' section. */ 70 static tree start_minfo_node; 71 static tree stop_minfo_node; 72 73 /* Record information about module initialization, termination, 74 unit testing, and thread local storage in the compilation. */ 75 76 struct GTY(()) module_info 77 { 78 vec<tree, va_gc> *ctors; 79 vec<tree, va_gc> *dtors; 80 vec<tree, va_gc> *ctorgates; 81 82 vec<tree, va_gc> *sharedctors; 83 vec<tree, va_gc> *shareddtors; 84 vec<tree, va_gc> *sharedctorgates; 85 86 vec<tree, va_gc> *unitTests; 87 }; 88 89 /* These must match the values in libdruntime/object_.d. */ 90 91 enum module_info_flags 92 { 93 MIctorstart = 0x1, 94 MIctordone = 0x2, 95 MIstandalone = 0x4, 96 MItlsctor = 0x8, 97 MItlsdtor = 0x10, 98 MIctor = 0x20, 99 MIdtor = 0x40, 100 MIxgetMembers = 0x80, 101 MIictor = 0x100, 102 MIunitTest = 0x200, 103 MIimportedModules = 0x400, 104 MIlocalClasses = 0x800, 105 MIname = 0x1000 106 }; 107 108 /* The ModuleInfo information structure for the module currently being compiled. 109 Assuming that only ever process one at a time. */ 110 111 static module_info *current_moduleinfo; 112 113 /* When compiling with -fbuilding-libphobos-tests, this contains information 114 about the module that gets compiled in only when unittests are enabled. */ 115 116 static module_info *current_testing_module; 117 118 /* The declaration of the current module being compiled. */ 119 120 static Module *current_module_decl; 121 122 /* Static constructors and destructors (not D `static this'). */ 123 124 static GTY(()) vec<tree, va_gc> *static_ctor_list; 125 static GTY(()) vec<tree, va_gc> *static_dtor_list; 126 127 /* Returns an internal function identified by IDENT. This is used 128 by both module initialization and dso handlers. */ 129 130 static FuncDeclaration * 131 get_internal_fn (tree ident) 132 { 133 Module *mod = current_module_decl; 134 const char *name = IDENTIFIER_POINTER (ident); 135 136 if (!mod) 137 mod = Module::rootModule; 138 139 if (name[0] == '*') 140 { 141 tree s = mangle_internal_decl (mod, name + 1, "FZv"); 142 name = IDENTIFIER_POINTER (s); 143 } 144 145 FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid, 146 Identifier::idPool (name)); 147 fd->loc = Loc (mod->srcfile->toChars (), 1, 0); 148 fd->parent = mod; 149 fd->protection.kind = PROTprivate; 150 fd->semanticRun = PASSsemantic3done; 151 152 return fd; 153 } 154 155 /* Generate an internal function identified by IDENT. 156 The function body to add is in EXPR. */ 157 158 static tree 159 build_internal_fn (tree ident, tree expr) 160 { 161 FuncDeclaration *fd = get_internal_fn (ident); 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 FuncDeclaration *fd = get_internal_fn (get_identifier (name)); 344 tree decl = get_symbol_decl (fd); 345 346 TREE_PUBLIC (decl) = 1; 347 DECL_ARTIFICIAL (decl) = 1; 348 DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; 349 DECL_VISIBILITY_SPECIFIED (decl) = 1; 350 351 d_comdat_linkage (decl); 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 gcc_assert (targetm_common.have_named_sections); 408 409 /* Build the ModuleInfo reference, this is done once for every Module. */ 410 tree ident = mangle_internal_decl (decl, "__moduleRef", "Z"); 411 tree mref = declare_extern_var (ident, ptr_type_node); 412 413 /* Build the initializer and emit. Do not start section with a `.' character 414 so that the linker will provide a __start_ and __stop_ symbol to indicate 415 the start and end address of the section respectively. 416 https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html. */ 417 DECL_INITIAL (mref) = build_address (minfo); 418 DECL_EXTERNAL (mref) = 0; 419 DECL_PRESERVE_P (mref) = 1; 420 421 set_decl_section_name (mref, "minfo"); 422 d_pushdecl (mref); 423 rest_of_decl_compilation (mref, 1, 0); 424 425 /* Only for the first D module being emitted do we need to generate a static 426 constructor and destructor for. These are only required once per shared 427 library, so it's safe to emit them only once per object file. */ 428 static bool first_module = true; 429 if (!first_module) 430 return; 431 432 start_minfo_node = build_dso_registry_var ("__start_minfo", ptr_type_node); 433 rest_of_decl_compilation (start_minfo_node, 1, 0); 434 435 stop_minfo_node = build_dso_registry_var ("__stop_minfo", ptr_type_node); 436 rest_of_decl_compilation (stop_minfo_node, 1, 0); 437 438 /* Declare dso_slot and dso_initialized. */ 439 dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"), 440 ptr_type_node); 441 DECL_EXTERNAL (dso_slot_node) = 0; 442 d_comdat_linkage (dso_slot_node); 443 rest_of_decl_compilation (dso_slot_node, 1, 0); 444 445 dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"), 446 boolean_type_node); 447 DECL_EXTERNAL (dso_initialized_node) = 0; 448 d_comdat_linkage (dso_initialized_node); 449 rest_of_decl_compilation (dso_initialized_node, 1, 0); 450 451 /* Declare dso_ctor() and dso_dtor(). */ 452 tree dso_ctor = build_dso_cdtor_fn (true); 453 vec_safe_push (static_ctor_list, dso_ctor); 454 455 tree dso_dtor = build_dso_cdtor_fn (false); 456 vec_safe_push (static_dtor_list, dso_dtor); 457 458 first_module = false; 459 } 460 461 /* Convenience function for layout_moduleinfo_fields. Adds a field of TYPE to 462 the moduleinfo record at OFFSET, incrementing the offset to the next field 463 position. No alignment is taken into account, all fields are packed. */ 464 465 static void 466 layout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT& offset) 467 { 468 tree field = create_field_decl (type, NULL, 1, 1); 469 insert_aggregate_field (rec_type, field, offset); 470 offset += int_size_in_bytes (type); 471 } 472 473 /* Layout fields that immediately come after the moduleinfo TYPE for DECL. 474 Data relating to the module is packed into the type on an as-needed 475 basis, this is done to keep its size to a minimum. */ 476 477 static tree 478 layout_moduleinfo_fields (Module *decl, tree type) 479 { 480 HOST_WIDE_INT offset = int_size_in_bytes (type); 481 type = copy_aggregate_type (type); 482 483 /* First fields added are all the function pointers. */ 484 if (decl->sctor) 485 layout_moduleinfo_field (ptr_type_node, type, offset); 486 487 if (decl->sdtor) 488 layout_moduleinfo_field (ptr_type_node, type, offset); 489 490 if (decl->ssharedctor) 491 layout_moduleinfo_field (ptr_type_node, type, offset); 492 493 if (decl->sshareddtor) 494 layout_moduleinfo_field (ptr_type_node, type, offset); 495 496 if (decl->findGetMembers ()) 497 layout_moduleinfo_field (ptr_type_node, type, offset); 498 499 if (decl->sictor) 500 layout_moduleinfo_field (ptr_type_node, type, offset); 501 502 if (decl->stest) 503 layout_moduleinfo_field (ptr_type_node, type, offset); 504 505 /* Array of module imports is laid out as a length field, followed by 506 a static array of ModuleInfo pointers. */ 507 size_t aimports_dim = decl->aimports.dim; 508 for (size_t i = 0; i < decl->aimports.dim; i++) 509 { 510 Module *mi = decl->aimports[i]; 511 if (!mi->needmoduleinfo) 512 aimports_dim--; 513 } 514 515 if (aimports_dim) 516 { 517 layout_moduleinfo_field (size_type_node, type, offset); 518 layout_moduleinfo_field (make_array_type (Type::tvoidptr, aimports_dim), 519 type, offset); 520 } 521 522 /* Array of local ClassInfo decls are laid out in the same way. */ 523 ClassDeclarations aclasses; 524 for (size_t i = 0; i < decl->members->dim; i++) 525 { 526 Dsymbol *member = (*decl->members)[i]; 527 member->addLocalClass (&aclasses); 528 } 529 530 if (aclasses.dim) 531 { 532 layout_moduleinfo_field (size_type_node, type, offset); 533 layout_moduleinfo_field (make_array_type (Type::tvoidptr, aclasses.dim), 534 type, offset); 535 } 536 537 /* Lastly, the name of the module is a static char array. */ 538 size_t namelen = strlen (decl->toPrettyChars ()) + 1; 539 layout_moduleinfo_field (make_array_type (Type::tchar, namelen), 540 type, offset); 541 542 size_t alignsize = MAX (TYPE_ALIGN_UNIT (type), 543 TYPE_ALIGN_UNIT (ptr_type_node)); 544 finish_aggregate_type (offset, alignsize, type, NULL); 545 546 return type; 547 } 548 549 /* Output the ModuleInfo for module DECL and register it with druntime. */ 550 551 static void 552 layout_moduleinfo (Module *decl) 553 { 554 ClassDeclarations aclasses; 555 FuncDeclaration *sgetmembers; 556 557 for (size_t i = 0; i < decl->members->dim; i++) 558 { 559 Dsymbol *member = (*decl->members)[i]; 560 member->addLocalClass (&aclasses); 561 } 562 563 size_t aimports_dim = decl->aimports.dim; 564 for (size_t i = 0; i < decl->aimports.dim; i++) 565 { 566 Module *mi = decl->aimports[i]; 567 if (!mi->needmoduleinfo) 568 aimports_dim--; 569 } 570 571 sgetmembers = decl->findGetMembers (); 572 573 size_t flags = 0; 574 if (decl->sctor) 575 flags |= MItlsctor; 576 if (decl->sdtor) 577 flags |= MItlsdtor; 578 if (decl->ssharedctor) 579 flags |= MIctor; 580 if (decl->sshareddtor) 581 flags |= MIdtor; 582 if (sgetmembers) 583 flags |= MIxgetMembers; 584 if (decl->sictor) 585 flags |= MIictor; 586 if (decl->stest) 587 flags |= MIunitTest; 588 if (aimports_dim) 589 flags |= MIimportedModules; 590 if (aclasses.dim) 591 flags |= MIlocalClasses; 592 if (!decl->needmoduleinfo) 593 flags |= MIstandalone; 594 595 flags |= MIname; 596 597 tree minfo = get_moduleinfo_decl (decl); 598 tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo)); 599 600 /* Put out the two named fields in a ModuleInfo decl: 601 uint flags; 602 uint index; */ 603 vec<constructor_elt, va_gc> *minit = NULL; 604 605 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 606 build_integer_cst (flags, d_uint_type)); 607 608 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 609 build_integer_cst (0, d_uint_type)); 610 611 /* Order of appearance, depending on flags: 612 void function() tlsctor; 613 void function() tlsdtor; 614 void* function() xgetMembers; 615 void function() ctor; 616 void function() dtor; 617 void function() ictor; 618 void function() unitTest; 619 ModuleInfo*[] importedModules; 620 TypeInfo_Class[] localClasses; 621 char[N] name; 622 */ 623 if (flags & MItlsctor) 624 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor)); 625 626 if (flags & MItlsdtor) 627 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor)); 628 629 if (flags & MIctor) 630 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 631 build_address (decl->ssharedctor)); 632 633 if (flags & MIdtor) 634 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 635 build_address (decl->sshareddtor)); 636 637 if (flags & MIxgetMembers) 638 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 639 build_address (get_symbol_decl (sgetmembers))); 640 641 if (flags & MIictor) 642 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor)); 643 644 if (flags & MIunitTest) 645 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest)); 646 647 if (flags & MIimportedModules) 648 { 649 vec<constructor_elt, va_gc> *elms = NULL; 650 tree satype = make_array_type (Type::tvoidptr, aimports_dim); 651 size_t idx = 0; 652 653 for (size_t i = 0; i < decl->aimports.dim; i++) 654 { 655 Module *mi = decl->aimports[i]; 656 if (mi->needmoduleinfo) 657 { 658 CONSTRUCTOR_APPEND_ELT (elms, size_int (idx), 659 build_address (get_moduleinfo_decl (mi))); 660 idx++; 661 } 662 } 663 664 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim)); 665 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 666 build_constructor (satype, elms)); 667 } 668 669 if (flags & MIlocalClasses) 670 { 671 vec<constructor_elt, va_gc> *elms = NULL; 672 tree satype = make_array_type (Type::tvoidptr, aclasses.dim); 673 674 for (size_t i = 0; i < aclasses.dim; i++) 675 { 676 ClassDeclaration *cd = aclasses[i]; 677 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), 678 build_address (get_classinfo_decl (cd))); 679 } 680 681 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.dim)); 682 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 683 build_constructor (satype, elms)); 684 } 685 686 if (flags & MIname) 687 { 688 /* Put out module name as a 0-terminated C-string, to save bytes. */ 689 const char *name = decl->toPrettyChars (); 690 size_t namelen = strlen (name) + 1; 691 tree strtree = build_string (namelen, name); 692 TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen); 693 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree); 694 } 695 696 TREE_TYPE (minfo) = type; 697 DECL_INITIAL (minfo) = build_struct_literal (type, minit); 698 d_finish_decl (minfo); 699 700 /* Register the module against druntime. */ 701 register_moduleinfo (decl, minfo); 702 } 703 704 /* Send the Module AST class DECL to GCC back-end. */ 705 706 void 707 build_module_tree (Module *decl) 708 { 709 /* There may be more than one module per object file, but should only 710 ever compile them one at a time. */ 711 assert (!current_moduleinfo && !current_module_decl); 712 713 module_info mi = module_info (); 714 module_info mitest = module_info (); 715 716 current_moduleinfo = &mi; 717 current_testing_module = &mitest; 718 current_module_decl = decl; 719 720 /* Layout module members. */ 721 if (decl->members) 722 { 723 for (size_t i = 0; i < decl->members->dim; i++) 724 { 725 Dsymbol *s = (*decl->members)[i]; 726 build_decl_tree (s); 727 } 728 } 729 730 /* For libphobos-internal use only. Generate a separate module info symbol 731 that references all compiled in unittests, this allows compiling library 732 modules and linking to libphobos without having run-time conflicts because 733 of two ModuleInfo records with the same name being present in two DSOs. */ 734 if (flag_building_libphobos_tests) 735 { 736 /* Associate the module info symbol with a mock module. */ 737 const char *name = concat (GDC_PREFIX ("modtest__"), 738 decl->ident->toChars (), NULL); 739 Module *tm = Module::create (decl->arg, Identifier::idPool (name), 0, 0); 740 Dsymbols members; 741 742 /* Setting parent puts module in the same package as the current, to 743 avoid any symbol conflicts. */ 744 tm->parent = decl->parent; 745 tm->needmoduleinfo = decl->needmoduleinfo; 746 tm->members = &members; 747 /* Register the current module as being imported by the mock module. 748 This informs run-time that there is a dependency between the two. */ 749 tm->aimports.push (decl); 750 751 if (mitest.ctors || mitest.ctorgates) 752 tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"), 753 mitest.ctors, mitest.ctorgates); 754 755 if (mitest.dtors) 756 tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"), 757 mitest.dtors, NULL); 758 759 if (mitest.sharedctors || mitest.sharedctorgates) 760 tm->ssharedctor 761 = build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"), 762 mitest.sharedctors, mitest.sharedctorgates); 763 764 if (mitest.shareddtors) 765 tm->sshareddtor 766 = build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"), 767 mitest.shareddtors, NULL); 768 769 if (mi.unitTests) 770 tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"), 771 mi.unitTests, NULL); 772 773 mi.unitTests = NULL; 774 layout_moduleinfo (tm); 775 } 776 777 /* Default behavior is to always generate module info because of templates. 778 Can be switched off for not compiling against runtime library. */ 779 if (global.params.useModuleInfo 780 && Module::moduleinfo != NULL 781 && decl->ident != Identifier::idPool ("__entrypoint")) 782 { 783 if (mi.ctors || mi.ctorgates) 784 decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"), 785 mi.ctors, mi.ctorgates); 786 787 if (mi.dtors) 788 decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"), 789 mi.dtors, NULL); 790 791 if (mi.sharedctors || mi.sharedctorgates) 792 decl->ssharedctor 793 = build_funcs_gates_fn (get_identifier ("*__modsharedctor"), 794 mi.sharedctors, mi.sharedctorgates); 795 796 if (mi.shareddtors) 797 decl->sshareddtor 798 = build_funcs_gates_fn (get_identifier ("*__modshareddtor"), 799 mi.shareddtors, NULL); 800 801 if (mi.unitTests) 802 decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"), 803 mi.unitTests, NULL); 804 805 layout_moduleinfo (decl); 806 } 807 808 current_moduleinfo = NULL; 809 current_testing_module = NULL; 810 current_module_decl = NULL; 811 } 812 813 /* Returns the current function or module context for the purpose 814 of imported_module_or_decl. */ 815 816 tree 817 d_module_context (void) 818 { 819 if (cfun != NULL) 820 return current_function_decl; 821 822 gcc_assert (current_module_decl != NULL); 823 return build_import_decl (current_module_decl); 824 } 825 826 /* Maybe record declaration D against our module information structure. */ 827 828 void 829 register_module_decl (Declaration *d) 830 { 831 FuncDeclaration *fd = d->isFuncDeclaration (); 832 if (fd != NULL) 833 { 834 tree decl = get_symbol_decl (fd); 835 836 /* Any module constructors or destructors that are only present when 837 compiling in unittests are kept track of separately so they are 838 not omitted when compiling with -fbuilding-libphobos-tests. */ 839 module_info *minfo; 840 if (flag_building_libphobos_tests && !fd->isUnitTestDeclaration () 841 && DECL_IN_UNITTEST_CONDITION_P (decl)) 842 minfo = current_testing_module; 843 else 844 minfo = current_moduleinfo; 845 846 gcc_assert (minfo != NULL); 847 848 /* If a static constructor, push into the current ModuleInfo. 849 Checks for `shared' first because it derives from the non-shared 850 constructor type in the front-end. */ 851 if (fd->isSharedStaticCtorDeclaration ()) 852 vec_safe_push (minfo->sharedctors, decl); 853 else if (fd->isStaticCtorDeclaration ()) 854 vec_safe_push (minfo->ctors, decl); 855 856 /* If a static destructor, do same as with constructors, but also 857 increment the destructor's vgate at construction time. */ 858 if (fd->isSharedStaticDtorDeclaration ()) 859 { 860 VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate; 861 if (vgate != NULL) 862 { 863 tree gate = get_symbol_decl (vgate); 864 vec_safe_push (minfo->sharedctorgates, gate); 865 } 866 vec_safe_insert (minfo->shareddtors, 0, decl); 867 } 868 else if (fd->isStaticDtorDeclaration ()) 869 { 870 VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate; 871 if (vgate != NULL) 872 { 873 tree gate = get_symbol_decl (vgate); 874 vec_safe_push (minfo->ctorgates, gate); 875 } 876 vec_safe_insert (minfo->dtors, 0, decl); 877 } 878 879 /* If a unittest function. */ 880 if (fd->isUnitTestDeclaration ()) 881 vec_safe_push (minfo->unitTests, decl); 882 } 883 } 884 885 /* Wrapup all global declarations and start the final compilation. */ 886 887 void 888 d_finish_compilation (tree *vec, int len) 889 { 890 /* Complete all generated thunks. */ 891 symtab->process_same_body_aliases (); 892 893 /* Process all file scopes in this compilation, and the external_scope, 894 through wrapup_global_declarations. */ 895 for (int i = 0; i < len; i++) 896 { 897 tree decl = vec[i]; 898 wrapup_global_declarations (&decl, 1); 899 } 900 901 /* If the target does not directly support static constructors, 902 static_ctor_list contains a list of all static constructors defined 903 so far. This routine will create a function to call all of those 904 and is picked up by collect2. */ 905 if (static_ctor_list) 906 { 907 tree decl = build_funcs_gates_fn (get_file_function_name ("I"), 908 static_ctor_list, NULL); 909 DECL_STATIC_CONSTRUCTOR (decl) = 1; 910 decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY); 911 } 912 913 if (static_dtor_list) 914 { 915 tree decl = build_funcs_gates_fn (get_file_function_name ("D"), 916 static_dtor_list, NULL); 917 DECL_STATIC_DESTRUCTOR (decl) = 1; 918 decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY); 919 } 920 } 921 922 923 #include "gt-d-modules.h" 924