/* modules.cc -- D module initialization and termination.
   Copyright (C) 2013-2021 Free Software Foundation, Inc.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"

#include "dmd/declaration.h"
#include "dmd/identifier.h"
#include "dmd/module.h"

#include "tree.h"
#include "diagnostic.h"
#include "fold-const.h"
#include "tm.h"
#include "function.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "toplev.h"
#include "target.h"
#include "common/common-target.h"
#include "stringpool.h"

#include "d-tree.h"
#include "d-target.h"


/* D generates module information to inform the runtime library which modules
   need some kind of special handling.  All `static this()', `static ~this()',
   and `unittest' functions for a given module are aggregated into a single
   function - one for each kind - and a pointer to that function is inserted
   into the ModuleInfo instance for that module.

   Module information for a particular module is indicated with an ABI defined
   structure derived from ModuleInfo.  ModuleInfo is a variably sized struct
   with two fixed base fields.  The first field `flags' determines what
   information is packed immediately after the record type.

   Like TypeInfo, the runtime library provides the definitions of the ModuleInfo
   structure, as well as accessors for the variadic fields.  So we only define
   layout compatible POD_structs for ModuleInfo.  */

/* The internally represented ModuleInfo and CompilerDSO types.  */
static tree moduleinfo_type;
static tree compiler_dso_type;
static tree dso_registry_fn;

/* The DSO slot for use by the druntime implementation.  */
static tree dso_slot_node;

/* For registering and deregistering DSOs with druntime, we have one global
   constructor and destructor per object that calls _d_dso_registry with the
   respective DSO record.  To ensure that this is only done once, a
   `dso_initialized' variable is introduced to guard repeated calls.  */
static tree dso_initialized_node;

/* The beginning and end of the `minfo' section.  */
static tree start_minfo_node;
static tree stop_minfo_node;

/* Record information about module initialization, termination,
   unit testing, and thread local storage in the compilation.  */

struct module_info
{
  vec <tree, va_gc> *ctors;
  vec <tree, va_gc> *dtors;
  vec <tree, va_gc> *ctorgates;

  vec <tree, va_gc> *sharedctors;
  vec <tree, va_gc> *shareddtors;
  vec <tree, va_gc> *sharedctorgates;

  vec <tree, va_gc> *unitTests;
};

/* These must match the values in libdruntime/object_.d.  */

enum module_info_flags
{
  MIctorstart	    = 0x1,
  MIctordone	    = 0x2,
  MIstandalone	    = 0x4,
  MItlsctor	    = 0x8,
  MItlsdtor	    = 0x10,
  MIctor	    = 0x20,
  MIdtor	    = 0x40,
  MIxgetMembers	    = 0x80,
  MIictor	    = 0x100,
  MIunitTest	    = 0x200,
  MIimportedModules = 0x400,
  MIlocalClasses    = 0x800,
  MIname	    = 0x1000
};

/* The ModuleInfo information structure for the module currently being compiled.
   Assuming that only ever process one at a time.  */

static module_info *current_moduleinfo;

/* When compiling with -fbuilding-libphobos-tests, this contains information
   about the module that gets compiled in only when unittests are enabled.  */

static module_info *current_testing_module;

/* The declaration of the current module being compiled.  */

static Module *current_module_decl;

/* Returns an internal function identified by IDENT.  This is used
   by both module initialization and dso handlers.  */

static FuncDeclaration *
get_internal_fn (tree ident, const Prot &prot)
{
  Module *mod = current_module_decl;
  const char *name = IDENTIFIER_POINTER (ident);

  if (!mod)
    mod = Module::rootModule;

  if (name[0] == '*')
    {
      tree s = mangle_internal_decl (mod, name + 1, "FZv");
      name = IDENTIFIER_POINTER (s);
    }

  FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid,
						   Identifier::idPool (name));
  fd->generated = true;
  fd->loc = Loc (mod->srcfile->toChars (), 1, 0);
  fd->parent = mod;
  fd->protection = prot;
  fd->semanticRun = PASSsemantic3done;

  return fd;
}

/* Generate an internal function identified by IDENT.
   The function body to add is in EXPR.  */

