/* typeinfo.cc -- D runtime type identification.
   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/aggregate.h"
#include "dmd/enum.h"
#include "dmd/errors.h"
#include "dmd/expression.h"
#include "dmd/globals.h"
#include "dmd/identifier.h"
#include "dmd/module.h"
#include "dmd/mtype.h"
#include "dmd/scope.h"
#include "dmd/template.h"
#include "dmd/target.h"

#include "tree.h"
#include "fold-const.h"
#include "diagnostic.h"
#include "stringpool.h"
#include "toplev.h"
#include "stor-layout.h"

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


/* D returns type information to the user as TypeInfo class objects, and can
   be retrieved for any type using `typeid()'.  We also use type information
   to implement many runtime library helpers, including `new', `delete', most
   dynamic array operations, and all associative array operations.

   Type information for a particular type is indicated with an ABI defined
   structure derived from TypeInfo.  This would all be very straight forward,
   but for the fact that the runtime library provides the definitions of the
   TypeInfo structure and the ABI defined derived classes in `object.d', as
   well as having specific implementations of TypeInfo for built-in types
   in `rt/typeinfo`.  We cannot build declarations of these directly in the
   compiler, but we need to layout objects of their type.

   To get around this, we define layout compatible POD-structs and generate the
   appropriate initializations for them.  When we have to provide a TypeInfo to
   the user, we cast the internal compiler type to TypeInfo.

   It is only required that TypeInfo has a definition in `object.d'.  It could
   happen that we are generating a type information for a TypeInfo object that
   has no declaration.  We however only need the addresses of such incomplete
   TypeInfo objects for static initialization.  */

enum tinfo_kind
{
  TK_TYPEINFO_TYPE,		/* object.TypeInfo  */
  TK_CLASSINFO_TYPE,		/* object.TypeInfo_Class  */
  TK_INTERFACE_TYPE,		/* object.TypeInfo_Interface  */
  TK_STRUCT_TYPE,		/* object.TypeInfo_Struct  */
  TK_POINTER_TYPE,		/* object.TypeInfo_Pointer  */
  TK_ARRAY_TYPE,		/* object.TypeInfo_Array  */
  TK_STATICARRAY_TYPE,		/* object.TypeInfo_StaticArray  */
  TK_ASSOCIATIVEARRAY_TYPE,	/* object.TypeInfo_AssociativeArray  */
  TK_VECTOR_TYPE,		/* object.TypeInfo_Vector  */
  TK_ENUMERAL_TYPE,		/* object.TypeInfo_Enum  */
  TK_FUNCTION_TYPE,		/* object.TypeInfo_Function  */
  TK_DELEGATE_TYPE,		/* object.TypeInfo_Delegate  */
  TK_TYPELIST_TYPE,		/* object.TypeInfo_Tuple  */
  TK_CONST_TYPE,		/* object.TypeInfo_Const  */
  TK_IMMUTABLE_TYPE,		/* object.TypeInfo_Invariant  */
  TK_SHARED_TYPE,		/* object.TypeInfo_Shared  */
  TK_INOUT_TYPE,		/* object.TypeInfo_Inout  */
  TK_CPPTI_TYPE,		/* object.__cpp_type_info_ptr  */
  TK_END
};

/* An array of all internal TypeInfo derived types we need.
   The TypeInfo and ClassInfo types are created early, the
   remainder are generated as needed.  */

static GTY(()) tree tinfo_types[TK_END];

/* Return the kind of TypeInfo used to describe TYPE.  */

static tinfo_kind
get_typeinfo_kind (Type *type)
{
  /* Check head shared/const modifiers first.  */
  if (type->isShared ())
    return TK_SHARED_TYPE;
  else if (type->isConst ())
    return TK_CONST_TYPE;
  else if (type->isImmutable ())
    return TK_IMMUTABLE_TYPE;
  else if (type->isWild ())
    return TK_INOUT_TYPE;

  switch (type->ty)
    {
    case Tpointer:
      return TK_POINTER_TYPE;

    case  Tarray:
      return TK_ARRAY_TYPE;

    case Tsarray:
      return TK_STATICARRAY_TYPE;

    case Taarray:
      return TK_ASSOCIATIVEARRAY_TYPE;

    case Tstruct:
      return TK_STRUCT_TYPE;

    case Tvector:
      return TK_VECTOR_TYPE;

    case Tenum:
      return TK_ENUMERAL_TYPE;

    case Tfunction:
      return TK_FUNCTION_TYPE;

    case Tdelegate:
      return TK_DELEGATE_TYPE;

    case Ttuple:
      return TK_TYPELIST_TYPE;

    case Tclass:
      if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
	return TK_INTERFACE_TYPE;
      else
	return TK_CLASSINFO_TYPE;

    default:
      return TK_TYPEINFO_TYPE;
    }
}

/* Generate the RECORD_TYPE containing the data layout of a TypeInfo derivative
   as used by the runtime.  This layout must be consistent with that defined in
   the `object.d' module.  */

static void
make_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...)
{
  va_list ap;

  va_start (ap, ident);

  /* First two fields are from the TypeInfo base class.
     Note, finish_builtin_struct() expects these fields in reverse order.  */
  tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);
  DECL_CHAIN (fields) = create_field_decl (vtbl_ptr_type_node, NULL, 1, 1);

  /* Now add the derived fields.  */
  tree field_type = va_arg (ap, tree);
  while (field_type != NULL_TREE)
    {
      tree field = create_field_decl (field_type, NULL, 1, 1);
      DECL_CHAIN (field) = fields;
      fields = field;
      field_type = va_arg (ap, tree);
    }

  /* Create the TypeInfo type.  */
  tree type = make_node (RECORD_TYPE);
  finish_builtin_struct (type, ident->toChars (), fields, NULL_TREE);

  tinfo_types[tk] = type;

  va_end (ap);
}

/* Reference to the `object` module, where all TypeInfo is defined.  */

static Module *object_module;

/* Helper for create_frontend_tinfo_types.  Creates a typeinfo class
   declaration incase one wasn't supplied by reading `object.d'.  */

