/* 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 GTY(()) 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;

/* Static constructors and destructors (not D `static this').  */

static GTY(()) vec <tree, va_gc> *static_ctor_list;
static GTY(()) vec <tree, va_gc> *static_dtor_list;

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

static FuncDeclaration *
get_internal_fn (tree ident)
{
  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->loc = Loc (mod->srcfile->toChars (), 1, 0);
  fd->parent = mod;
  fd->protection.kind = Prot::private_;
  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);
  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));
  tree decl = get_symbol_decl (fd);

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

  d_comdat_linkage (decl);

  /* 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);
  DECL_EXTERNAL (dso_slot_node) = 0;
  d_comdat_linkage (dso_slot_node);
  rest_of_decl_compilation (dso_slot_node, 1, 0);

  dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
						 boolean_type_node);
  DECL_EXTERNAL (dso_initialized_node) = 0;
  d_comdat_linkage (dso_initialized_node);
  rest_of_decl_compilation (dso_initialized_node, 1, 0);

  /* Declare dso_ctor() and dso_dtor().  */
  tree dso_ctor = build_dso_cdtor_fn (true);
  vec_safe_push (static_ctor_list, dso_ctor);

  tree dso_dtor = build_dso_cdtor_fn (false);
  vec_safe_push (static_dtor_list, dso_dtor);

  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);
    }

  /* If the target does not directly support static constructors,
     static_ctor_list contains a list of all static constructors defined
     so far.  This routine will create a function to call all of those
     and is picked up by collect2.  */
  if (static_ctor_list)
    {
      tree decl = build_funcs_gates_fn (get_file_function_name ("I"),
					static_ctor_list, NULL);
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
      decl_init_priority_insert (decl, DEFAULT_INIT_PRIORITY);
    }

  if (static_dtor_list)
    {
      tree decl = build_funcs_gates_fn (get_file_function_name ("D"),
					static_dtor_list, NULL);
      DECL_STATIC_DESTRUCTOR (decl) = 1;
      decl_fini_priority_insert (decl, DEFAULT_INIT_PRIORITY);
    }
}


#include "gt-d-modules.h"