static tree
build_internal_fn (tree ident, tree expr)
{
  FuncDeclaration *fd = get_internal_fn (ident, Prot (Prot::private_));
  tree decl = get_symbol_decl (fd);

  tree old_context = start_function (fd);
  rest_of_decl_compilation (decl, 1, 0);
  add_stmt (expr);
  finish_function (old_context);

  /* D static ctors, static dtors, unittests, and the ModuleInfo
     chain function are always private.  */
  TREE_PUBLIC (decl) = 0;
  TREE_USED (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;

  return decl;
}

/* Build and emit a function identified by IDENT that increments (in order)
   all variables in GATES, then calls the list of functions in FUNCTIONS.  */

static tree
build_funcs_gates_fn (tree ident, vec <tree, va_gc> *functions,
		      vec <tree, va_gc> *gates)
{
  tree expr_list = NULL_TREE;

  /* Increment gates first.  */
  for (size_t i = 0; i < vec_safe_length (gates); i++)
    {
      tree decl = (*gates)[i];
      tree value = build2 (PLUS_EXPR, TREE_TYPE (decl),
			   decl, integer_one_node);
      tree var_expr = modify_expr (decl, value);
      expr_list = compound_expr (expr_list, var_expr);
    }

  /* Call Functions.  */
  for (size_t i = 0; i < vec_safe_length (functions); i++)
    {
      tree decl = (*functions)[i];
      tree call_expr = build_call_expr (decl, 0);
      expr_list = compound_expr (expr_list, call_expr);
    }

  if (expr_list)
    return build_internal_fn (ident, expr_list);

  return NULL_TREE;
}

/* Return the type for ModuleInfo, create it if it doesn't already exist.  */

static tree
get_moduleinfo_type (void)
{
  if (moduleinfo_type)
    return moduleinfo_type;

  /* Layout of ModuleInfo is:
	uint flags;
	uint index;  */
  tree fields = create_field_decl (d_uint_type, NULL, 1, 1);
  DECL_CHAIN (fields) = create_field_decl (d_uint_type, NULL, 1, 1);

  moduleinfo_type = make_node (RECORD_TYPE);
  finish_builtin_struct (moduleinfo_type, "ModuleInfo", fields, NULL_TREE);

  return moduleinfo_type;
}

/* Get the VAR_DECL of the ModuleInfo for DECL.  If this does not yet exist,
   create it.  The ModuleInfo decl is used to keep track of constructors,
   destructors, unittests, members, classes, and imports for the given module.
   This is used by the D runtime for module initialization and termination.  */

static tree
get_moduleinfo_decl (Module *decl)
{
  if (decl->csym)
    return decl->csym;

  tree ident = mangle_internal_decl (decl, "__ModuleInfo", "Z");
  tree type = get_moduleinfo_type ();

  decl->csym = declare_extern_var (ident, type);
  DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);

  DECL_CONTEXT (decl->csym) = build_import_decl (decl);
  /* Not readonly, moduleinit depends on this.  */
  TREE_READONLY (decl->csym) = 0;

  return decl->csym;
}

/* Return the type for CompilerDSOData, create it if it doesn't exist.  */

static tree
get_compiler_dso_type (void)
{
  if (compiler_dso_type)
    return compiler_dso_type;

  /* Layout of CompilerDSOData is:
	size_t version;
	void** slot;
	ModuleInfo** _minfo_beg;
	ModuleInfo** _minfo_end;
	FuncTable* _deh_beg;
	FuncTable* _deh_end;

     Note, finish_builtin_struct() expects these fields in reverse order.  */
  tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);
  tree field = create_field_decl (ptr_type_node, NULL, 1, 1);
  DECL_CHAIN (field) = fields;
  fields = field;

  field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),
			     NULL, 1, 1);
  DECL_CHAIN (field) = fields;
  fields = field;
  field = create_field_decl (build_pointer_type (get_moduleinfo_type ()),
			     NULL, 1, 1);
  DECL_CHAIN (field) = fields;
  fields = field;

  field = create_field_decl (build_pointer_type (ptr_type_node), NULL, 1, 1);
  DECL_CHAIN (field) = fields;
  fields = field;

  field = create_field_decl (size_type_node, NULL, 1, 1);
  DECL_CHAIN (field) = fields;
  fields = field;

  compiler_dso_type = make_node (RECORD_TYPE);
  finish_builtin_struct (compiler_dso_type, "CompilerDSOData",
			 fields, NULL_TREE);

  return compiler_dso_type;
}

