/* d-builtins.cc -- GCC builtins support for D.
   Copyright (C) 2006-2022 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/attrib.h"
#include "dmd/aggregate.h"
#include "dmd/cond.h"
#include "dmd/declaration.h"
#include "dmd/expression.h"
#include "dmd/identifier.h"
#include "dmd/module.h"
#include "dmd/mtype.h"
#include "dmd/target.h"

#include "tree.h"
#include "fold-const.h"
#include "diagnostic.h"
#include "langhooks.h"
#include "target.h"
#include "common/common-target.h"
#include "stringpool.h"
#include "stor-layout.h"
#include "builtins.h"

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


static GTY(()) vec <tree, va_gc> *gcc_builtins_functions = NULL;
static GTY(()) vec <tree, va_gc> *gcc_builtins_types = NULL;

/* Record built-in types and their associated decls for re-use when
   generating the `gcc.builtins' module.  */

struct builtin_data
{
  Type *dtype;
  tree ctype;
  Dsymbol *dsym;

  builtin_data (Type *t, tree c, Dsymbol *d = NULL)
    : dtype(t), ctype(c), dsym(d)
  { }
};

static vec <builtin_data> builtin_converted_decls;

/* Build D frontend type from tree TYPE type given.  This will set the
   back-end type symbol directly for complex types to save build_ctype()
   the work.  For other types, it is not useful or will cause errors, such
   as casting from `C char' to `D char', which also means that `char *`
   needs to be specially handled.  */

