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