static void
make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL)
{
  if (!base)
    base = Type::dtypeinfo;

  gcc_assert (object_module);

  /* Create object module in order to complete the semantic.  */
  if (!object_module->_scope)
    object_module->importAll (NULL);

  /* Object class doesn't exist, create a stub one that will cause an error if
     used.  */
  Loc loc = (object_module->md) ? object_module->md->loc : object_module->loc;
  if (!base)
    {
      if (!ClassDeclaration::object)
	{
	  ClassDeclaration *object
	    = ClassDeclaration::create (loc, Identifier::idPool ("Object"),
					NULL, NULL, true);
	  object->parent = object_module;
	  object->members = new Dsymbols;
	  object->storage_class |= STCtemp;
	}

      base = ClassDeclaration::object;
    }

  /* Assignment of global typeinfo variables is managed by the ClassDeclaration
     constructor, so only need to new the declaration here.  */
  ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL,
						      true);
  tinfo->parent = object_module;
  tinfo->members = new Dsymbols;
  dsymbolSemantic (tinfo, object_module->_scope);
  tinfo->baseClass = base;
  /* This is a compiler generated class, and shouldn't be mistaken for being
     the type declared in the runtime library.  */
  tinfo->storage_class |= STCtemp;
}

/* Make sure the required builtin types exist for generating the TypeInfo
   variable definitions.  */

void
create_tinfo_types (Module *mod)
{
  /* Build the internal TypeInfo and ClassInfo types.
     See TypeInfoVisitor for documentation of field layout.  */
  make_internal_typeinfo (TK_TYPEINFO_TYPE, Identifier::idPool ("TypeInfo"),
			  NULL);

  make_internal_typeinfo (TK_CLASSINFO_TYPE,
			  Identifier::idPool ("TypeInfo_Class"),
			  array_type_node, array_type_node, array_type_node,
			  array_type_node, ptr_type_node, ptr_type_node,
			  ptr_type_node, d_uint_type, ptr_type_node,
			  array_type_node, ptr_type_node, ptr_type_node, NULL);

  object_module = mod;
}

/* Same as create_tinfo_types, but builds all front-end TypeInfo variable
   definitions.  */

static void
create_frontend_tinfo_types (void)
{
  /* If there's no object module, then neither can there be TypeInfo.  */
  if (object_module == NULL)
    return;

  /* Create all frontend TypeInfo classes declarations.  We rely on all
     existing, even if only just as stubs.  */
  if (!Type::dtypeinfo)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo"),
			    ClassDeclaration::object);

  if (!Type::typeinfoclass)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class"));

  if (!Type::typeinfointerface)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface"));

  if (!Type::typeinfostruct)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct"));

  if (!Type::typeinfopointer)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer"));

  if (!Type::typeinfoarray)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array"));

  if (!Type::typeinfostaticarray)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray"));

  if (!Type::typeinfoassociativearray)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray"));

  if (!Type::typeinfoenum)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum"));

  if (!Type::typeinfofunction)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function"));

  if (!Type::typeinfodelegate)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate"));

  if (!Type::typeinfotypelist)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple"));

  if (!Type::typeinfoconst)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const"));

  if (!Type::typeinfoinvariant)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"),
			    Type::typeinfoconst);

  if (!Type::typeinfoshared)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"),
			    Type::typeinfoconst);

  if (!Type::typeinfowild)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"),
			    Type::typeinfoconst);

  if (!Type::typeinfovector)
    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector"));

  if (!ClassDeclaration::cpp_type_info_ptr)
    make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"),
			    ClassDeclaration::object);
}

/* Return true if TypeInfo class TINFO is available in the runtime library.  */

bool
have_typeinfo_p (ClassDeclaration *tinfo)
{
  /* Run-time typeinfo disabled on command line.  */
  if (!global.params.useTypeInfo)
    return false;

  /* Can't layout TypeInfo if type is not declared, or is an opaque
     declaration in the object module.  */
  if (!tinfo || !tinfo->members)
    return false;

  /* Typeinfo is compiler-generated.  */
  if (tinfo->storage_class & STCtemp)
    return false;

  return true;
}

/* Implements the visitor interface to build the TypeInfo layout of all
   TypeInfoDeclaration AST classes emitted from the D Front-end.
   All visit methods accept one parameter D, which holds the frontend AST
   of the TypeInfo class.  They also don't return any value, instead the
   generated symbol is cached internally and returned from the caller.  */

class TypeInfoVisitor : public Visitor
{
  using Visitor::visit;

  tree decl_;
  vec<constructor_elt, va_gc> *init_;

  /* Build an internal comdat symbol for the manifest constant VALUE, so that
     its address can be taken.  */

  tree internal_reference (tree value)
  {
    /* Use the typeinfo decl name as a prefix for the internal symbol.  */
    const char *prefix = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (this->decl_));
    tree decl = build_artificial_decl (TREE_TYPE (value), value, prefix);

    /* The internal pointer reference should be public, but not visible outside
       the compilation unit.  */
    DECL_EXTERNAL (decl) = 0;
    TREE_PUBLIC (decl) = 1;
    DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
    set_linkage_for_decl (decl);
    d_pushdecl (decl);

