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