/* Returns the _d_dso_registry FUNCTION_DECL.  */

static tree
get_dso_registry_fn (void)
{
  if (dso_registry_fn)
    return dso_registry_fn;

  tree dso_type = get_compiler_dso_type ();
  tree fntype = build_function_type_list (void_type_node,
					  build_pointer_type (dso_type),
					  NULL_TREE);
  dso_registry_fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
				get_identifier ("_d_dso_registry"), fntype);
  TREE_PUBLIC (dso_registry_fn) = 1;
  DECL_EXTERNAL (dso_registry_fn) = 1;

  return dso_registry_fn;
}

/* Depending on CTOR_P, builds and emits eiter a constructor or destructor
   calling _d_dso_registry if `dso_initialized' is `false' in a constructor
   or `true' in a destructor.  */

static tree
build_dso_cdtor_fn (bool ctor_p)
{
  const char *name = ctor_p ? GDC_PREFIX ("dso_ctor") : GDC_PREFIX ("dso_dtor");
  tree condition = ctor_p ? boolean_true_node : boolean_false_node;

  /* Declaration of dso_ctor/dso_dtor is:

     extern(C) void dso_{c,d}tor (void)
     {
	if (dso_initialized != condition)
	{
	    dso_initialized = condition;
	    CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};
	    _d_dso_registry (&dso);
	}
    }
   */
  FuncDeclaration *fd = get_internal_fn (get_identifier (name),
					 Prot (Prot::public_));
  tree decl = get_symbol_decl (fd);

  TREE_PUBLIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;

  /* Start laying out the body.  */
  tree old_context = start_function (fd);
  rest_of_decl_compilation (decl, 1, 0);

  /* if (dso_initialized != condition).  */
  tree if_cond = build_boolop (NE_EXPR, dso_initialized_node, condition);

  /* dso_initialized = condition;  */
  tree expr_list = modify_expr (dso_initialized_node, condition);

  /* CompilerDSOData dso = {1, &dsoSlot, &__start_minfo, &__stop_minfo};  */
  tree dso_type = get_compiler_dso_type ();
  tree dso = build_local_temp (dso_type);

  vec <constructor_elt, va_gc> *ve = NULL;
  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_integer_cst (1, size_type_node));
  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (dso_slot_node));
  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (start_minfo_node));
  CONSTRUCTOR_APPEND_ELT (ve, NULL_TREE, build_address (stop_minfo_node));

  tree assign_expr = modify_expr (dso, build_struct_literal (dso_type, ve));
  expr_list = compound_expr (expr_list, assign_expr);

  /* _d_dso_registry (&dso);  */
  tree call_expr = build_call_expr (get_dso_registry_fn (), 1,
				    build_address (dso));
  expr_list = compound_expr (expr_list, call_expr);

  add_stmt (build_vcondition (if_cond, expr_list, void_node));
  finish_function (old_context);

  return decl;
}

/* Build a variable used in the dso_registry code identified by NAME,
   and data type TYPE.  The variable always has VISIBILITY_HIDDEN and
   TREE_PUBLIC flags set.  */

static tree
build_dso_registry_var (const char * name, tree type)
{
  tree var = declare_extern_var (get_identifier (name), type);
  DECL_VISIBILITY (var) = VISIBILITY_HIDDEN;
  DECL_VISIBILITY_SPECIFIED (var) = 1;
  return var;
}

/* Place a reference to the ModuleInfo symbol MINFO for DECL into the
   `minfo' section.  Then create the global ctors/dtors to call the
   _d_dso_registry function if necessary.  */

