Home | History | Annotate | Line # | Download | only in d
      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