Type *
build_frontend_type (tree type)
{
  Type *dtype;
  MOD mod = 0;

  if (TYPE_READONLY (type))
    mod |= MODconst;
  if (TYPE_VOLATILE (type))
    mod |= MODshared;

  /* If we've seen the type before, re-use the converted decl.  */
  unsigned saved_builtin_decls_length = builtin_converted_decls.length ();
  for (size_t i = 0; i < saved_builtin_decls_length; ++i)
    {
      tree t = builtin_converted_decls[i].ctype;
      if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type))
	return builtin_converted_decls[i].dtype;
    }

  switch (TREE_CODE (type))
    {
    case POINTER_TYPE:
      dtype = build_frontend_type (TREE_TYPE (type));
      if (dtype)
	{
	  /* Check for char * first.  Needs to be done for chars/string.  */
	  if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)
	    return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);

	  if (dtype->ty == TY::Tfunction)
	    return (TypePointer::create (dtype))->addMod (mod);

	  return dtype->pointerTo ()->addMod (mod);
	}
      break;

    case REFERENCE_TYPE:
      dtype = build_frontend_type (TREE_TYPE (type));
      if (dtype)
	{
	  /* Want to assign ctype directly so that the REFERENCE_TYPE code
	     can be turned into as an `inout' argument.  Can't use pointerTo(),
	     because the returned Type is shared.  */
	  dtype = (TypePointer::create (dtype))->addMod (mod);
	  dtype->ctype = type;
	  builtin_converted_decls.safe_push (builtin_data (dtype, type));
	  return dtype;
	}
      break;

    case BOOLEAN_TYPE:
      /* Should be no need for size checking.  */
      return Type::tbool->addMod (mod);

    case INTEGER_TYPE:
    {
      unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
      bool unsignedp = TYPE_UNSIGNED (type);

      /* For now, skip support for cent/ucent until the frontend
	 has better support for handling it.  */
      for (size_t i = (size_t) TY::Tint8; i <= (size_t) TY::Tuns64; i++)
	{
	  dtype = Type::basic[i];

	  /* Search for type matching size and signedness.  */
	  if (unsignedp != dtype->isunsigned ()
	      || size != dtype->size ())
	    continue;

	  return dtype->addMod (mod);
	}
      break;
    }

    case REAL_TYPE:
    {
      unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));

      for (size_t i = (size_t) TY::Tfloat32; i <= (size_t) TY::Tfloat80; i++)
	{
	  dtype = Type::basic[i];

	  /* Search for type matching size.  */
	  if (dtype->size () != size)
	    continue;

	  return dtype->addMod (mod);
	}
      break;
    }

    case COMPLEX_TYPE:
    {
      unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
      for (size_t i = (size_t) TY::Tcomplex32; i <= (size_t) TY::Tcomplex80;
	   i++)
	{
	  dtype = Type::basic[i];

	  /* Search for type matching size.  */
	  if (dtype->size () != size)
	    continue;

	  return dtype->addMod (mod);
	}
      break;
    }

    case VOID_TYPE:
      return Type::tvoid->addMod (mod);

    case ARRAY_TYPE:
      dtype = build_frontend_type (TREE_TYPE (type));
      if (dtype)
	{
	  tree index = TYPE_DOMAIN (type);
	  tree ub = TYPE_MAX_VALUE (index);
	  tree lb = TYPE_MIN_VALUE (index);

	  tree length = fold_build2 (MINUS_EXPR, TREE_TYPE (lb), ub, lb);
	  length = size_binop (PLUS_EXPR, size_one_node,
			       convert (sizetype, length));

	  dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
	  builtin_converted_decls.safe_push (builtin_data (dtype, type));
	  return dtype;
	}
      break;

    case VECTOR_TYPE:
    {
      unsigned HOST_WIDE_INT nunits;
      if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits))
	break;

      dtype = build_frontend_type (TREE_TYPE (type));
      if (!dtype)
	break;

      dtype = dtype->sarrayOf (nunits)->addMod (mod);
      if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ()))
	break;

      dtype = (TypeVector::create (dtype))->addMod (mod);
      builtin_converted_decls.safe_push (builtin_data (dtype, type));
      return dtype;
    }

    case RECORD_TYPE:
    {
      Identifier *ident = TYPE_IDENTIFIER (type) ?
	Identifier::idPool (IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))) : NULL;

      /* Neither the `object' and `gcc.builtins' modules will not exist when
	 this is called.  Use a stub `object' module parent in the meantime.
	 If `gcc.builtins' is later imported, the parent will be overridden
	 with the correct module symbol.  */
      static Identifier *object = Identifier::idPool ("object");
      static Module *stubmod = Module::create ("object.d", object, 0, 0);

      StructDeclaration *sdecl = StructDeclaration::create (Loc (), ident,
							    false);
      sdecl->parent = stubmod;
      sdecl->structsize = int_size_in_bytes (type);
      sdecl->alignsize = TYPE_ALIGN_UNIT (type);
      sdecl->alignment.setDefault ();
      sdecl->sizeok = Sizeok::done;
      sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
      sdecl->type->ctype = type;
      sdecl->type->merge2 ();

      /* Add both named and anonymous fields as members of the struct.
	 Anonymous fields still need a name in D, so call them "__pad%u".  */
      unsigned anonfield_id = 0;
      sdecl->members = d_gc_malloc<Dsymbols> ();

      for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	{
	  Type *ftype = build_frontend_type (TREE_TYPE (field));
	  if (!ftype)
	    {
	      /* Drop any field types that got cached before the conversion
		 of this record type failed.  */
	      builtin_converted_decls.truncate (saved_builtin_decls_length);
	      return NULL;
	    }

	  Identifier *fident;
	  if (DECL_NAME (field) == NULL_TREE)
	    {
	      char name[16];
	      snprintf (name, sizeof (name), "__pad%u", anonfield_id++);
	      fident = Identifier::idPool (name);
	    }
	  else
	    {
	      const char *name = IDENTIFIER_POINTER (DECL_NAME (field));
	      fident = Identifier::idPool (name);
	    }

	  VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
						       NULL);
	  vd->parent = sdecl;
	  vd->offset = tree_to_uhwi (byte_position (field));
	  vd->semanticRun = PASS::semanticdone;
	  vd->csym = field;
	  sdecl->members->push (vd);
	  sdecl->fields.push (vd);
	}

      dtype = sdecl->type;
      builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));
      return dtype;
    }

    case FUNCTION_TYPE:
      dtype = build_frontend_type (TREE_TYPE (type));
      if (dtype)
	{
	  tree parms = TYPE_ARG_TYPES (type);
	  VarArg varargs_p = VARARGvariadic;

	  Parameters *args = d_gc_malloc<Parameters> ();
	  args->reserve (list_length (parms));

	  /* Attempt to convert all parameter types.  */
	  for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))
	    {
	      tree argtype = TREE_VALUE (parm);
	      if (argtype == void_type_node)
		{
		  varargs_p = VARARGnone;
		  break;
		}

	      StorageClass sc = STCundefined;
	      if (TREE_CODE (argtype) == REFERENCE_TYPE)
		{
		  argtype = TREE_TYPE (argtype);
		  sc |= STCref;
		}

	      Type *targ = build_frontend_type (argtype);
	      if (!targ)
		{
		  /* Drop any parameter types that got cached before the
		     conversion of this function type failed.  */
		  builtin_converted_decls.truncate (saved_builtin_decls_length);
		  return NULL;
		}

	      args->push (Parameter::create (sc, targ, NULL, NULL, NULL));
	    }

	  /* GCC generic and placeholder built-ins are marked as variadic, yet
	     have no named parameters, and so can't be represented in D.  */
	  if (args->length != 0 || varargs_p == VARARGnone)
	    {
	      dtype = TypeFunction::create (args, dtype, varargs_p, LINK::c);
	      return dtype->addMod (mod);
	    }
	}
      break;

    default:
      break;
    }

  return NULL;
}

/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
   LOC is the location in the source file where this CST is being evaluated.
   This is used for getting the CTFE value out of a const-folded builtin,
   returns NULL if it cannot convert CST.  */