    return decl;
  }

  /* Add VALUE to the constructor values list.  */

  void layout_field (tree value)
  {
    CONSTRUCTOR_APPEND_ELT (this->init_, NULL_TREE, value);
  }

  /* Write out STR as a static D string literal.  */

  void layout_string (const char *str)
  {
    unsigned len = strlen (str);
    tree value = build_string (len, str);

    TREE_TYPE (value) = make_array_type (Type::tchar, len);
    TREE_CONSTANT (value) = 1;
    TREE_READONLY (value) = 1;
    TREE_STATIC (value) = 1;

    /* Taking the address, so assign the literal to a static var.  */
    tree decl = this->internal_reference (value);
    TREE_READONLY (decl) = 1;

    value = d_array_value (build_ctype (Type::tchar->arrayOf ()),
			   size_int (len), build_address (decl));
    this->layout_field (value);
  }

  /* Write out the __vptr and optionally __monitor fields of class CD.  */

  void layout_base (ClassDeclaration *cd)
  {
    gcc_assert (cd != NULL);

    if (have_typeinfo_p (cd))
      this->layout_field (build_address (get_vtable_decl (cd)));
    else
      this->layout_field (null_pointer_node);

    if (cd->hasMonitor ())
      this->layout_field (null_pointer_node);
  }

  /* Write out the interfaces field of class CD.
     Returns the array of interfaces that the field is pointing to.  */

  tree layout_interfaces (ClassDeclaration *cd)
  {
    size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
    tree csym = build_address (get_classinfo_decl (cd));

    /* Put out the offset to where vtblInterfaces are written.  */
    tree value = d_array_value (array_type_node,
				size_int (cd->vtblInterfaces->length),
				build_offset (csym, size_int (offset)));
    this->layout_field (value);

    /* Internally, the compiler sees Interface as:
	void*[4] interface;

       The run-time layout of Interface is:
	TypeInfo_Class classinfo;
	void*[] vtbl;
	size_t offset;  */
    vec<constructor_elt, va_gc> *elms = NULL;

    for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
      {
	BaseClass *b = (*cd->vtblInterfaces)[i];
	ClassDeclaration *id = b->sym;
	vec<constructor_elt, va_gc> *v = NULL;

	/* Fill in the vtbl[].  */
	if (!cd->isInterfaceDeclaration ())
	  b->fillVtbl (cd, &b->vtbl, 1);

	/* ClassInfo for the interface.  */
	value = build_address (get_classinfo_decl (id));
	CONSTRUCTOR_APPEND_ELT (v, size_int (0), value);

	if (!cd->isInterfaceDeclaration ())
	  {
	    /* The vtable of the interface length and ptr.  */
	    unsigned voffset = base_vtable_offset (cd, b);
	    gcc_assert (voffset != 0u);
	    value = build_offset (csym, size_int (voffset));

	    CONSTRUCTOR_APPEND_ELT (v, size_int (1),
				    size_int (id->vtbl.length));
	    CONSTRUCTOR_APPEND_ELT (v, size_int (2), value);
	  }

	/* The `this' offset.  */
	CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));

	/* Add to the array of interfaces.  */
	value = build_constructor (vtbl_interface_type_node, v);
	CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
      }

    tree domain = size_int (cd->vtblInterfaces->length - 1);
    tree arrtype = build_array_type (vtbl_interface_type_node,
				     build_index_type (domain));
    return build_constructor (arrtype, elms);
  }

  /* Write out the interfacing vtable[] of base class BCD that will be accessed
     from the overriding class CD.  If both are the same class, then this will
     be its own vtable.  INDEX is the offset in the interfaces array of the
     base class where the Interface reference can be found.
     This must be mirrored with base_vtable_offset().  */

  void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd,
			   size_t index)
  {
    BaseClass *bs = (*bcd->vtblInterfaces)[index];
    ClassDeclaration *id = bs->sym;
    vec<constructor_elt, va_gc> *elms = NULL;
    FuncDeclarations bvtbl;

    if (id->vtbl.length == 0 || base_vtable_offset (cd, bs) == ~0u)
      return;

    /* Fill bvtbl with the functions we want to put out.  */
    if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0))
      return;

    /* First entry is struct Interface reference.  */
    if (id->vtblOffset ())
      {
	size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
	offset += (index * int_size_in_bytes (vtbl_interface_type_node));
	tree value = build_offset (build_address (get_classinfo_decl (bcd)),
				   size_int (offset));
	CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value);
      }

    for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.length; i++)
      {
	FuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i];
	if (fd != NULL)
	  {
	    tree value = build_address (make_thunk (fd, bs->offset));
	    CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
	  }
      }

    tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
    tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
    tree value = build_constructor (vtbltype, elms);
    this->layout_field (value);
  }