static void
register_moduleinfo (Module *decl, tree minfo)
{
  /* No defined minfo section for target.  */
  if (targetdm.d_minfo_section == NULL)
    return;

  if (!targetm_common.have_named_sections)
    sorry ("%<-fmoduleinfo%> is not supported on this target");

  /* Build the ModuleInfo reference, this is done once for every Module.  */
  tree ident = mangle_internal_decl (decl, "__moduleRef", "Z");
  tree mref = declare_extern_var (ident, ptr_type_node);

  /* Build the initializer and emit.  Do not start section with a `.' character
     so that the linker will provide a __start_ and __stop_ symbol to indicate
     the start and end address of the section respectively.
     https://sourceware.org/binutils/docs-2.26/ld/Orphan-Sections.html.  */
  DECL_INITIAL (mref) = build_address (minfo);
  DECL_EXTERNAL (mref) = 0;
  DECL_PRESERVE_P (mref) = 1;

  set_decl_section_name (mref, targetdm.d_minfo_section);
  symtab_node::get (mref)->implicit_section = true;
  d_pushdecl (mref);
  rest_of_decl_compilation (mref, 1, 0);

  /* Only for the first D module being emitted do we need to generate a static
     constructor and destructor for.  These are only required once per shared
     library, so it's safe to emit them only once per object file.  */
  static bool first_module = true;
  if (!first_module)
    return;

  start_minfo_node = build_dso_registry_var (targetdm.d_minfo_start_name,
					     ptr_type_node);
  rest_of_decl_compilation (start_minfo_node, 1, 0);

  stop_minfo_node = build_dso_registry_var (targetdm.d_minfo_end_name,
					    ptr_type_node);
  rest_of_decl_compilation (stop_minfo_node, 1, 0);

  /* Declare dso_slot and dso_initialized.  */
  dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"),
					  ptr_type_node);
  d_finish_decl (dso_slot_node);

  dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
						 boolean_type_node);
  d_finish_decl (dso_initialized_node);

  /* Declare dso_ctor() and dso_dtor().  */
  tree dso_ctor = build_dso_cdtor_fn (true);
  DECL_STATIC_CONSTRUCTOR (dso_ctor) = 1;
  decl_init_priority_insert (dso_ctor, DEFAULT_INIT_PRIORITY);

  tree dso_dtor = build_dso_cdtor_fn (false);
  DECL_STATIC_DESTRUCTOR (dso_dtor) = 1;
  decl_fini_priority_insert (dso_dtor, DEFAULT_INIT_PRIORITY);

  first_module = false;
}

/* Convenience function for layout_moduleinfo_fields.  Adds a field of TYPE to
   the moduleinfo record at OFFSET, incrementing the offset to the next field
   position.  No alignment is taken into account, all fields are packed.  */

static void
layout_moduleinfo_field (tree type, tree rec_type, HOST_WIDE_INT &offset)
{
  tree field = create_field_decl (type, NULL, 1, 1);
  insert_aggregate_field (rec_type, field, offset);
  offset += int_size_in_bytes (type);
}

/* Layout fields that immediately come after the moduleinfo TYPE for DECL.
   Data relating to the module is packed into the type on an as-needed
   basis, this is done to keep its size to a minimum.  */