Expression *
d_eval_constant_expression (const Loc &loc, tree cst)
{
  STRIP_TYPE_NOPS (cst);
  Type *type = build_frontend_type (TREE_TYPE (cst));

  if (type)
    {
      /* Convert our GCC CST tree into a D Expression.  This seems like we are
	 trying too hard, as these will only be converted back to a tree again
	 later in the codegen pass, but satisfies the need to have GCC built-ins
	 CTFE-able in the frontend.  */
      tree_code code = TREE_CODE (cst);
      if (code == COMPLEX_CST)
	{
	  real_value re = TREE_REAL_CST (TREE_REALPART (cst));
	  real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
	  complex_t value = complex_t (ldouble (re), ldouble (im));
	  return ComplexExp::create (loc, value, type);
	}
      else if (code == INTEGER_CST)
	{
	  dinteger_t value = TREE_INT_CST_LOW (cst);
	  return IntegerExp::create (loc, value, type);
	}
      else if (code == REAL_CST)
	{
	  real_value value = TREE_REAL_CST (cst);
	  return RealExp::create (loc, ldouble (value), type);
	}
      else if (code == STRING_CST)
	{
	  const void *string = TREE_STRING_POINTER (cst);
	  size_t len = TREE_STRING_LENGTH (cst) - 1;
	  return StringExp::create (loc, CONST_CAST (void *, string), len);
	}
      else if (code == VECTOR_CST)
	{
	  dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant ();
	  Expressions *elements = d_gc_malloc<Expressions> ();
	  elements->setDim (nunits);

	  for (size_t i = 0; i < nunits; i++)
	    {
	      Expression *elem
		= d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
	      if (elem == NULL)
		return NULL;

	      (*elements)[i] = elem;
	    }

	  Expression *e = ArrayLiteralExp::create (loc, elements);
	  e->type = type->isTypeVector ()->basetype;

	  return VectorExp::create (loc, e, type);
	}
      else if (code == ADDR_EXPR)
	{
	  /* Special handling for trees constructed by build_string_literal.
	     What we receive is an `&"string"[0]' expression, strip off the
	     outer ADDR_EXPR and ARRAY_REF to get to the underlying CST.  */
	  tree pointee = TREE_OPERAND (cst, 0);

	  if (TREE_CODE (pointee) != ARRAY_REF
	      || TREE_OPERAND (pointee, 1) != integer_zero_node
	      || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
	    return NULL;

	  return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
	}
    }

  return NULL;
}

/* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.
   Adds IDENT to the list of predefined version identifiers.  */

void
d_add_builtin_version (const char* ident)
{
  VersionCondition::addPredefinedGlobalIdent (ident);
}

/* Initialize the list of all the predefined version identifiers.  */

void
d_init_versions (void)
{
  VersionCondition::addPredefinedGlobalIdent ("GNU");
  VersionCondition::addPredefinedGlobalIdent ("D_Version2");

  if (BYTES_BIG_ENDIAN)
    VersionCondition::addPredefinedGlobalIdent ("BigEndian");
  else
    VersionCondition::addPredefinedGlobalIdent ("LittleEndian");

  if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
    VersionCondition::addPredefinedGlobalIdent ("GNU_SjLj_Exceptions");
  else if (targetm_common.except_unwind_info (&global_options) == UI_SEH)
    VersionCondition::addPredefinedGlobalIdent ("GNU_SEH_Exceptions");
  else if (targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
    VersionCondition::addPredefinedGlobalIdent ("GNU_DWARF2_Exceptions");

  if (!targetm.have_tls)
    VersionCondition::addPredefinedGlobalIdent ("GNU_EMUTLS");

  if (STACK_GROWS_DOWNWARD)
    VersionCondition::addPredefinedGlobalIdent ("GNU_StackGrowsDown");

  /* Should define this anyway to set us apart from the competition.  */
  VersionCondition::addPredefinedGlobalIdent ("GNU_InlineAsm");

  /* LP64 only means 64bit pointers in D.  */
  if (POINTER_SIZE == 64)
    VersionCondition::addPredefinedGlobalIdent ("D_LP64");

  /* Setting `global.params.cov' forces module info generation which is
     not needed for the GCC coverage implementation.  Instead, just
     test flag_test_coverage while leaving `global.params.cov' unset.  */
  if (flag_test_coverage)
    VersionCondition::addPredefinedGlobalIdent ("D_Coverage");
  if (flag_pic)
    VersionCondition::addPredefinedGlobalIdent ("D_PIC");
  if (flag_pie)
    VersionCondition::addPredefinedGlobalIdent ("D_PIE");

  if (global.params.ddoc.doOutput)
    VersionCondition::addPredefinedGlobalIdent ("D_Ddoc");

  if (global.params.useUnitTests)
    VersionCondition::addPredefinedGlobalIdent ("unittest");

  if (global.params.useAssert == CHECKENABLEon)
    VersionCondition::addPredefinedGlobalIdent ("assert");

  if (global.params.useIn == CHECKENABLEon)
    VersionCondition::addPredefinedGlobalIdent("D_PreConditions");

  if (global.params.useOut == CHECKENABLEon)
    VersionCondition::addPredefinedGlobalIdent("D_PostConditions");

  if (global.params.useInvariants == CHECKENABLEon)
    VersionCondition::addPredefinedGlobalIdent("D_Invariants");

  if (global.params.useArrayBounds == CHECKENABLEoff)
    VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");

  if (global.params.betterC)
    VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
  else
    {
      VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
      VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
      VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
    }

  VersionCondition::addPredefinedGlobalIdent ("all");

  /* Emit all target-specific version identifiers.  */
  targetdm.d_cpu_versions ();
  targetdm.d_os_versions ();

  VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
}

/* A helper for d_build_builtins_module.  Return a new ALIAS for TYPE.
   Analogous to `alias ALIAS = TYPE' in D code.  */

static AliasDeclaration *
build_alias_declaration (const char *alias, Type *type)
{
  return AliasDeclaration::create (Loc (), Identifier::idPool (alias), type);
}

/* A helper function for Target::loadModule.  Generates all code for the
   `gcc.builtins' module, whose frontend symbol should be M.  */

void
d_build_builtins_module (Module *m)
{
  Dsymbols *members = d_gc_malloc<Dsymbols> ();
  tree decl;

  for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i)
    {
      const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
      Type *t = build_frontend_type (TREE_TYPE (decl));
      TypeFunction *tf = t ? t->isTypeFunction () : NULL;

      /* Cannot create built-in function type for DECL.  */
      if (!tf)
	continue;

      /* A few notes on D2 attributes applied to builtin functions:
	 - It is assumed that built-ins solely provided by the compiler are
	   considered @safe and pure.
	 - Built-ins that correspond to `extern(C)' functions in the standard
	   library that have `__attribute__(nothrow)' are considered `@trusted'.
	 - The purity of a built-in can vary depending on compiler flags set
	   upon initialization, or by the `-foptions' passed, such as
	   flag_unsafe_math_optimizations.
	 - Built-ins never use the GC or raise a D exception, and so are always
	   marked as `nothrow' and `@nogc'.  */
      tf->purity = DECL_PURE_P (decl) ? PURE::const_
	: TREE_READONLY (decl) ? PURE::const_
	: DECL_IS_NOVOPS (decl) ? PURE::weak
	: !DECL_ASSEMBLER_NAME_SET_P (decl) ? PURE::weak
	: PURE::impure;
      tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUST::safe
	: TREE_NOTHROW (decl) ? TRUST::trusted
	: TRUST::system;
      tf->isnothrow (true);
      tf->isnogc (true);

      FuncDeclaration *func
	= FuncDeclaration::create (Loc (), Loc (),
				   Identifier::idPool (name),
				   STCextern, tf);
      DECL_LANG_SPECIFIC (decl) = build_lang_decl (func);
      func->csym = decl;
      func->builtin = BUILTIN::gcc;

      members->push (func);
    }

  for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i)
    {
      const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
      Type *t = build_frontend_type (TREE_TYPE (decl));

      /* Cannot create built-in type for DECL.  */
      if (!t)
	continue;

      members->push (build_alias_declaration (name, t));
    }

  /* Iterate through the target-specific builtin types for va_list.  */
  if (targetm.enum_va_list_p)
    {
      const char *name;
      tree type;

      for (int i = 0; targetm.enum_va_list_p (i, &name, &type); ++i)
	{
	  Type *t = build_frontend_type (type);
	  /* Cannot create built-in type.  */
	  if (!t)
	    continue;

	  members->push (build_alias_declaration (name, t));
	}
    }

  /* Push out declarations for any RECORD_TYPE types encountered when building
     all builtin functions and types.  */
  for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
    {
      /* Currently, there is no need to run semantic, but we do want to output
	 initializers, typeinfo, and others on demand.  */
      Dsymbol *dsym = builtin_converted_decls[i].dsym;
      if (dsym != NULL && !dsym->isAnonymous ())
	{
	  dsym->parent = m;
	  members->push (dsym);
	}
    }

  /* Expose target-specific va_list type.  */
  Type *tvalist = target.va_listType (Loc (), NULL);
  TypeStruct *ts = tvalist->isTypeStruct ();
  if (ts == NULL || !ts->sym->isAnonymous ())
    members->push (build_alias_declaration ("__builtin_va_list", tvalist));
  else
    {
      ts->sym->ident = Identifier::idPool ("__builtin_va_list");
      members->push (ts->sym);
    }

  /* Expose target-specific integer types to the builtins module.  */
  {
    Type *t = build_frontend_type (long_integer_type_node);
    members->push (build_alias_declaration ("__builtin_clong", t));

    t = build_frontend_type (long_unsigned_type_node);
    members->push (build_alias_declaration ("__builtin_culong", t));

    t = build_frontend_type (long_long_integer_type_node);
    members->push (build_alias_declaration ("__builtin_clonglong", t));

    t = build_frontend_type (long_long_unsigned_type_node);
    members->push (build_alias_declaration ("__builtin_culonglong", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 0));
    members->push (build_alias_declaration ("__builtin_machine_byte", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 1));
    members->push (build_alias_declaration ("__builtin_machine_ubyte", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 0));
    members->push (build_alias_declaration ("__builtin_machine_int", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 1));
    members->push (build_alias_declaration ("__builtin_machine_uint", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 0));
    members->push (build_alias_declaration ("__builtin_pointer_int", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 1));
    members->push (build_alias_declaration ("__builtin_pointer_uint", t));

    /* _Unwind_Word has its own target specific mode.  */
    machine_mode mode = targetm.unwind_word_mode ();
    t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 0));
    members->push (build_alias_declaration ("__builtin_unwind_int", t));

    t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 1));
    members->push (build_alias_declaration ("__builtin_unwind_uint", t));
  }

  m->members->push (LinkDeclaration::create (Loc (), LINK::c, members));
}