public:
  TypeInfoVisitor (tree decl)
  {
    this->decl_ = decl;
    this->init_ = NULL;
  }

  /* Return the completed constructor for the TypeInfo record.  */

  tree result (void)
  {
    return build_struct_literal (TREE_TYPE (this->decl_), this->init_);
  }

  /* Layout of TypeInfo is:
	void **__vptr;
	void *__monitor;  */

  void visit (TypeInfoDeclaration *)
  {
    /* The vtable for TypeInfo.  */
    this->layout_base (Type::dtypeinfo);
  }

  /* Layout of TypeInfo_Const is:
	void **__vptr;
	void *__monitor;
	TypeInfo base;  */

  void visit (TypeInfoConstDeclaration *d)
  {
    Type *tm = d->tinfo->mutableOf ();
    tm = tm->merge2 ();

    /* The vtable for TypeInfo_Const.  */
    this->layout_base (Type::typeinfoconst);

    /* TypeInfo for the mutable type.  */
    this->layout_field (build_typeinfo (d->loc, tm));
  }

  /* Layout of TypeInfo_Immutable is:
	void **__vptr;
	void *__monitor;
	TypeInfo base;  */

  void visit (TypeInfoInvariantDeclaration *d)
  {
    Type *tm = d->tinfo->mutableOf ();
    tm = tm->merge2 ();

    /* The vtable for TypeInfo_Invariant.  */
    this->layout_base (Type::typeinfoinvariant);

    /* TypeInfo for the mutable type.  */
    this->layout_field (build_typeinfo (d->loc, tm));
  }

  /* Layout of TypeInfo_Shared is:
	void **__vptr;
	void *__monitor;
	TypeInfo base;  */

  void visit (TypeInfoSharedDeclaration *d)
  {
    Type *tm = d->tinfo->unSharedOf ();
    tm = tm->merge2 ();

    /* The vtable for TypeInfo_Shared.  */
    this->layout_base (Type::typeinfoshared);

    /* TypeInfo for the unshared type.  */
    this->layout_field (build_typeinfo (d->loc, tm));
  }

  /* Layout of TypeInfo_Inout is:
	void **__vptr;
	void *__monitor;
	TypeInfo base;  */

  void visit (TypeInfoWildDeclaration *d)
  {
    Type *tm = d->tinfo->mutableOf ();
    tm = tm->merge2 ();

    /* The vtable for TypeInfo_Inout.  */
    this->layout_base (Type::typeinfowild);

    /* TypeInfo for the mutable type.  */
    this->layout_field (build_typeinfo (d->loc, tm));
  }

  /* Layout of TypeInfo_Enum is:
	void **__vptr;
	void *__monitor;
	TypeInfo base;
	string name;
	void[] m_init;  */

  void visit (TypeInfoEnumDeclaration *d)
  {
    TypeEnum *ti = d->tinfo->isTypeEnum ();
    EnumDeclaration *ed = ti->sym;

    /* The vtable for TypeInfo_Enum.  */
    this->layout_base (Type::typeinfoenum);

    /* TypeInfo for enum members.  */
    tree memtype = (ed->memtype) ? build_typeinfo (d->loc, ed->memtype)
      : null_pointer_node;
    this->layout_field (memtype);

    /* Name of the enum declaration.  */
    this->layout_string (ed->toPrettyChars ());

    /* Default initializer for enum.  */
    if (ed->members && !d->tinfo->isZeroInit ())
      {
	tree length = size_int (ed->type->size ());
	tree ptr = build_address (enum_initializer_decl (ed));
	this->layout_field (d_array_value (array_type_node, length, ptr));
      }
    else
      this->layout_field (null_array_node);
  }

  /* Layout of TypeInfo_Pointer is:
	void **__vptr;
	void *__monitor;
	TypeInfo m_next;  */

  void visit (TypeInfoPointerDeclaration *d)
  {
    TypePointer *ti = d->tinfo->isTypePointer ();

    /* The vtable for TypeInfo_Pointer.  */
    this->layout_base (Type::typeinfopointer);

    /* TypeInfo for pointer-to type.  */
    this->layout_field (build_typeinfo (d->loc, ti->next));
  }

  /* Layout of TypeInfo_Array is:
	void **__vptr;
	void *__monitor;
	TypeInfo value;  */

  void visit (TypeInfoArrayDeclaration *d)
  {
    TypeDArray *ti = d->tinfo->isTypeDArray ();

    /* The vtable for TypeInfo_Array.  */
    this->layout_base (Type::typeinfoarray);

    /* TypeInfo for array of type.  */
    this->layout_field (build_typeinfo (d->loc, ti->next));
  }

  /* Layout of TypeInfo_StaticArray is:
	void **__vptr;
	void *__monitor;
	TypeInfo value;
	size_t len;  */

  void visit (TypeInfoStaticArrayDeclaration *d)
  {
    TypeSArray *ti = d->tinfo->isTypeSArray ();

    /* The vtable for TypeInfo_StaticArray.  */
    this->layout_base (Type::typeinfostaticarray);

    /* TypeInfo for array of type.  */
    this->layout_field (build_typeinfo (d->loc, ti->next));

    /* Static array length.  */
    this->layout_field (size_int (ti->dim->toInteger ()));
  }

  /* Layout of TypeInfo_AssociativeArray is:
	void **__vptr;
	void *__monitor;
	TypeInfo value;
	TypeInfo key;  */

  void visit (TypeInfoAssociativeArrayDeclaration *d)
  {
    TypeAArray *ti = d->tinfo->isTypeAArray ();

    /* The vtable for TypeInfo_AssociativeArray.  */
    this->layout_base (Type::typeinfoassociativearray);

    /* TypeInfo for value of type.  */
    this->layout_field (build_typeinfo (d->loc, ti->next));

    /* TypeInfo for index of type.  */
    this->layout_field (build_typeinfo (d->loc, ti->index));
  }

  /* Layout of TypeInfo_Vector is:
	void **__vptr;
	void *__monitor;
	TypeInfo base;  */

  void visit (TypeInfoVectorDeclaration *d)
  {
    TypeVector *ti = d->tinfo->isTypeVector ();

    /* The vtable for TypeInfo_Vector.  */
    this->layout_base (Type::typeinfovector);

    /* TypeInfo for equivalent static array.  */
    this->layout_field (build_typeinfo (d->loc, ti->basetype));
  }

  /* Layout of TypeInfo_Function is:
	void **__vptr;
	void *__monitor;
	TypeInfo next;
	string deco;  */

  void visit (TypeInfoFunctionDeclaration *d)
  {
    TypeFunction *ti = d->tinfo->isTypeFunction ();
    gcc_assert (ti->deco != NULL);

    /* The vtable for TypeInfo_Function.  */
    this->layout_base (Type::typeinfofunction);

    /* TypeInfo for function return value.  */
    this->layout_field (build_typeinfo (d->loc, ti->next));

    /* Mangled name of function declaration.  */
    this->layout_string (d->tinfo->deco);
  }

  /* Layout of TypeInfo_Delegate is:
	void **__vptr;
	void *__monitor;
	TypeInfo next;
	string deco;  */

  void visit (TypeInfoDelegateDeclaration *d)
  {
    TypeDelegate *ti = d->tinfo->isTypeDelegate ();
    gcc_assert (ti->deco != NULL);

    /* The vtable for TypeInfo_Delegate.  */
    this->layout_base (Type::typeinfodelegate);

    /* TypeInfo for delegate return value.  */
    this->layout_field (build_typeinfo (d->loc, ti->next));

    /* Mangled name of delegate declaration.  */
    this->layout_string (d->tinfo->deco);
  }

  /* Layout of ClassInfo/TypeInfo_Class is:
	void **__vptr;
	void *__monitor;
	byte[] m_init;
	string name;
	void*[] vtbl;
	Interface[] interfaces;
	TypeInfo_Class base;
	void *destructor;
	void function(Object) classInvariant;
	ClassFlags m_flags;
	void *deallocator;
	OffsetTypeInfo[] m_offTi;
	void function(Object) defaultConstructor;
	immutable(void)* m_RTInfo;

     Information relating to interfaces, and their vtables are laid out
     immediately after the named fields, if there is anything to write.  */

  void visit (TypeInfoClassDeclaration *d)
  {
    TypeClass *ti = d->tinfo->isTypeClass ();
    ClassDeclaration *cd = ti->sym;

    /* The vtable for ClassInfo.  */
    this->layout_base (Type::typeinfoclass);

    if (!cd->members)
      return;

    tree interfaces = NULL_TREE;

    if (!cd->isInterfaceDeclaration ())
      {
	/* Default initializer for class.  */
	tree init = aggregate_initializer_decl (cd);
	tree value = d_array_value (array_type_node, size_int (cd->structsize),
				    build_address (init));
	this->layout_field (value);

	/* Name of the class declaration.  */
	const char *name = cd->ident->toChars ();
	if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0))
	  name = cd->toPrettyChars ();
	this->layout_string (name);

	/* The vtable of the class declaration.  */
	value = d_array_value (array_type_node, size_int (cd->vtbl.length),
			       build_address (get_vtable_decl (cd)));
	this->layout_field (value);

	/* Array of base interfaces that have their own vtable.  */
	if (cd->vtblInterfaces->length)
	  interfaces = this->layout_interfaces (cd);
	else
	  this->layout_field (null_array_node);

	/* TypeInfo_Class base;  */
	tree base = (cd->baseClass)
	  ? build_address (get_classinfo_decl (cd->baseClass))
	  : null_pointer_node;
	this->layout_field (base);

	/* void *destructor;  */
	tree dtor = (cd->dtor) ? build_address (get_symbol_decl (cd->dtor))
	  : null_pointer_node;
	this->layout_field (dtor);

	/* void function(Object) classInvariant;  */
	tree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv))
	  : null_pointer_node;
	this->layout_field (inv);

	/* ClassFlags m_flags;  */
	int flags = ClassFlags::hasOffTi;
	if (cd->isCOMclass ())
	  flags |= ClassFlags::isCOMclass;

	if (cd->isCPPclass ())
	  flags |= ClassFlags::isCPPclass;

	flags |= ClassFlags::hasGetMembers;
	flags |= ClassFlags::hasTypeInfo;

	if (cd->ctor)
	  flags |= ClassFlags::hasCtor;

	for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
	  {
	    if (bcd->dtor)
	      {
		flags |= ClassFlags::hasDtor;
		break;
	      }
	  }

	if (cd->isAbstract ())
	  flags |= ClassFlags::isAbstract;

	for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
	  {
	    if (!bcd->members)
	      continue;

	    for (size_t i = 0; i < bcd->members->length; i++)
	      {
		Dsymbol *sm = (*bcd->members)[i];
		if (sm->hasPointers ())
		  goto Lhaspointers;
	      }
	  }

	flags |= ClassFlags::noPointers;

    Lhaspointers:
	this->layout_field (build_integer_cst (flags, d_uint_type));

	/* void *deallocator;  */
	tree ddtor = (cd->aggDelete)
	  ? build_address (get_symbol_decl (cd->aggDelete))
	  : null_pointer_node;
	this->layout_field (ddtor);

	/* OffsetTypeInfo[] m_offTi;  (not implemented)  */
	this->layout_field (null_array_node);

	/* void function(Object) defaultConstructor;  */
	if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable))
	  {
	    tree dctor = get_symbol_decl (cd->defaultCtor);
	    this->layout_field (build_address (dctor));
	  }
	else
	  this->layout_field (null_pointer_node);

	/* immutable(void)* m_RTInfo;  */
	if (cd->getRTInfo)
	  this->layout_field (build_expr (cd->getRTInfo, true));
	else if (!(flags & ClassFlags::noPointers))
	  this->layout_field (size_one_node);
	else
	  this->layout_field (null_pointer_node);
      }
    else
      {
	/* No initializer for interface.  */
	this->layout_field (null_array_node);

	/* Name of the interface declaration.  */
	this->layout_string (cd->toPrettyChars ());

	/* No vtable for interface declaration.  */
	this->layout_field (null_array_node);

	/* Array of base interfaces that have their own vtable.  */
	if (cd->vtblInterfaces->length)
	  interfaces = this->layout_interfaces (cd);
	else
	  this->layout_field (null_array_node);

	/* TypeInfo_Class base;
	   void *destructor;
	   void function(Object) classInvariant;  */
	this->layout_field (null_pointer_node);
	this->layout_field (null_pointer_node);
	this->layout_field (null_pointer_node);

	/* ClassFlags m_flags;  */
	int flags = ClassFlags::hasOffTi;
	flags |= ClassFlags::hasTypeInfo;
	if (cd->isCOMinterface ())
	  flags |= ClassFlags::isCOMclass;

	this->layout_field (build_integer_cst (flags, d_uint_type));

	/* void *deallocator;
	   OffsetTypeInfo[] m_offTi;  (not implemented)
	   void function(Object) defaultConstructor;  */
	this->layout_field (null_pointer_node);
	this->layout_field (null_array_node);
	this->layout_field (null_pointer_node);

	/* immutable(void)* m_RTInfo;  */
	if (cd->getRTInfo)
	  this->layout_field (build_expr (cd->getRTInfo, true));
	else
	  this->layout_field (null_pointer_node);
      }

    /* Put out array of Interfaces.  */
    if (interfaces != NULL_TREE)
      this->layout_field (interfaces);

    if (!cd->isInterfaceDeclaration ())
      {
	/* Put out this class' interface vtables[].  */
	for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
	  this->layout_base_vtable (cd, cd, i);

	/* Put out the overriding interface vtables[].  */
	for (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass)
	  {
	    for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
	      this->layout_base_vtable (cd, bcd, i);
	  }
      }
  }

  /* Layout of TypeInfo_Interface is:
	void **__vptr;
	void *__monitor;
	TypeInfo_Class info;  */

  void visit (TypeInfoInterfaceDeclaration *d)
  {
    TypeClass *ti = d->tinfo->isTypeClass ();

    if (!ti->sym->vclassinfo)
      ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti);

    /* The vtable for TypeInfo_Interface.  */
    this->layout_base (Type::typeinfointerface);

    /* TypeInfo for class inheriting the interface.  */
    tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo);
    this->layout_field (build_address (tidecl));
  }

  /* Layout of TypeInfo_Struct is:
	void **__vptr;
	void *__monitor;
	string name;
	void[] m_init;
	hash_t function(in void*) xtoHash;
	bool function(in void*, in void*) xopEquals;
	int function(in void*, in void*) xopCmp;
	string function(const(void)*) xtoString;
	StructFlags m_flags;
	void function(void*) xdtor;
	void function(void*) xpostblit;
	uint m_align;
	immutable(void)* xgetRTInfo;  */

  void visit (TypeInfoStructDeclaration *d)
  {
    TypeStruct *ti = d->tinfo->isTypeStruct ();
    StructDeclaration *sd = ti->sym;

    /* The vtable for TypeInfo_Struct.  */
    this->layout_base (Type::typeinfostruct);

    if (!sd->members)
      return;

    /* Name of the struct declaration.  */
    this->layout_string (sd->toPrettyChars ());

    /* Default initializer for struct.  */
    tree ptr = (sd->zeroInit) ? null_pointer_node
      : build_address (aggregate_initializer_decl (sd));
    this->layout_field (d_array_value (array_type_node,
				       size_int (sd->structsize), ptr));

    /* hash_t function (in void*) xtoHash;  */
    tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash))
      : null_pointer_node;
    this->layout_field (xhash);

    if (sd->xhash)
      {
	TypeFunction *tf = sd->xhash->type->toTypeFunction ();
	if (!tf->isnothrow || tf->trust == TRUSTsystem)
	  {
	    warning (sd->xhash->loc, "toHash() must be declared as "
		     "extern (D) size_t toHash() const nothrow @safe, "
		     "not %s", tf->toChars ());
	  }
      }

    /* bool function(in void*, in void*) xopEquals;  */
    tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
      : null_pointer_node;
    this->layout_field (xeq);

    /* int function(in void*, in void*) xopCmp;  */
    tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp))
      : null_pointer_node;
    this->layout_field (xcmp);

    /* string function(const(void)*) xtoString;  */
    FuncDeclaration *fdx = search_toString (sd);
    if (fdx)
      this->layout_field (build_address (get_symbol_decl (fdx)));
    else
      this->layout_field (null_pointer_node);

    /* StructFlags m_flags;  */
    int m_flags = StructFlags::none;
    if (ti->hasPointers ())
      m_flags |= StructFlags::hasPointers;
    this->layout_field (build_integer_cst (m_flags, d_uint_type));

    /* void function(void*) xdtor;  */
    tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor))
      : null_pointer_node;
    this->layout_field (dtor);

    /* void function(void*) xpostblit;  */
    if (sd->postblit && !(sd->postblit->storage_class & STCdisable))
      this->layout_field (build_address (get_symbol_decl (sd->postblit)));
    else
      this->layout_field (null_pointer_node);

    /* uint m_align;  */
    this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type));

    /* immutable(void)* xgetRTInfo;  */
    if (sd->getRTInfo)
      this->layout_field (build_expr (sd->getRTInfo, true));
    else if (m_flags & StructFlags::hasPointers)
      this->layout_field (size_one_node);
  }

  /* Layout of TypeInfo_Tuple is:
	void **__vptr;
	void *__monitor;
	TypeInfo[] elements;  */

  void visit (TypeInfoTupleDeclaration *d)
  {
    TypeTuple *ti = d->tinfo->isTypeTuple ();

    /* The vtable for TypeInfo_Tuple.  */
    this->layout_base (Type::typeinfotypelist);

    /* TypeInfo[] elements;  */
    Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->length);
    vec<constructor_elt, va_gc> *elms = NULL;
    for (size_t i = 0; i < ti->arguments->length; i++)
      {
	Parameter *arg = (*ti->arguments)[i];
	CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
				build_typeinfo (d->loc, arg->type));
      }
    tree ctor = build_constructor (build_ctype (satype), elms);
    tree decl = this->internal_reference (ctor);

    tree length = size_int (ti->arguments->length);
    tree ptr = build_address (decl);
    this->layout_field (d_array_value (array_type_node, length, ptr));

    rest_of_decl_compilation (decl, 1, 0);
  }
};