static tree
layout_moduleinfo_fields (Module *decl, tree type)
{
  HOST_WIDE_INT offset = int_size_in_bytes (type);
  type = copy_aggregate_type (type);

  /* First fields added are all the function pointers.  */
  if (decl->sctor)
    layout_moduleinfo_field (ptr_type_node, type, offset);

  if (decl->sdtor)
    layout_moduleinfo_field (ptr_type_node, type, offset);

  if (decl->ssharedctor)
    layout_moduleinfo_field (ptr_type_node, type, offset);

  if (decl->sshareddtor)
    layout_moduleinfo_field (ptr_type_node, type, offset);

  if (decl->findGetMembers ())
    layout_moduleinfo_field (ptr_type_node, type, offset);

  if (decl->sictor)
    layout_moduleinfo_field (ptr_type_node, type, offset);

  if (decl->stest)
    layout_moduleinfo_field (ptr_type_node, type, offset);

  /* Array of module imports is laid out as a length field, followed by
     a static array of ModuleInfo pointers.  */
  size_t aimports_dim = decl->aimports.length;
  for (size_t i = 0; i < decl->aimports.length; i++)
    {
      Module *mi = decl->aimports[i];
      if (!mi->needmoduleinfo)
	aimports_dim--;
    }

  if (aimports_dim)
    {
      layout_moduleinfo_field (size_type_node, type, offset);
      layout_moduleinfo_field (make_array_type (Type::tvoidptr, aimports_dim),
			       type, offset);
    }

  /* Array of local ClassInfo decls are laid out in the same way.  */
  ClassDeclarations aclasses;
  for (size_t i = 0; i < decl->members->length; i++)
    {
      Dsymbol *member = (*decl->members)[i];
      member->addLocalClass (&aclasses);
    }

  if (aclasses.length)
    {
      layout_moduleinfo_field (size_type_node, type, offset);
      layout_moduleinfo_field (make_array_type (Type::tvoidptr,
						aclasses.length),
			       type, offset);
    }

  /* Lastly, the name of the module is a static char array.  */
  size_t namelen = strlen (decl->toPrettyChars ()) + 1;
  layout_moduleinfo_field (make_array_type (Type::tchar, namelen),
			   type, offset);

  size_t alignsize = MAX (TYPE_ALIGN_UNIT (type),
			  TYPE_ALIGN_UNIT (ptr_type_node));
  finish_aggregate_type (offset, alignsize, type);

  return type;
}

/* Output the ModuleInfo for module DECL and register it with druntime.  */

static void
layout_moduleinfo (Module *decl)
{
  ClassDeclarations aclasses;
  FuncDeclaration *sgetmembers;

  for (size_t i = 0; i < decl->members->length; i++)
    {
      Dsymbol *member = (*decl->members)[i];
      member->addLocalClass (&aclasses);
    }

  size_t aimports_dim = decl->aimports.length;
  for (size_t i = 0; i < decl->aimports.length; i++)
    {
      Module *mi = decl->aimports[i];
      if (!mi->needmoduleinfo)
	aimports_dim--;
    }

  sgetmembers = decl->findGetMembers ();

  size_t flags = 0;
  if (decl->sctor)
    flags |= MItlsctor;
  if (decl->sdtor)
    flags |= MItlsdtor;
  if (decl->ssharedctor)
    flags |= MIctor;
  if (decl->sshareddtor)
    flags |= MIdtor;
  if (sgetmembers)
    flags |= MIxgetMembers;
  if (decl->sictor)
    flags |= MIictor;
  if (decl->stest)
    flags |= MIunitTest;
  if (aimports_dim)
    flags |= MIimportedModules;
  if (aclasses.length)
    flags |= MIlocalClasses;
  if (!decl->needmoduleinfo)
    flags |= MIstandalone;

  flags |= MIname;

  tree minfo = get_moduleinfo_decl (decl);
  tree type = layout_moduleinfo_fields (decl, TREE_TYPE (minfo));

  /* Put out the two named fields in a ModuleInfo decl:
	uint flags;
	uint index;  */
  vec <constructor_elt, va_gc> *minit = NULL;

  CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			  build_integer_cst (flags, d_uint_type));

  CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			  build_integer_cst (0, d_uint_type));

  /* Order of appearance, depending on flags:
	void function() tlsctor;
	void function() tlsdtor;
	void* function() xgetMembers;
	void function() ctor;
	void function() dtor;
	void function() ictor;
	void function() unitTest;
	ModuleInfo*[] importedModules;
	TypeInfo_Class[] localClasses;
	char[N] name;
   */
  if (flags & MItlsctor)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sctor));

  if (flags & MItlsdtor)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sdtor));

  if (flags & MIctor)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			    build_address (decl->ssharedctor));

  if (flags & MIdtor)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			    build_address (decl->sshareddtor));

  if (flags & MIxgetMembers)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			    build_address (get_symbol_decl (sgetmembers)));

  if (flags & MIictor)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->sictor));

  if (flags & MIunitTest)
    CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, build_address (decl->stest));

  if (flags & MIimportedModules)
    {
      vec <constructor_elt, va_gc> *elms = NULL;
      tree satype = make_array_type (Type::tvoidptr, aimports_dim);
      size_t idx = 0;

      for (size_t i = 0; i < decl->aimports.length; i++)
	{
	  Module *mi = decl->aimports[i];
	  if (mi->needmoduleinfo)
	    {
	      CONSTRUCTOR_APPEND_ELT (elms, size_int (idx),
				      build_address (get_moduleinfo_decl (mi)));
	      idx++;
	    }
	}

      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));
      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			      build_constructor (satype, elms));
    }

  if (flags & MIlocalClasses)
    {
      vec <constructor_elt, va_gc> *elms = NULL;
      tree satype = make_array_type (Type::tvoidptr, aclasses.length);

      for (size_t i = 0; i < aclasses.length; i++)
	{
	  ClassDeclaration *cd = aclasses[i];
	  CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
				  build_address (get_classinfo_decl (cd)));
	}

      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.length));
      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
			      build_constructor (satype, elms));
    }

  if (flags & MIname)
    {
      /* Put out module name as a 0-terminated C-string, to save bytes.  */
      const char *name = decl->toPrettyChars ();
      size_t namelen = strlen (name) + 1;
      tree strtree = build_string (namelen, name);
      TREE_TYPE (strtree) = make_array_type (Type::tchar, namelen);
      CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, strtree);
    }

  TREE_TYPE (minfo) = type;
  DECL_INITIAL (minfo) = build_struct_literal (type, minit);
  d_finish_decl (minfo);

  /* Register the module against druntime.  */
  register_moduleinfo (decl, minfo);
}