/* Remove all type modifiers from TYPE, returning the naked type.  */

static Type *
strip_type_modifiers (Type *type)
{
  if (type->ty == TY::Tpointer)
    {
      Type *tnext = strip_type_modifiers (type->nextOf ());
      return tnext->pointerTo ();
    }

  return type->castMod (0);
}

/* Returns true if types T1 and T2 representing return types or types of
   function arguments are close enough to be considered interchangeable.  */

static bool
matches_builtin_type (Type *t1, Type *t2)
{
  Type *tb1 = strip_type_modifiers (t1);
  Type *tb2 = strip_type_modifiers (t2);

  if (same_type_p (t1, t2))
    return true;

  if (((tb1->isTypePointer () && tb2->isTypePointer ())
       || (tb1->isTypeVector () && tb2->isTypeVector ()))
      && tb1->implicitConvTo (tb2) != MATCH::nomatch)
    return true;

  if (tb1->isintegral () == tb2->isintegral ()
      && tb1->size () == tb2->size ())
    return true;

  return false;
}

/* Check whether the declared function type T1 is covariant with the built-in
   function type T2.  Returns true if they are covariant.  */

static bool
covariant_with_builtin_type_p (Type *t1, Type *t2)
{
  /* Check whether the declared function matches the built-in.  */
  if (same_type_p (t1, t2) || t1->covariant (t2) == Covariant::yes)
    return true;

  /* May not be covariant because of D attributes applied on t1.
     Strip them all off and compare again.  */
  TypeFunction *tf1 = t1->isTypeFunction ();
  TypeFunction *tf2 = t2->isTypeFunction ();

  /* Check for obvious reasons why types may be distinct.  */
  if (tf1 == NULL || tf2 == NULL
      || tf1->isref () != tf2->isref ()
      || tf1->parameterList.varargs != tf2->parameterList.varargs
      || tf1->parameterList.length () != tf2->parameterList.length ())
    return false;

  /* Check return type and each parameter type for mismatch.  */
  if (!matches_builtin_type (tf1->next, tf2->next))
    return false;

  const size_t nparams = tf1->parameterList.length ();
  for (size_t i = 0; i < nparams; i++)
    {
      Parameter *fparam1 = tf1->parameterList[i];
      Parameter *fparam2 = tf2->parameterList[i];

      if (fparam1->isReference () != fparam2->isReference ()
	  || fparam1->isLazy () != fparam2->isLazy ())
	return false;

      if (!matches_builtin_type (fparam1->type, fparam2->type))
	return false;
    }

  return true;
}

