1 /* modules.cc -- D module initialization and termination. 2 Copyright (C) 2013-2020 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 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. */ 57 static tree moduleinfo_type; 58 static tree compiler_dso_type; 59 static tree dso_registry_fn; 60 61 /* The DSO slot for use by the druntime implementation. */ 62 static 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. */ 68 static tree dso_initialized_node; 69 70 /* The beginning and end of the `minfo' section. */ 71 static tree start_minfo_node; 72 static tree stop_minfo_node; 73 74 /* Record information about module initialization, termination, 75 unit testing, and thread local storage in the compilation. */ 76 77 struct 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 92 enum 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 112 static module_info *current_moduleinfo; 113 114 /* When compiling with -fbuilding-libphobos-tests, this contains information 115 about the module that gets compiled in only when unittests are enabled. */ 116 117 static module_info *current_testing_module; 118 119 /* The declaration of the current module being compiled. */ 120 121 static Module *current_module_decl; 122 123 /* Static constructors and destructors (not D `static this'). */ 124 125 static GTY(()) vec<tree, va_gc> *static_ctor_list; 126 static 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 131 static FuncDeclaration * 132 get_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; 150 fd->protection.kind = PROTprivate; 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 159 static tree 160 build_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 182 static tree 183 build_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 214 static tree 215 get_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 237 static tree 238 get_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 258 static tree 259 get_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 304 static tree 305 get_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 326 static tree 327 build_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 392 static tree 393 build_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 405 static void 406 register_moduleinfo (Module *decl, tree minfo) 407 { 408 if (!targetm_common.have_named_sections) 409 sorry ("%<-fmoduleinfo%> is not supported on this target"); 410 411 /* Build the ModuleInfo reference, this is done once for every Module. */ 412 tree ident = mangle_internal_decl (decl, "__moduleRef", "Z"); 413 tree mref = declare_extern_var (ident, ptr_type_node); 414 415 /* Build the initializer and emit. Do not start section with a `.' character 416 so that the linker will provide a __start_ and __stop_ symbol to indicate 417 the start and end address of the section respectively. 418 https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html. */ 419 DECL_INITIAL (mref) = build_address (minfo); 420 DECL_EXTERNAL (mref) = 0; 421 DECL_PRESERVE_P (mref) = 1; 422 423 set_decl_section_name (mref, "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 467 static void 468 layout_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 479 static tree 480 layout_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. */ 509 size_t aimports_dim = decl->aimports.dim; 510 for (size_t i = 0; i < decl->aimports.dim; i++) 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; 526 for (size_t i = 0; i < decl->members->dim; i++) 527 { 528 Dsymbol *member = (*decl->members)[i]; 529 member->addLocalClass (&aclasses); 530 } 531 532 if (aclasses.dim) 533 { 534 layout_moduleinfo_field (size_type_node, type, offset); 535 layout_moduleinfo_field (make_array_type (Type::tvoidptr, aclasses.dim), 536 type, offset); 537 } 538 539 /* Lastly, the name of the module is a static char array. */ 540 size_t namelen = strlen (decl->toPrettyChars ()) + 1; 541 layout_moduleinfo_field (make_array_type (Type::tchar, namelen), 542 type, offset); 543 544 size_t alignsize = MAX (TYPE_ALIGN_UNIT (type), 545 TYPE_ALIGN_UNIT (ptr_type_node)); 546 finish_aggregate_type (offset, alignsize, type); 547 548 return type; 549 } 550 551 /* Output the ModuleInfo for module DECL and register it with druntime. */ 552 553 static void 554 layout_moduleinfo (Module *decl) 555 { 556 ClassDeclarations aclasses; 557 FuncDeclaration *sgetmembers; 558 559 for (size_t i = 0; i < decl->members->dim; i++) 560 { 561 Dsymbol *member = (*decl->members)[i]; 562 member->addLocalClass (&aclasses); 563 } 564 565 size_t aimports_dim = decl->aimports.dim; 566 for (size_t i = 0; i < decl->aimports.dim; i++) 567 { 568 Module *mi = decl->aimports[i]; 569 if (!mi->needmoduleinfo) 570 aimports_dim--; 571 } 572 573 sgetmembers = decl->findGetMembers (); 574 575 size_t flags = 0; 576 if (decl->sctor) 577 flags |= MItlsctor; 578 if (decl->sdtor) 579 flags |= MItlsdtor; 580 if (decl->ssharedctor) 581 flags |= MIctor; 582 if (decl->sshareddtor) 583 flags |= MIdtor; 584 if (sgetmembers) 585 flags |= MIxgetMembers; 586 if (decl->sictor) 587 flags |= MIictor; 588 if (decl->stest) 589 flags |= MIunitTest; 590 if (aimports_dim) 591 flags |= MIimportedModules; 592 if (aclasses.dim) 593 flags |= MIlocalClasses; 594 if (!decl->needmoduleinfo) 595 flags |= MIstandalone; 596 597 flags |= MIname; 598 599 tree minfo = get_moduleinfo_decl (decl); 600 tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo)); 601 602 /* Put out the two named fields in a ModuleInfo decl: 603 uint flags; 604 uint index; */ 605 vec<constructor_elt, va_gc> *minit = NULL; 606 607 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 608 build_integer_cst (flags, d_uint_type)); 609 610 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 611 build_integer_cst (0, d_uint_type)); 612 613 /* Order of appearance, depending on flags: 614 void function() tlsctor; 615 void function() tlsdtor; 616 void* function() xgetMembers; 617 void function() ctor; 618 void function() dtor; 619 void function() ictor; 620 void function() unitTest; 621 ModuleInfo*[] importedModules; 622 TypeInfo_Class[] localClasses; 623 char[N] name; 624 */ 625 if (flags & MItlsctor) 626 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor)); 627 628 if (flags & MItlsdtor) 629 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor)); 630 631 if (flags & MIctor) 632 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 633 build_address (decl->ssharedctor)); 634 635 if (flags & MIdtor) 636 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 637 build_address (decl->sshareddtor)); 638 639 if (flags & MIxgetMembers) 640 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 641 build_address (get_symbol_decl (sgetmembers))); 642 643 if (flags & MIictor) 644 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor)); 645 646 if (flags & MIunitTest) 647 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest)); 648 649 if (flags & MIimportedModules) 650 { 651 vec<constructor_elt, va_gc> *elms = NULL; 652 tree satype = make_array_type (Type::tvoidptr, aimports_dim); 653 size_t idx = 0; 654 655 for (size_t i = 0; i < decl->aimports.dim; i++) 656 { 657 Module *mi = decl->aimports[i]; 658 if (mi->needmoduleinfo) 659 { 660 CONSTRUCTOR_APPEND_ELT (elms, size_int (idx), 661 build_address (get_moduleinfo_decl (mi))); 662 idx++; 663 } 664 } 665 666 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim)); 667 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 668 build_constructor (satype, elms)); 669 } 670 671 if (flags & MIlocalClasses) 672 { 673 vec<constructor_elt, va_gc> *elms = NULL; 674 tree satype = make_array_type (Type::tvoidptr, aclasses.dim); 675 676 for (size_t i = 0; i < aclasses.dim; i++) 677 { 678 ClassDeclaration *cd = aclasses[i]; 679 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), 680 build_address (get_classinfo_decl (cd))); 681 } 682 683 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.dim)); 684 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, 685 build_constructor (satype, elms)); 686 } 687 688 if (flags & MIname) 689 { 690 /* Put out module name as a 0-terminated C-string, to save bytes. */ 691 const char *name = decl->toPrettyChars (); 692 size_t namelen = strlen (name) + 1; 693 tree strtree = build_string (namelen, name); 694 TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen); 695 CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree); 696 } 697 698 TREE_TYPE (minfo) = type; 699 DECL_INITIAL (minfo) = build_struct_literal (type, minit); 700 d_finish_decl (minfo); 701 702 /* Register the module against druntime. */ 703 register_moduleinfo (decl, minfo); 704 } 705 706 /* Send the Module AST class DECL to GCC back-end. */ 707 708 void 709 build_module_tree (Module *decl) 710 { 711 /* There may be more than one module per object file, but should only 712 ever compile them one at a time. */ 713 assert (!current_moduleinfo && !current_module_decl); 714 715 module_info mi = module_info (); 716 module_info mitest = module_info (); 717 718 current_moduleinfo = &mi; 719 current_testing_module = &mitest; 720 current_module_decl = decl; 721 722 /* Layout module members. */ 723 if (decl->members) 724 { 725 for (size_t i = 0; i < decl->members->dim; i++) 726 { 727 Dsymbol *s = (*decl->members)[i]; 728 build_decl_tree (s); 729 } 730 } 731 732 /* For libphobos-internal use only. Generate a separate module info symbol 733 that references all compiled in unittests, this allows compiling library 734 modules and linking to libphobos without having run-time conflicts because 735 of two ModuleInfo records with the same name being present in two DSOs. */ 736 if (flag_building_libphobos_tests) 737 { 738 /* Associate the module info symbol with a mock module. */ 739 const char *name = concat (GDC_PREFIX ("modtest__"), 740 decl->ident->toChars (), NULL); 741 Module *tm = Module::create (decl->arg, Identifier::idPool (name), 0, 0); 742 Dsymbols members; 743 744 /* Setting parent puts module in the same package as the current, to 745 avoid any symbol conflicts. */ 746 tm->parent = decl->parent; 747 tm->needmoduleinfo = decl->needmoduleinfo; 748 tm->members = &members; 749 /* Register the current module as being imported by the mock module. 750 This informs run-time that there is a dependency between the two. */ 751 tm->aimports.push (decl); 752 753 if (mitest.ctors || mitest.ctorgates) 754 tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"), 755 mitest.ctors, mitest.ctorgates); 756 757 if (mitest.dtors) 758 tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"), 759 mitest.dtors, NULL); 760 761 if (mitest.sharedctors || mitest.sharedctorgates) 762 tm->ssharedctor 763 = build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"), 764 mitest.sharedctors, mitest.sharedctorgates); 765 766 if (mitest.shareddtors) 767 tm->sshareddtor 768 = build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"), 769 mitest.shareddtors, NULL); 770 771 if (mi.unitTests) 772 tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"), 773 mi.unitTests, NULL); 774 775 mi.unitTests = NULL; 776 layout_moduleinfo (tm); 777 } 778 779 /* Default behavior is to always generate module info because of templates. 780 Can be switched off for not compiling against runtime library. */ 781 if (global.params.useModuleInfo 782 && Module::moduleinfo != NULL 783 && decl->ident != Identifier::idPool ("__entrypoint")) 784 { 785 if (mi.ctors || mi.ctorgates) 786 decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"), 787 mi.ctors, mi.ctorgates); 788 789 if (mi.dtors) 790 decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"), 791 mi.dtors, NULL); 792 793 if (mi.sharedctors || mi.sharedctorgates) 794 decl->ssharedctor 795 = build_funcs_gates_fn (get_identifier ("*__modsharedctor"), 796 mi.sharedctors, mi.sharedctorgates); 797 798 if (mi.shareddtors) 799 decl->sshareddtor 800 = build_funcs_gates_fn (get_identifier ("*__modshareddtor"), 801 mi.shareddtors, NULL); 802 803 if (mi.unitTests) 804 decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"), 805 mi.unitTests, NULL); 806 807 layout_moduleinfo (decl); 808 } 809 810 current_moduleinfo = NULL; 811 current_testing_module = NULL; 812 current_module_decl = NULL; 813 } 814 815 /* Returns the current function or module context for the purpose 816 of imported_module_or_decl. */ 817 818 tree 819 d_module_context (void) 820 { 821 if (cfun != NULL) 822 return current_function_decl; 823 824 gcc_assert (current_module_decl != NULL); 825 return build_import_decl (current_module_decl); 826 } 827 828 /* Maybe record declaration D against our module information structure. */ 829 830 void 831 register_module_decl (Declaration *d) 832 { 833 FuncDeclaration *fd = d->isFuncDeclaration (); 834 if (fd != NULL) 835 { 836 tree decl = get_symbol_decl (fd); 837 838 /* Any module constructors or destructors that are only present when 839 compiling in unittests are kept track of separately so they are 840 not omitted when compiling with -fbuilding-libphobos-tests. */ 841 module_info *minfo; 842 if (flag_building_libphobos_tests && !fd->isUnitTestDeclaration () 843 && DECL_IN_UNITTEST_CONDITION_P (decl)) 844 minfo = current_testing_module; 845 else 846 minfo = current_moduleinfo; 847 848 gcc_assert (minfo != NULL); 849 850 /* If a static constructor, push into the current ModuleInfo. 851 Checks for `shared' first because it derives from the non-shared 852 constructor type in the front-end. */ 853 if (fd->isSharedStaticCtorDeclaration ()) 854 vec_safe_push (minfo->sharedctors, decl); 855 else if (fd->isStaticCtorDeclaration ()) 856 vec_safe_push (minfo->ctors, decl); 857 858 /* If a static destructor, do same as with constructors, but also 859 increment the destructor's vgate at construction time. */ 860 if (fd->isSharedStaticDtorDeclaration ()) 861 { 862 VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate; 863 if (vgate != NULL) 864 { 865 tree gate = get_symbol_decl (vgate); 866 vec_safe_push (minfo->sharedctorgates, gate); 867 } 868 vec_safe_insert (minfo->shareddtors, 0, decl); 869 } 870 else if (fd->isStaticDtorDeclaration ()) 871 { 872 VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate; 873 if (vgate != NULL) 874 { 875 tree gate = get_symbol_decl (vgate); 876 vec_safe_push (minfo->ctorgates, gate); 877 } 878 vec_safe_insert (minfo->dtors, 0, decl); 879 } 880 881 /* If a unittest function. */ 882 if (fd->isUnitTestDeclaration ()) 883 vec_safe_push (minfo->unitTests, decl); 884 } 885 } 886 887 /* Wrapup all global declarations and start the final compilation. */ 888 889 void 890 d_finish_compilation (tree *vec, int len) 891 { 892 /* Complete all generated thunks. */ 893 symtab->process_same_body_aliases (); 894 895 /* Process all file scopes in this compilation, and the external_scope, 896 through wrapup_global_declarations. */ 897 for (int i = 0; i < len; i++) 898 { 899 tree decl = vec[i]; 900 wrapup_global_declarations (&decl, 1); 901 } 902 903 /* If the target does not directly support static constructors, 904 static_ctor_list contains a list of all static constructors defined 905 so far. This routine will create a function to call all of those 906 and is picked up by collect2. */ 907 if (static_ctor_list) 908 { 909 tree decl = build_funcs_gates_fn (get_file_function_name ("I"), 910 static_ctor_list, NULL); 911 DECL_STATIC_CONSTRUCTOR (decl) = 1; 912 decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY); 913 } 914 915 if (static_dtor_list) 916 { 917 tree decl = build_funcs_gates_fn (get_file_function_name ("D"), 918 static_dtor_list, NULL); 919 DECL_STATIC_DESTRUCTOR (decl) = 1; 920 decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY); 921 } 922 } 923 924 925 #include "gt-d-modules.h" 926