/* Send the Module AST class DECL to GCC back-end.  */

void
build_module_tree (Module *decl)
{
  /* There may be more than one module per object file, but should only
     ever compile them one at a time.  */
  assert (!current_moduleinfo && !current_module_decl);

  module_info mi = module_info ();
  module_info mitest = module_info ();

  current_moduleinfo = &mi;
  current_testing_module = &mitest;
  current_module_decl = decl;

  /* Layout module members.  */
  if (decl->members)
    {
      for (size_t i = 0; i < decl->members->length; i++)
	{
	  Dsymbol *s = (*decl->members)[i];
	  build_decl_tree (s);
	}
    }

  /* For libphobos-internal use only.  Generate a separate module info symbol
     that references all compiled in unittests, this allows compiling library
     modules and linking to libphobos without having run-time conflicts because
     of two ModuleInfo records with the same name being present in two DSOs.  */
  if (flag_building_libphobos_tests)
    {
      /* Associate the module info symbol with a mock module.  */
      const char *name = concat (GDC_PREFIX ("modtest__"),
				 decl->ident->toChars (), NULL);
      Module *tm = Module::create (decl->arg, Identifier::idPool (name), 0, 0);
      Dsymbols members;

      /* Setting parent puts module in the same package as the current, to
	 avoid any symbol conflicts.  */
      tm->parent = decl->parent;
      tm->needmoduleinfo = decl->needmoduleinfo;
      tm->members = &members;
      /* Register the current module as being imported by the mock module.
	 This informs run-time that there is a dependency between the two.  */
      tm->aimports.push (decl);

      if (mitest.ctors || mitest.ctorgates)
	tm->sctor = build_funcs_gates_fn (get_identifier ("*__modtestctor"),
					  mitest.ctors, mitest.ctorgates);

      if (mitest.dtors)
	tm->sdtor = build_funcs_gates_fn (get_identifier ("*__modtestdtor"),
					  mitest.dtors, NULL);

      if (mitest.sharedctors || mitest.sharedctorgates)
	tm->ssharedctor
	  = build_funcs_gates_fn (get_identifier ("*__modtestsharedctor"),
				  mitest.sharedctors, mitest.sharedctorgates);

      if (mitest.shareddtors)
	tm->sshareddtor
	  = build_funcs_gates_fn (get_identifier ("*__modtestshareddtor"),
				  mitest.shareddtors, NULL);

      if (mi.unitTests)
	tm->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
					  mi.unitTests, NULL);

      mi.unitTests = NULL;
      layout_moduleinfo (tm);
    }

  /* Default behavior is to always generate module info because of templates.
     Can be switched off for not compiling against runtime library.  */
  if (global.params.useModuleInfo
      && Module::moduleinfo != NULL
      && decl->ident != Identifier::idPool ("__entrypoint"))
    {
      if (mi.ctors || mi.ctorgates)
	decl->sctor = build_funcs_gates_fn (get_identifier ("*__modctor"),
					    mi.ctors, mi.ctorgates);

      if (mi.dtors)
	decl->sdtor = build_funcs_gates_fn (get_identifier ("*__moddtor"),
					    mi.dtors, NULL);

      if (mi.sharedctors || mi.sharedctorgates)
	decl->ssharedctor
	  = build_funcs_gates_fn (get_identifier ("*__modsharedctor"),
				  mi.sharedctors, mi.sharedctorgates);

      if (mi.shareddtors)
	decl->sshareddtor
	  = build_funcs_gates_fn (get_identifier ("*__modshareddtor"),
				  mi.shareddtors, NULL);

      if (mi.unitTests)
	decl->stest = build_funcs_gates_fn (get_identifier ("*__modtest"),
					    mi.unitTests, NULL);

      layout_moduleinfo (decl);
    }

  current_moduleinfo = NULL;
  current_testing_module = NULL;
  current_module_decl = NULL;
}