/* Search for any `extern(C)' functions that match any known GCC library builtin
   function in D and override its internal back-end symbol.  */

static void
maybe_set_builtin_1 (Dsymbol *d)
{
  AttribDeclaration *ad = d->isAttribDeclaration ();
  FuncDeclaration *fd = d->isFuncDeclaration ();

  if (ad != NULL)
    {
      /* Recursively search through attribute decls.  */
      Dsymbols *decls = ad->include (NULL);
      if (decls && decls->length)
	{
	  for (size_t i = 0; i < decls->length; i++)
	    {
	      Dsymbol *sym = (*decls)[i];
	      maybe_set_builtin_1 (sym);
	    }
	}
    }
  else if (fd && !fd->fbody && fd->resolvedLinkage () == LINK::c)
    {
      tree ident = get_identifier (fd->ident->toChars ());
      tree decl = IDENTIFIER_DECL_TREE (ident);

      if (decl && TREE_CODE (decl) == FUNCTION_DECL
	  && DECL_ASSEMBLER_NAME_SET_P (decl)
	  && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
	{
	  /* Found a match, tell the frontend this is a builtin.  */
	  DECL_LANG_SPECIFIC (decl) = build_lang_decl (fd);
	  fd->csym = decl;
	  fd->builtin = BUILTIN::gcc;

	  /* Copy front-end attributes to the builtin.  */
	  apply_user_attributes (fd, fd->csym);

	  /* Function has `pragma(mangle)' specified, override its name.  */
	  if (fd->mangleOverride.length)
	    {
	      tree mangle =
		get_identifier_with_length (fd->mangleOverride.ptr,
					    fd->mangleOverride.length);
	      const char *asmname = IDENTIFIER_POINTER (mangle);
	      set_builtin_user_assembler_name (decl, asmname);
	    }

	  /* Warn when return and argument types of the user defined function is
	     not covariant with the built-in function type.  */
	  if (Type *type = build_frontend_type (TREE_TYPE (decl)))
	    {
	      if (!covariant_with_builtin_type_p (fd->type, type))
		{
		  warning_at (make_location_t (fd->loc),
			      OPT_Wbuiltin_declaration_mismatch,
			      "conflicting types for built-in function %qs; "
			      "expected %qs",
			      fd->toChars (), type->toChars ());
		}
	    }
	}
    }
}

/* A helper function for Target::loadModule.  Traverse all members in module M
   to search for any functions that can be mapped to any GCC builtin.  */

void
d_maybe_set_builtin (Module *m)
{
  if (!m || !m->members)
    return;

  for (size_t i = 0; i < m->members->length; i++)
    {
      Dsymbol *sym = (*m->members)[i];
      maybe_set_builtin_1 (sym);
    }
}

/* Used to help initialize the builtin-types.def table.  When a type of
   the correct size doesn't exist, use error_mark_node instead of NULL.
   The latter results in segfaults even when a decl using the type doesn't
   get invoked.  */

static tree
builtin_type_for_size (int size, bool unsignedp)
{
  tree type = lang_hooks.types.type_for_size (size, unsignedp);
  return type ? type : error_mark_node;
}

/* Support for DEF_BUILTIN.  */

static void
do_build_builtin_fn (built_in_function fncode,
		     const char *name,
		     built_in_class fnclass,
		     tree fntype, bool both_p, bool fallback_p,
		     tree fnattrs, bool implicit_p)
{
  tree decl;
  const char *libname;

  if (fntype == error_mark_node)
    return;

  gcc_assert ((!both_p && !fallback_p)
	      || startswith (name, "__builtin_"));

  libname = name + strlen ("__builtin_");

  decl = add_builtin_function (name, fntype, fncode, fnclass,
			       fallback_p ? libname : NULL, fnattrs);

  set_builtin_decl (fncode, decl, implicit_p);
}

/* Standard data types to be used in builtin argument declarations.  */

static GTY(()) tree string_type_node;
static GTY(()) tree const_string_type_node;
static GTY(()) tree wint_type_node;
static GTY(()) tree intmax_type_node;
static GTY(()) tree uintmax_type_node;
static GTY(()) tree signed_size_type_node;


/* Build nodes that would have been created by the C front-end; necessary
   for including builtin-types.def and ultimately builtins.def.  */

static void
d_build_c_type_nodes (void)
{
  string_type_node = build_pointer_type (char_type_node);
  const_string_type_node
    = build_pointer_type (build_qualified_type (char_type_node,
						TYPE_QUAL_CONST));

  if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
    {
      intmax_type_node = integer_type_node;
      uintmax_type_node = unsigned_type_node;
    }
  else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
    {
      intmax_type_node = long_integer_type_node;
      uintmax_type_node = long_unsigned_type_node;
    }
  else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
    {
      intmax_type_node = long_long_integer_type_node;
      uintmax_type_node = long_long_unsigned_type_node;
    }
  else
    gcc_unreachable ();

  signed_size_type_node = signed_type_for (size_type_node);
  wint_type_node = unsigned_type_node;
  pid_type_node = integer_type_node;
}

/* Build nodes that are used by the D front-end.
   These are distinct from C types.  */

static void
d_build_d_type_nodes (void)
{
  /* Integral types.  */
  d_byte_type = make_signed_type (8);
  d_ubyte_type = make_unsigned_type (8);

  d_short_type = make_signed_type (16);
  d_ushort_type = make_unsigned_type (16);

  d_int_type = make_signed_type (32);
  d_uint_type = make_unsigned_type (32);

  d_long_type = make_signed_type (64);
  d_ulong_type = make_unsigned_type (64);

  d_cent_type = make_signed_type (128);
  d_ucent_type = make_unsigned_type (128);

  {
    /* Re-define size_t as a D type.  */
    machine_mode type_mode = TYPE_MODE (size_type_node);
    size_type_node = lang_hooks.types.type_for_mode (type_mode, 1);
  }

  /* Bool and Character types.  */
  d_bool_type = make_unsigned_type (1);
  TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);

  char8_type_node = make_unsigned_type (8);
  TYPE_STRING_FLAG (char8_type_node) = 1;

  char16_type_node = make_unsigned_type (16);
  TYPE_STRING_FLAG (char16_type_node) = 1;

  char32_type_node = make_unsigned_type (32);
  TYPE_STRING_FLAG (char32_type_node) = 1;

  /* Imaginary types.  */
  ifloat_type_node = build_distinct_type_copy (float_type_node);
  TYPE_IMAGINARY_FLOAT (ifloat_type_node) = 1;

  idouble_type_node = build_distinct_type_copy (double_type_node);
  TYPE_IMAGINARY_FLOAT (idouble_type_node) = 1;

  ireal_type_node = build_distinct_type_copy (long_double_type_node);
  TYPE_IMAGINARY_FLOAT (ireal_type_node) = 1;

  /* Noreturn type.  */
  noreturn_type_node = build_distinct_type_copy (void_type_node);

  /* Calling build_ctype() links the front-end Type to the GCC node,
     and sets the TYPE_NAME to the D language type.  */
  for (unsigned ty = 0; ty < (unsigned) TY::TMAX; ty++)
    {
      if (Type::basic[ty] != NULL)
	build_ctype (Type::basic[ty]);
    }

  /* Used for ModuleInfo, ClassInfo, and Interface decls.  */
  unknown_type_node = make_node (RECORD_TYPE);

  /* Make sure we get a unique function type, so we can give
     its pointer type a name.  (This wins for gdb).  */
  {
    tree vfunc_type = make_node (FUNCTION_TYPE);
    TREE_TYPE (vfunc_type) = d_int_type;
    TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
    layout_type (vfunc_type);

    vtable_entry_type = build_pointer_type (vfunc_type);
  }

  vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
  layout_type (vtbl_ptr_type_node);

  /* When an object is accessed via an interface, this type appears
     as the first entry in its vtable.  */
  {
    tree domain = build_index_type (size_int (3));
    vtbl_interface_type_node = build_array_type (ptr_type_node, domain);
  }

  /* Use `void[]' as a generic dynamic array type.  */
  array_type_node = make_struct_type ("__builtin_void[]", 2,
				      get_identifier ("length"), size_type_node,
				      get_identifier ("ptr"), ptr_type_node);
  TYPE_DYNAMIC_ARRAY (array_type_node) = 1;

  null_array_node = d_array_value (array_type_node, size_zero_node,
				   null_pointer_node);
}