/* Main entry point for TypeInfoVisitor interface to generate
   TypeInfo constructor for the TypeInfoDeclaration AST class D.  */

tree
layout_typeinfo (TypeInfoDeclaration *d)
{
  if (!Type::dtypeinfo)
    create_frontend_tinfo_types ();

  TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d));
  d->accept (&v);
  return v.result ();
}

/* Like layout_typeinfo, but generates the TypeInfo_Class for
   the class or interface declaration CD.  */

tree
layout_classinfo (ClassDeclaration *cd)
{
  if (!Type::dtypeinfo)
    create_frontend_tinfo_types ();

  TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
  TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd));
  d->accept (&v);
  return v.result ();
}

/* Get the offset to the BC's vtbl[] initializer from the start of CD.
   Returns "~0u" if the base class is not found in any vtable interfaces.  */

unsigned
base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
{
  unsigned csymoffset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
  unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
  csymoffset += cd->vtblInterfaces->length * interfacesize;

  for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
    {
      BaseClass *b = (*cd->vtblInterfaces)[i];
      if (b == bc)
	return csymoffset;
      csymoffset += b->sym->vtbl.length * target.ptrsize;
    }

  /* Check all overriding interface vtbl[]s.  */
  for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)
    {
      for (size_t k = 0; k < cd2->vtblInterfaces->length; k++)
	{
	  BaseClass *bs = (*cd2->vtblInterfaces)[k];
	  if (bs->fillVtbl (cd, NULL, 0))
	    {
	      if (bc == bs)
		return csymoffset;
	      csymoffset += bs->sym->vtbl.length * target.ptrsize;
	    }
	}
    }

  return ~0u;
}