/* Returns the current function or module context for the purpose
   of imported_module_or_decl.  */

tree
d_module_context (void)
{
  if (cfun != NULL)
    return current_function_decl;

  gcc_assert (current_module_decl != NULL);
  return build_import_decl (current_module_decl);
}

/* Maybe record declaration D against our module information structure.  */

void
register_module_decl (Declaration *d)
{
  FuncDeclaration *fd = d->isFuncDeclaration ();
  if (fd != NULL)
    {
      tree decl = get_symbol_decl (fd);

      /* Any module constructors or destructors that are only present when
	 compiling in unittests are kept track of separately so they are
	 not omitted when compiling with -fbuilding-libphobos-tests.  */
      module_info *minfo;
      if (flag_building_libphobos_tests && !fd->isUnitTestDeclaration ()
	  && DECL_IN_UNITTEST_CONDITION_P (decl))
	minfo = current_testing_module;
      else
	minfo = current_moduleinfo;

      gcc_assert (minfo != NULL);

      /* If a static constructor, push into the current ModuleInfo.
	 Checks for `shared' first because it derives from the non-shared
	 constructor type in the front-end.  */
      if (fd->isSharedStaticCtorDeclaration ())
	vec_safe_push (minfo->sharedctors, decl);
      else if (fd->isStaticCtorDeclaration ())
	vec_safe_push (minfo->ctors, decl);

      /* If a static destructor, do same as with constructors, but also
	 increment the destructor's vgate at construction time.  */
      if (fd->isSharedStaticDtorDeclaration ())
	{
	  VarDeclaration *vgate = ((SharedStaticDtorDeclaration *) fd)->vgate;
	  if (vgate != NULL)
	    {
	      tree gate = get_symbol_decl (vgate);
	      vec_safe_push (minfo->sharedctorgates, gate);
	    }
	  vec_safe_insert (minfo->shareddtors, 0, decl);
	}
      else if (fd->isStaticDtorDeclaration ())
	{
	  VarDeclaration *vgate = ((StaticDtorDeclaration *) fd)->vgate;
	  if (vgate != NULL)
	    {
	      tree gate = get_symbol_decl (vgate);
	      vec_safe_push (minfo->ctorgates, gate);
	    }
	  vec_safe_insert (minfo->dtors, 0, decl);
	}

      /* If a unittest function.  */
      if (fd->isUnitTestDeclaration ())
	vec_safe_push (minfo->unitTests, decl);
    }
}

/* Wrapup all global declarations and start the final compilation.  */

void
d_finish_compilation (tree *vec, int len)
{
  /* Complete all generated thunks.  */
  symtab->process_same_body_aliases ();

  /* Process all file scopes in this compilation, and the external_scope,
     through wrapup_global_declarations.  */
  for (int i = 0; i < len; i++)
    {
      tree decl = vec[i];
      wrapup_global_declarations (&decl, 1);
    }
}