/* Handle default attributes.  */

enum built_in_attribute
{
#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
#define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
#include "builtin-attrs.def"
#undef DEF_ATTR_NULL_TREE
#undef DEF_ATTR_INT
#undef DEF_ATTR_STRING
#undef DEF_ATTR_IDENT
#undef DEF_ATTR_TREE_LIST
  ATTR_LAST
};

static GTY(()) tree built_in_attributes[(int) ATTR_LAST];

/* Initialize the attribute table for all the supported builtins.  */

static void
d_init_attributes (void)
{
  /* Fill in the built_in_attributes array.  */
#define DEF_ATTR_NULL_TREE(ENUM)	\
  built_in_attributes[(int) ENUM] = NULL_TREE;
# define DEF_ATTR_INT(ENUM, VALUE)	\
  built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
#define DEF_ATTR_STRING(ENUM, VALUE)	\
  built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
#define DEF_ATTR_IDENT(ENUM, STRING)	\
  built_in_attributes[(int) ENUM] = get_identifier (STRING);
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)	\
  built_in_attributes[(int) ENUM]			\
  = tree_cons (built_in_attributes[(int) PURPOSE],	\
	       built_in_attributes[(int) VALUE],	\
	       built_in_attributes[(int) CHAIN]);
#include "builtin-attrs.def"
#undef DEF_ATTR_NULL_TREE
#undef DEF_ATTR_INT
#undef DEF_ATTR_STRING
#undef DEF_ATTR_IDENT
#undef DEF_ATTR_TREE_LIST
}