/* Layout fields that immediately come after the classinfo type for DECL if
   there's any interfaces or interface vtables to be added.
   This must be mirrored with base_vtable_offset().  */

static tree
layout_classinfo_interfaces (ClassDeclaration *decl)
{
  tree type = tinfo_types[TK_CLASSINFO_TYPE];
  size_t structsize = int_size_in_bytes (type);

  if (decl->vtblInterfaces->length)
    {
      size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node);
      tree field;

      type = copy_aggregate_type (type);

      /* First layout the static array of Interface, which provides information
	 about the vtables that follow.  */
      tree domain = size_int (decl->vtblInterfaces->length - 1);
      tree arrtype = build_array_type (vtbl_interface_type_node,
				       build_index_type (domain));
      field = create_field_decl (arrtype, NULL, 1, 1);
      insert_aggregate_field (type, field, structsize);
      structsize += decl->vtblInterfaces->length * interfacesize;

      /* For each interface, layout each vtable.  */
      for (size_t i = 0; i < decl->vtblInterfaces->length; i++)
	{
	  BaseClass *b = (*decl->vtblInterfaces)[i];
	  ClassDeclaration *id = b->sym;
	  unsigned offset = base_vtable_offset (decl, b);

	  if (id->vtbl.length && offset != ~0u)
	    {
	      tree vtbldomain
		= build_index_type (size_int (id->vtbl.length - 1));
	      tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);

	      field = create_field_decl (vtbltype, NULL, 1, 1);
	      insert_aggregate_field (type, field, offset);
	      structsize += id->vtbl.length * target.ptrsize;
	    }
	}
    }

  /* Layout the arrays of overriding interface vtables.  */
  for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass)
    {
      for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
	{
	  BaseClass *b = (*bcd->vtblInterfaces)[i];
	  ClassDeclaration *id = b->sym;
	  unsigned offset = base_vtable_offset (decl, b);

	  if (id->vtbl.length && offset != ~0u)
	    {
	      if (type == tinfo_types[TK_CLASSINFO_TYPE])
		type = copy_aggregate_type (type);

	      tree vtbldomain
		= build_index_type (size_int (id->vtbl.length - 1));
	      tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);

	      tree field = create_field_decl (vtbltype, NULL, 1, 1);
	      insert_aggregate_field (type, field, offset);
	      structsize += id->vtbl.length * target.ptrsize;
	    }
	}
    }

  /* Update the type size and record mode for the classinfo type.  */
  if (type != tinfo_types[TK_CLASSINFO_TYPE])
    finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type);

  return type;
}

/* Returns true if the TypeInfo for TYPE should be placed in
   the runtime library.  */

static bool
builtin_typeinfo_p (Type *type)
{
  if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull)
    return !type->mod;

  if (type->ty == Tarray)
    {
      /* Strings are so common, make them builtin.  */
      Type *next = type->nextOf ();
      return !type->mod
	&& ((next->isTypeBasic () != NULL && !next->mod)
	    || (next->ty == Tchar && next->mod == MODimmutable)
	    || (next->ty == Tchar && next->mod == MODconst));
    }

  return false;
}

/* Implements a visitor interface to create the decl tree for TypeInfo decls.
   TypeInfo_Class objects differ in that they also have information about
   the class type packed immediately after the TypeInfo symbol.

   If the frontend had an interface to allow distinguishing being these two
   AST types, then that would be better for us.  */

class TypeInfoDeclVisitor : public Visitor
{
  using Visitor::visit;

public:
  TypeInfoDeclVisitor (void)
  {
  }

  void visit (TypeInfoDeclaration *tid)
  {
    tree ident = get_identifier (tid->ident->toChars ());
    tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)];
    gcc_assert (type != NULL_TREE);

    /* Built-in typeinfo will be referenced as one-only.  */
    tid->csym = declare_extern_var (ident, type);
    DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid);

    DECL_CONTEXT (tid->csym) = d_decl_context (tid);
    TREE_READONLY (tid->csym) = 1;
  }

  void visit (TypeInfoClassDeclaration *tid)
  {
    TypeClass *tc = tid->tinfo->isTypeClass ();
    tid->csym = get_classinfo_decl (tc->sym);
  }
};