/* Builtin types.  */

enum d_builtin_type
{
#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6) NAME,
#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7) NAME,
#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7, ARG8) NAME,
#define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7, ARG8, ARG9) NAME,
#define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			     ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
#define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			     ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
				NAME,
#define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
				ARG6) NAME,
#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
				ARG6, ARG7) NAME,
#define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
				 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
#include "builtin-types.def"
#undef DEF_PRIMITIVE_TYPE
#undef DEF_FUNCTION_TYPE_0
#undef DEF_FUNCTION_TYPE_1
#undef DEF_FUNCTION_TYPE_2
#undef DEF_FUNCTION_TYPE_3
#undef DEF_FUNCTION_TYPE_4
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_9
#undef DEF_FUNCTION_TYPE_10
#undef DEF_FUNCTION_TYPE_11
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_6
#undef DEF_FUNCTION_TYPE_VAR_7
#undef DEF_FUNCTION_TYPE_VAR_11
#undef DEF_POINTER_TYPE
  BT_LAST
};

typedef enum d_builtin_type builtin_type;

/* A temporary array used in communication with def_fn_type.  */
static GTY(()) tree builtin_types[(int) BT_LAST + 1];

/* A helper function for d_init_builtins.  Build function type for DEF with
   return type RET and N arguments.  If VAR is true, then the function should
   be variadic after those N arguments.

   Takes special care not to ICE if any of the types involved are
   error_mark_node, which indicates that said type is not in fact available
   (see builtin_type_for_size).  In which case the function type as a whole
   should be error_mark_node.  */

static void
def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
{
  tree t;
  tree *args = XALLOCAVEC (tree, n);
  va_list list;
  int i;

  va_start (list, n);
  for (i = 0; i < n; ++i)
    {
      builtin_type a = (builtin_type) va_arg (list, int);
      t = builtin_types[a];
      if (t == error_mark_node)
	goto egress;
      args[i] = t;
    }

  t = builtin_types[ret];
  if (t == error_mark_node)
    goto egress;
  if (var)
    t = build_varargs_function_type_array (t, n, args);
  else
    t = build_function_type_array (t, n, args);

 egress:
  builtin_types[def] = t;
  va_end (list);
}