/* Get the VAR_DECL of the TypeInfo for DECL.  If this does not yet exist,
   create it.  The TypeInfo decl provides information about the type of a given
   expression or object.  */

tree
get_typeinfo_decl (TypeInfoDeclaration *decl)
{
  if (decl->csym)
    return decl->csym;

  gcc_assert (decl->tinfo->ty != Terror);

  TypeInfoDeclVisitor v = TypeInfoDeclVisitor ();
  decl->accept (&v);
  gcc_assert (decl->csym != NULL_TREE);

  return decl->csym;
}

/* Get the VAR_DECL of the ClassInfo for DECL.  If this does not yet exist,
   create it.  The ClassInfo decl provides information about the dynamic type
   of a given class type or object.  */

tree
get_classinfo_decl (ClassDeclaration *decl)
{
  if (decl->csym)
    return decl->csym;

  InterfaceDeclaration *id = decl->isInterfaceDeclaration ();
  tree ident = mangle_internal_decl (decl, id ? "__Interface" : "__Class", "Z");
  tree type = layout_classinfo_interfaces (decl);

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

  /* Class is a reference, want the record type.  */
  DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type));
  /* ClassInfo cannot be const data, because we use the monitor on it.  */
  TREE_READONLY (decl->csym) = 0;

  return decl->csym;
}

/* Performs sanity checks on the `object.TypeInfo' type, raising an error if
   RTTI is disabled, or the type is missing.  */

void
check_typeinfo_type (const Loc &loc, Scope *sc)
{
  if (!global.params.useTypeInfo)
    {
      static int warned = 0;

      /* Even when compiling without RTTI we should still be able to evaluate
	 TypeInfo at compile-time, just not at run-time.  */
      if (!warned && (!sc || !(sc->flags & SCOPEctfe)))
	{
	  error_at (make_location_t (loc),
		    "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
	  warned = 1;
	}
    }

  if (Type::dtypeinfo == NULL
      || (Type::dtypeinfo->storage_class & STCtemp))
    {
      /* If TypeInfo has not been declared, warn about each location once.  */
      static Loc warnloc;

      if (loc.filename && !warnloc.equals (loc))
	{
	  error_at (make_location_t (loc),
		    "%<object.TypeInfo%> could not be found, "
		    "but is implicitly used");
	  warnloc = loc;
	}
    }
}

/* Returns typeinfo reference for TYPE.  */

tree
build_typeinfo (const Loc &loc, Type *type)
{
  gcc_assert (type->ty != Terror);
  check_typeinfo_type (loc, NULL);
  create_typeinfo (type, NULL);
  return build_address (get_typeinfo_decl (type->vtinfo));
}

/* Like layout_classinfo, but generates an Object that wraps around a
   pointer to C++ type_info so it can be distinguished from D TypeInfo.  */

void
layout_cpp_typeinfo (ClassDeclaration *cd)
{
  if (!Type::dtypeinfo)
    create_frontend_tinfo_types ();

  gcc_assert (cd->isCPPclass ());

  tree decl = get_cpp_typeinfo_decl (cd);
  vec<constructor_elt, va_gc> *init = NULL;

  /* Use the vtable of __cpp_type_info_ptr, the EH personality routine
     expects this, as it uses .classinfo identity comparison to test for
     C++ catch handlers.  */
  ClassDeclaration *cppti = ClassDeclaration::cpp_type_info_ptr;
  if (have_typeinfo_p (cppti))
    {
      tree vptr = get_vtable_decl (cppti);
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr));
    }
  else
    CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);

  if (cppti->hasMonitor ())
    CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);

  /* Let C++ do the RTTI generation, and just reference the symbol as
     extern, knowing the underlying type is not required.  */
  const char *ident = target.cpp.typeInfoMangle (cd);
  tree typeinfo = declare_extern_var (get_identifier (ident),
				      unknown_type_node);
  TREE_READONLY (typeinfo) = 1;
  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo));

  /* Build the initializer and emit.  */
  DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init);
  d_finish_decl (decl);
}

/* Get the VAR_DECL of the __cpp_type_info_ptr for DECL.  If this does not yet
   exist, create it.  The __cpp_type_info_ptr decl is then initialized with a
   pointer to the C++ type_info for the given class.  */

tree
get_cpp_typeinfo_decl (ClassDeclaration *decl)
{
  gcc_assert (decl->isCPPclass ());

  if (decl->cpp_type_info_ptr_sym)
    return decl->cpp_type_info_ptr_sym;

  if (!tinfo_types[TK_CPPTI_TYPE])
    make_internal_typeinfo (TK_CPPTI_TYPE,
			    Identifier::idPool ("__cpp_type_info_ptr"),
			    ptr_type_node, NULL);

  tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", "");
  tree type = tinfo_types[TK_CPPTI_TYPE];

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

  /* Class is a reference, want the record type.  */
  DECL_CONTEXT (decl->cpp_type_info_ptr_sym)
    = TREE_TYPE (build_ctype (decl->type));
  TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;

  /* Layout the initializer and emit the symbol.  */
  layout_cpp_typeinfo (decl);

  return decl->cpp_type_info_ptr_sym;
}

/* Get the exact TypeInfo for TYPE, if it doesn't exist, create it.  */

void
create_typeinfo (Type *type, Module *mod)
{
  if (!Type::dtypeinfo)
    create_frontend_tinfo_types ();

  /* Do this since not all Type's are merged.  */
  Type *t = type->merge2 ();
  Identifier *ident;

  if (!t->vtinfo)
    {
      tinfo_kind tk = get_typeinfo_kind (t);
      switch (tk)
	{
	case TK_SHARED_TYPE:
	case TK_CONST_TYPE:
	case TK_IMMUTABLE_TYPE:
	case TK_INOUT_TYPE:
	case TK_POINTER_TYPE:
	case TK_ARRAY_TYPE:
	case TK_VECTOR_TYPE:
	case TK_INTERFACE_TYPE:
	  /* Kinds of TypeInfo that add one extra pointer field.  */
	  if (tk == TK_SHARED_TYPE)
	    {
	      /* Does both `shared' and `shared const'.  */
	      t->vtinfo = TypeInfoSharedDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Shared");
	    }
	  else if (tk == TK_CONST_TYPE)
	    {
	      t->vtinfo = TypeInfoConstDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Const");
	    }
	  else if (tk == TK_IMMUTABLE_TYPE)
	    {
	      t->vtinfo = TypeInfoInvariantDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Invariant");
	    }
	  else if (tk == TK_INOUT_TYPE)
	    {
	      t->vtinfo = TypeInfoWildDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Wild");
	    }
	  else if (tk == TK_POINTER_TYPE)
	    {
	      t->vtinfo = TypeInfoPointerDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Pointer");
	    }
	  else if (tk == TK_ARRAY_TYPE)
	    {
	      t->vtinfo = TypeInfoArrayDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Array");
	    }
	  else if (tk == TK_VECTOR_TYPE)
	    {
	      t->vtinfo = TypeInfoVectorDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Vector");
	    }
	  else if (tk == TK_INTERFACE_TYPE)
	    {
	      t->vtinfo = TypeInfoInterfaceDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Interface");
	    }
	  else
	    gcc_unreachable ();

	  if (!tinfo_types[tk])
	    make_internal_typeinfo (tk, ident, ptr_type_node, NULL);
	  break;

	case TK_STATICARRAY_TYPE:
	  if (!tinfo_types[tk])
	    {
	      ident = Identifier::idPool ("TypeInfo_StaticArray");
	      make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node,
				      NULL);
	    }
	  t->vtinfo = TypeInfoStaticArrayDeclaration::create (t);
	  break;

	case TK_ASSOCIATIVEARRAY_TYPE:
	  if (!tinfo_types[tk])
	    {
	      ident = Identifier::idPool ("TypeInfo_AssociativeArray");
	      make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node,
				      NULL);
	    }
	  t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t);
	  break;

	case TK_STRUCT_TYPE:
	  if (!tinfo_types[tk])
	    {
	      ident = Identifier::idPool ("TypeInfo_Struct");
	      make_internal_typeinfo (tk, ident,
				      array_type_node, array_type_node,
				      ptr_type_node, ptr_type_node,
				      ptr_type_node, ptr_type_node,
				      d_uint_type, ptr_type_node,
				      ptr_type_node, d_uint_type,
				      ptr_type_node, NULL);
	    }
	  t->vtinfo = TypeInfoStructDeclaration::create (t);
	  break;

	case TK_ENUMERAL_TYPE:
	  if (!tinfo_types[tk])
	    {
	      ident = Identifier::idPool ("TypeInfo_Enum");
	      make_internal_typeinfo (tk, ident,
				      ptr_type_node, array_type_node,
				      array_type_node, NULL);
	    }
	  t->vtinfo = TypeInfoEnumDeclaration::create (t);
	  break;

	case TK_FUNCTION_TYPE:
	case TK_DELEGATE_TYPE:
	  /* Functions and delegates share a common TypeInfo layout.  */
	  if (tk == TK_FUNCTION_TYPE)
	    {
	      t->vtinfo = TypeInfoFunctionDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Function");
	    }
	  else if (tk == TK_DELEGATE_TYPE)
	    {
	      t->vtinfo = TypeInfoDelegateDeclaration::create (t);
	      ident = Identifier::idPool ("TypeInfo_Delegate");
	    }
	  else
	    gcc_unreachable ();

	  if (!tinfo_types[tk])
	    make_internal_typeinfo (tk, ident, ptr_type_node,
				    array_type_node, NULL);
	  break;

	case TK_TYPELIST_TYPE:
	  if (!tinfo_types[tk])
	    {
	      ident = Identifier::idPool ("TypeInfo_Tuple");
	      make_internal_typeinfo (tk, ident, array_type_node, NULL);
	    }
	  t->vtinfo = TypeInfoTupleDeclaration::create (t);
	  break;

	case TK_CLASSINFO_TYPE:
	  t->vtinfo = TypeInfoClassDeclaration::create (t);
	  break;

	default:
	  t->vtinfo = TypeInfoDeclaration::create (t);
	}
      gcc_assert (t->vtinfo);

      /* If this has a custom implementation in rt/typeinfo, then
	 do not generate a COMDAT for it.  */
      if (!builtin_typeinfo_p (t))
	{
	  /* Find module that will go all the way to an object file.  */
	  if (mod)
	    mod->members->push (t->vtinfo);
	  else
	    build_decl_tree (t->vtinfo);
	}
    }
  /* Types aren't merged, but we can share the vtinfo's.  */
  if (!type->vtinfo)
    type->vtinfo = t->vtinfo;

  gcc_assert (type->vtinfo != NULL);
}

/* Implements a visitor interface to check whether a type is speculative.
   TypeInfo_Struct would reference the members of the struct it is representing
   (e.g: opEquals via xopEquals field), so if it's instantiated in speculative
   context, TypeInfo creation should also be stopped to avoid possible
   `unresolved symbol' linker errors.  */

class SpeculativeTypeVisitor : public Visitor
{
  using Visitor::visit;

  bool result_;

public:
  SpeculativeTypeVisitor (void)
  {
    this->result_ = false;
  }

  bool result (void)
  {
    return this->result_;
  }

  void visit (Type *t)
  {
    Type *tb = t->toBasetype ();
    if (tb != t)
      tb->accept (this);
  }

  void visit (TypeNext *t)
  {
    if (t->next)
      t->next->accept (this);
  }

  void visit (TypeBasic *)
  {
  }

  void visit (TypeVector *t)
  {
    t->basetype->accept (this);
  }

  void visit (TypeAArray *t)
  {
    t->index->accept (this);
    visit ((TypeNext *) t);
  }

  void visit (TypeFunction *t)
  {
    visit ((TypeNext *) t);
  }

  void visit (TypeStruct *t)
  {
    StructDeclaration *sd = t->sym;
    if (TemplateInstance *ti = sd->isInstantiated ())
      {
	if (!ti->needsCodegen ())
	  {
	    if (ti->minst || sd->requestTypeInfo)
	      return;

	    this->result_ |= true;
	  }
      }
  }

  void visit (TypeClass *t)
  {
    ClassDeclaration *cd = t->sym;
    if (TemplateInstance *ti = cd->isInstantiated ())
      {
	if (!ti->needsCodegen () && !ti->minst)
	  {
	    this->result_ |= true;
	  }
      }
  }

  void visit (TypeTuple *t)
  {
    if (!t->arguments)
      return;

    for (size_t i = 0; i < t->arguments->length; i++)
      {
	Type *tprm = (*t->arguments)[i]->type;
	if (tprm)
	  tprm->accept (this);
	if (this->result_)
	  return;
      }
  }
};

/* Return true if type was instantiated in a speculative context.  */

bool
speculative_type_p (Type *t)
{
  SpeculativeTypeVisitor v = SpeculativeTypeVisitor ();
  t->accept (&v);
  return v.result ();
}

#include "gt-d-typeinfo.h"