/* Create builtin types and functions.  VA_LIST_REF_TYPE_NODE and
   VA_LIST_ARG_TYPE_NODE are used in builtin-types.def.  */

static void
d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
		   tree va_list_arg_type_node ATTRIBUTE_UNUSED)
{
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
  builtin_types[(int) ENUM] = VALUE;
#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
  def_fn_type (ENUM, RETURN, 0, 0);
#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
  def_fn_type (ENUM, RETURN, 0, 1, ARG1);
#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
  def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
  def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
  def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
  def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6)					\
  def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7)					\
  def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7, ARG8)				\
  def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
	       ARG7, ARG8);
#define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7, ARG8, ARG9)			\
  def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
	       ARG7, ARG8, ARG9);
#define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7, ARG8, ARG9, ARG10)		 \
  def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
	       ARG7, ARG8, ARG9, ARG10);
#define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
			    ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)	 \
  def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
	       ARG7, ARG8, ARG9, ARG10, ARG11);
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
  def_fn_type (ENUM, RETURN, 1, 0);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
  def_fn_type (ENUM, RETURN, 1, 1, ARG1);
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
  def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
  def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
  def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
  def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
#define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
				ARG6)					    \
  def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
				ARG6, ARG7)				    \
  def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
#define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
				 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)       \
  def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,      \
	       ARG7, ARG8, ARG9, ARG10, ARG11);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
  builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);

#include "builtin-types.def"

#undef DEF_PRIMITIVE_TYPE
#undef DEF_FUNCTION_TYPE_1
#undef DEF_FUNCTION_TYPE_2
#undef DEF_FUNCTION_TYPE_3
#undef DEF_FUNCTION_TYPE_4
#undef DEF_FUNCTION_TYPE_5
#undef DEF_FUNCTION_TYPE_6
#undef DEF_FUNCTION_TYPE_7
#undef DEF_FUNCTION_TYPE_8
#undef DEF_FUNCTION_TYPE_9
#undef DEF_FUNCTION_TYPE_10
#undef DEF_FUNCTION_TYPE_11
#undef DEF_FUNCTION_TYPE_VAR_0
#undef DEF_FUNCTION_TYPE_VAR_1
#undef DEF_FUNCTION_TYPE_VAR_2
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
#undef DEF_FUNCTION_TYPE_VAR_6
#undef DEF_FUNCTION_TYPE_VAR_7
#undef DEF_FUNCTION_TYPE_VAR_11
#undef DEF_POINTER_TYPE
  builtin_types[(int) BT_LAST] = NULL_TREE;

  d_init_attributes ();

#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
		    NONANSI_P, ATTRS, IMPLICIT, COND)			  \
  if (NAME && COND)							  \
    do_build_builtin_fn (ENUM, NAME, CLASS,				  \
			 builtin_types[(int) TYPE],			  \
			 BOTH_P, FALLBACK_P,				  \
			 built_in_attributes[(int) ATTRS], IMPLICIT);
#include "builtins.def"
#undef DEF_BUILTIN
}

/* Build builtin functions and types for the D language frontend.  */

void
d_init_builtins (void)
{
  d_build_c_type_nodes ();
  d_build_d_type_nodes ();

  if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
    {
      /* It might seem natural to make the argument type a pointer, but there
	 is no implicit casting from arrays to pointers in D.  */
      d_define_builtins (va_list_type_node, va_list_type_node);
    }
  else
    {
      d_define_builtins (build_reference_type (va_list_type_node),
			 va_list_type_node);
    }

  targetm.init_builtins ();
  build_common_builtin_nodes ();
}

/* Registration of machine- or os-specific builtin types.
   Add to builtin types list for maybe processing later
   if `gcc.builtins' was imported into the current module.  */

void
d_register_builtin_type (tree type, const char *name)
{
  tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
			  get_identifier (name), type);
  DECL_ARTIFICIAL (decl) = 1;

  if (!TYPE_NAME (type))
    TYPE_NAME (type) = decl;

  vec_safe_push (gcc_builtins_types, decl);
}

/* Add DECL to builtin functions list for maybe processing later
   if `gcc.builtins' was imported into the current module.  */

tree
d_builtin_function (tree decl)
{
  if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))
    {
      /* Associate the assembler identifier with the built-in.  */
      tree ident = DECL_ASSEMBLER_NAME (decl);
      IDENTIFIER_DECL_TREE (ident) = decl;
    }

  vec_safe_push (gcc_builtins_functions, decl);
  return decl;
}

/* Same as d_builtin_function, but used to delay putting in back-end builtin
   functions until the ISA that defines the builtin has been declared.
   However in D, there is no global namespace.  All builtins get pushed into the
   `gcc.builtins' module, which is constructed during the semantic analysis
   pass, which has already finished by the time target attributes are evaluated.
   So builtins are not pushed because they would be ultimately ignored.
   The purpose of having this function then is to improve compile-time
   reflection support to allow user-code to determine whether a given back end
   function is enabled by the ISA.  */

tree
d_builtin_function_ext_scope (tree decl)
{
  return decl;
}

#include "gt-d-d-builtins.h"
