Home | History | Annotate | Line # | Download | only in d
      1 /* d-builtins.cc -- GCC builtins support for D.
      2    Copyright (C) 2006-2022 Free Software Foundation, Inc.
      3 
      4 GCC is free software; you can redistribute it and/or modify
      5 it under the terms of the GNU General Public License as published by
      6 the Free Software Foundation; either version 3, or (at your option)
      7 any later version.
      8 
      9 GCC is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with GCC; see the file COPYING3.  If not see
     16 <http://www.gnu.org/licenses/>.  */
     17 
     18 #include "config.h"
     19 #include "system.h"
     20 #include "coretypes.h"
     21 
     22 #include "dmd/attrib.h"
     23 #include "dmd/aggregate.h"
     24 #include "dmd/cond.h"
     25 #include "dmd/declaration.h"
     26 #include "dmd/expression.h"
     27 #include "dmd/identifier.h"
     28 #include "dmd/module.h"
     29 #include "dmd/mtype.h"
     30 #include "dmd/target.h"
     31 
     32 #include "tree.h"
     33 #include "fold-const.h"
     34 #include "diagnostic.h"
     35 #include "langhooks.h"
     36 #include "target.h"
     37 #include "common/common-target.h"
     38 #include "stringpool.h"
     39 #include "stor-layout.h"
     40 
     41 #include "d-tree.h"
     42 #include "d-frontend.h"
     43 #include "d-target.h"
     44 
     45 
     46 static GTY(()) vec <tree, va_gc> *gcc_builtins_functions = NULL;
     47 static GTY(()) vec <tree, va_gc> *gcc_builtins_libfuncs = NULL;
     48 static GTY(()) vec <tree, va_gc> *gcc_builtins_types = NULL;
     49 
     50 /* Record built-in types and their associated decls for re-use when
     51    generating the `gcc.builtins' module.  */
     52 
     53 struct builtin_data
     54 {
     55   Type *dtype;
     56   tree ctype;
     57   Dsymbol *dsym;
     58 
     59   builtin_data (Type *t, tree c, Dsymbol *d = NULL)
     60     : dtype(t), ctype(c), dsym(d)
     61   { }
     62 };
     63 
     64 static vec <builtin_data> builtin_converted_decls;
     65 
     66 /* Build D frontend type from tree TYPE type given.  This will set the
     67    back-end type symbol directly for complex types to save build_ctype()
     68    the work.  For other types, it is not useful or will cause errors, such
     69    as casting from `C char' to `D char', which also means that `char *`
     70    needs to be specially handled.  */
     71 
     72 Type *
     73 build_frontend_type (tree type)
     74 {
     75   Type *dtype;
     76   MOD mod = 0;
     77 
     78   if (TYPE_READONLY (type))
     79     mod |= MODconst;
     80   if (TYPE_VOLATILE (type))
     81     mod |= MODshared;
     82 
     83   /* If we've seen the type before, re-use the converted decl.  */
     84   unsigned saved_builtin_decls_length = builtin_converted_decls.length ();
     85   for (size_t i = 0; i < saved_builtin_decls_length; ++i)
     86     {
     87       tree t = builtin_converted_decls[i].ctype;
     88       if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type))
     89 	return builtin_converted_decls[i].dtype;
     90     }
     91 
     92   switch (TREE_CODE (type))
     93     {
     94     case POINTER_TYPE:
     95       dtype = build_frontend_type (TREE_TYPE (type));
     96       if (dtype)
     97 	{
     98 	  /* Check for char * first.  Needs to be done for chars/string.  */
     99 	  if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)
    100 	    return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);
    101 
    102 	  if (dtype->ty == TY::Tfunction)
    103 	    return (TypePointer::create (dtype))->addMod (mod);
    104 
    105 	  return dtype->pointerTo ()->addMod (mod);
    106 	}
    107       break;
    108 
    109     case REFERENCE_TYPE:
    110       dtype = build_frontend_type (TREE_TYPE (type));
    111       if (dtype)
    112 	{
    113 	  /* Want to assign ctype directly so that the REFERENCE_TYPE code
    114 	     can be turned into as an `inout' argument.  Can't use pointerTo(),
    115 	     because the returned Type is shared.  */
    116 	  dtype = (TypePointer::create (dtype))->addMod (mod);
    117 	  dtype->ctype = type;
    118 	  builtin_converted_decls.safe_push (builtin_data (dtype, type));
    119 	  return dtype;
    120 	}
    121       break;
    122 
    123     case BOOLEAN_TYPE:
    124       /* Should be no need for size checking.  */
    125       return Type::tbool->addMod (mod);
    126 
    127     case INTEGER_TYPE:
    128     {
    129       unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
    130       bool unsignedp = TYPE_UNSIGNED (type);
    131 
    132       /* For now, skip support for cent/ucent until the frontend
    133 	 has better support for handling it.  */
    134       for (size_t i = (size_t) TY::Tint8; i <= (size_t) TY::Tuns64; i++)
    135 	{
    136 	  dtype = Type::basic[i];
    137 
    138 	  /* Search for type matching size and signedness.  */
    139 	  if (unsignedp != dtype->isunsigned ()
    140 	      || size != dtype->size ())
    141 	    continue;
    142 
    143 	  return dtype->addMod (mod);
    144 	}
    145       break;
    146     }
    147 
    148     case REAL_TYPE:
    149     {
    150       unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
    151 
    152       for (size_t i = (size_t) TY::Tfloat32; i <= (size_t) TY::Tfloat80; i++)
    153 	{
    154 	  dtype = Type::basic[i];
    155 
    156 	  /* Search for type matching size.  */
    157 	  if (dtype->size () != size)
    158 	    continue;
    159 
    160 	  return dtype->addMod (mod);
    161 	}
    162       break;
    163     }
    164 
    165     case COMPLEX_TYPE:
    166     {
    167       unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
    168       for (size_t i = (size_t) TY::Tcomplex32; i <= (size_t) TY::Tcomplex80;
    169 	   i++)
    170 	{
    171 	  dtype = Type::basic[i];
    172 
    173 	  /* Search for type matching size.  */
    174 	  if (dtype->size () != size)
    175 	    continue;
    176 
    177 	  return dtype->addMod (mod);
    178 	}
    179       break;
    180     }
    181 
    182     case VOID_TYPE:
    183       return Type::tvoid->addMod (mod);
    184 
    185     case ARRAY_TYPE:
    186       dtype = build_frontend_type (TREE_TYPE (type));
    187       if (dtype)
    188 	{
    189 	  tree index = TYPE_DOMAIN (type);
    190 	  tree ub = TYPE_MAX_VALUE (index);
    191 	  tree lb = TYPE_MIN_VALUE (index);
    192 
    193 	  tree length = fold_build2 (MINUS_EXPR, TREE_TYPE (lb), ub, lb);
    194 	  length = size_binop (PLUS_EXPR, size_one_node,
    195 			       convert (sizetype, length));
    196 
    197 	  dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
    198 	  builtin_converted_decls.safe_push (builtin_data (dtype, type));
    199 	  return dtype;
    200 	}
    201       break;
    202 
    203     case VECTOR_TYPE:
    204     {
    205       unsigned HOST_WIDE_INT nunits;
    206       if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits))
    207 	break;
    208 
    209       dtype = build_frontend_type (TREE_TYPE (type));
    210       if (!dtype)
    211 	break;
    212 
    213       dtype = dtype->sarrayOf (nunits)->addMod (mod);
    214       if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ()))
    215 	break;
    216 
    217       dtype = (TypeVector::create (dtype))->addMod (mod);
    218       builtin_converted_decls.safe_push (builtin_data (dtype, type));
    219       return dtype;
    220     }
    221 
    222     case RECORD_TYPE:
    223     {
    224       Identifier *ident = TYPE_IDENTIFIER (type) ?
    225 	Identifier::idPool (IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))) : NULL;
    226 
    227       /* Neither the `object' and `gcc.builtins' modules will not exist when
    228 	 this is called.  Use a stub `object' module parent in the meantime.
    229 	 If `gcc.builtins' is later imported, the parent will be overridden
    230 	 with the correct module symbol.  */
    231       static Identifier *object = Identifier::idPool ("object");
    232       static Module *stubmod = Module::create ("object.d", object, 0, 0);
    233 
    234       StructDeclaration *sdecl = StructDeclaration::create (Loc (), ident,
    235 							    false);
    236       sdecl->parent = stubmod;
    237       sdecl->structsize = int_size_in_bytes (type);
    238       sdecl->alignsize = TYPE_ALIGN_UNIT (type);
    239       sdecl->alignment.setDefault ();
    240       sdecl->sizeok = Sizeok::done;
    241       sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
    242       sdecl->type->ctype = type;
    243       sdecl->type->merge2 ();
    244 
    245       /* Add both named and anonymous fields as members of the struct.
    246 	 Anonymous fields still need a name in D, so call them "__pad%u".  */
    247       unsigned anonfield_id = 0;
    248       sdecl->members = d_gc_malloc<Dsymbols> ();
    249 
    250       for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    251 	{
    252 	  Type *ftype = build_frontend_type (TREE_TYPE (field));
    253 	  if (!ftype)
    254 	    {
    255 	      /* Drop any field types that got cached before the conversion
    256 		 of this record type failed.  */
    257 	      builtin_converted_decls.truncate (saved_builtin_decls_length);
    258 	      return NULL;
    259 	    }
    260 
    261 	  Identifier *fident;
    262 	  if (DECL_NAME (field) == NULL_TREE)
    263 	    {
    264 	      char name[16];
    265 	      snprintf (name, sizeof (name), "__pad%u", anonfield_id++);
    266 	      fident = Identifier::idPool (name);
    267 	    }
    268 	  else
    269 	    {
    270 	      const char *name = IDENTIFIER_POINTER (DECL_NAME (field));
    271 	      fident = Identifier::idPool (name);
    272 	    }
    273 
    274 	  VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
    275 						       NULL);
    276 	  vd->parent = sdecl;
    277 	  vd->offset = tree_to_uhwi (byte_position (field));
    278 	  vd->semanticRun = PASS::semanticdone;
    279 	  vd->csym = field;
    280 	  sdecl->members->push (vd);
    281 	  sdecl->fields.push (vd);
    282 	}
    283 
    284       dtype = sdecl->type;
    285       builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));
    286       return dtype;
    287     }
    288 
    289     case FUNCTION_TYPE:
    290       dtype = build_frontend_type (TREE_TYPE (type));
    291       if (dtype)
    292 	{
    293 	  tree parms = TYPE_ARG_TYPES (type);
    294 	  VarArg varargs_p = VARARGvariadic;
    295 
    296 	  Parameters *args = d_gc_malloc<Parameters> ();
    297 	  args->reserve (list_length (parms));
    298 
    299 	  /* Attempt to convert all parameter types.  */
    300 	  for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))
    301 	    {
    302 	      tree argtype = TREE_VALUE (parm);
    303 	      if (argtype == void_type_node)
    304 		{
    305 		  varargs_p = VARARGnone;
    306 		  break;
    307 		}
    308 
    309 	      StorageClass sc = STCundefined;
    310 	      if (TREE_CODE (argtype) == REFERENCE_TYPE)
    311 		{
    312 		  argtype = TREE_TYPE (argtype);
    313 		  sc |= STCref;
    314 		}
    315 
    316 	      Type *targ = build_frontend_type (argtype);
    317 	      if (!targ)
    318 		{
    319 		  /* Drop any parameter types that got cached before the
    320 		     conversion of this function type failed.  */
    321 		  builtin_converted_decls.truncate (saved_builtin_decls_length);
    322 		  return NULL;
    323 		}
    324 
    325 	      args->push (Parameter::create (sc, targ, NULL, NULL, NULL));
    326 	    }
    327 
    328 	  /* GCC generic and placeholder built-ins are marked as variadic, yet
    329 	     have no named parameters, and so can't be represented in D.  */
    330 	  if (args->length != 0 || varargs_p == VARARGnone)
    331 	    {
    332 	      dtype = TypeFunction::create (args, dtype, varargs_p, LINK::c);
    333 	      return dtype->addMod (mod);
    334 	    }
    335 	}
    336       break;
    337 
    338     default:
    339       break;
    340     }
    341 
    342   return NULL;
    343 }
    344 
    345 /* Attempt to convert GCC evaluated CST to a D Frontend Expression.
    346    LOC is the location in the source file where this CST is being evaluated.
    347    This is used for getting the CTFE value out of a const-folded builtin,
    348    returns NULL if it cannot convert CST.  */
    349 
    350 Expression *
    351 d_eval_constant_expression (const Loc &loc, tree cst)
    352 {
    353   STRIP_TYPE_NOPS (cst);
    354   Type *type = build_frontend_type (TREE_TYPE (cst));
    355 
    356   if (type)
    357     {
    358       /* Convert our GCC CST tree into a D Expression.  This seems like we are
    359 	 trying too hard, as these will only be converted back to a tree again
    360 	 later in the codegen pass, but satisfies the need to have GCC built-ins
    361 	 CTFE-able in the frontend.  */
    362       tree_code code = TREE_CODE (cst);
    363       if (code == COMPLEX_CST)
    364 	{
    365 	  real_value re = TREE_REAL_CST (TREE_REALPART (cst));
    366 	  real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
    367 	  complex_t value = complex_t (ldouble (re), ldouble (im));
    368 	  return ComplexExp::create (loc, value, type);
    369 	}
    370       else if (code == INTEGER_CST)
    371 	{
    372 	  dinteger_t value = TREE_INT_CST_LOW (cst);
    373 	  return IntegerExp::create (loc, value, type);
    374 	}
    375       else if (code == REAL_CST)
    376 	{
    377 	  real_value value = TREE_REAL_CST (cst);
    378 	  return RealExp::create (loc, ldouble (value), type);
    379 	}
    380       else if (code == STRING_CST)
    381 	{
    382 	  const void *string = TREE_STRING_POINTER (cst);
    383 	  size_t len = TREE_STRING_LENGTH (cst) - 1;
    384 	  return StringExp::create (loc, CONST_CAST (void *, string), len);
    385 	}
    386       else if (code == VECTOR_CST)
    387 	{
    388 	  dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant ();
    389 	  Expressions *elements = d_gc_malloc<Expressions> ();
    390 	  elements->setDim (nunits);
    391 
    392 	  for (size_t i = 0; i < nunits; i++)
    393 	    {
    394 	      Expression *elem
    395 		= d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
    396 	      if (elem == NULL)
    397 		return NULL;
    398 
    399 	      (*elements)[i] = elem;
    400 	    }
    401 
    402 	  Expression *e = ArrayLiteralExp::create (loc, elements);
    403 	  e->type = type->isTypeVector ()->basetype;
    404 
    405 	  return VectorExp::create (loc, e, type);
    406 	}
    407       else if (code == ADDR_EXPR)
    408 	{
    409 	  /* Special handling for trees constructed by build_string_literal.
    410 	     What we receive is an `&"string"[0]' expression, strip off the
    411 	     outer ADDR_EXPR and ARRAY_REF to get to the underlying CST.  */
    412 	  tree pointee = TREE_OPERAND (cst, 0);
    413 
    414 	  if (TREE_CODE (pointee) != ARRAY_REF
    415 	      || TREE_OPERAND (pointee, 1) != integer_zero_node
    416 	      || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
    417 	    return NULL;
    418 
    419 	  return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
    420 	}
    421     }
    422 
    423   return NULL;
    424 }
    425 
    426 /* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.
    427    Adds IDENT to the list of predefined version identifiers.  */
    428 
    429 void
    430 d_add_builtin_version (const char* ident)
    431 {
    432   VersionCondition::addPredefinedGlobalIdent (ident);
    433 }
    434 
    435 /* Initialize the list of all the predefined version identifiers.  */
    436 
    437 void
    438 d_init_versions (void)
    439 {
    440   VersionCondition::addPredefinedGlobalIdent ("GNU");
    441   VersionCondition::addPredefinedGlobalIdent ("D_Version2");
    442 
    443   if (BYTES_BIG_ENDIAN)
    444     VersionCondition::addPredefinedGlobalIdent ("BigEndian");
    445   else
    446     VersionCondition::addPredefinedGlobalIdent ("LittleEndian");
    447 
    448   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
    449     VersionCondition::addPredefinedGlobalIdent ("GNU_SjLj_Exceptions");
    450   else if (targetm_common.except_unwind_info (&global_options) == UI_SEH)
    451     VersionCondition::addPredefinedGlobalIdent ("GNU_SEH_Exceptions");
    452   else if (targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
    453     VersionCondition::addPredefinedGlobalIdent ("GNU_DWARF2_Exceptions");
    454 
    455   if (!targetm.have_tls)
    456     VersionCondition::addPredefinedGlobalIdent ("GNU_EMUTLS");
    457 
    458   if (STACK_GROWS_DOWNWARD)
    459     VersionCondition::addPredefinedGlobalIdent ("GNU_StackGrowsDown");
    460 
    461   /* Should define this anyway to set us apart from the competition.  */
    462   VersionCondition::addPredefinedGlobalIdent ("GNU_InlineAsm");
    463 
    464   /* LP64 only means 64bit pointers in D.  */
    465   if (POINTER_SIZE == 64)
    466     VersionCondition::addPredefinedGlobalIdent ("D_LP64");
    467 
    468   /* Setting `global.params.cov' forces module info generation which is
    469      not needed for the GCC coverage implementation.  Instead, just
    470      test flag_test_coverage while leaving `global.params.cov' unset.  */
    471   if (flag_test_coverage)
    472     VersionCondition::addPredefinedGlobalIdent ("D_Coverage");
    473   if (flag_pic)
    474     VersionCondition::addPredefinedGlobalIdent ("D_PIC");
    475   if (flag_pie)
    476     VersionCondition::addPredefinedGlobalIdent ("D_PIE");
    477 
    478   if (global.params.doDocComments)
    479     VersionCondition::addPredefinedGlobalIdent ("D_Ddoc");
    480 
    481   if (global.params.useUnitTests)
    482     VersionCondition::addPredefinedGlobalIdent ("unittest");
    483 
    484   if (global.params.useAssert == CHECKENABLEon)
    485     VersionCondition::addPredefinedGlobalIdent ("assert");
    486 
    487   if (global.params.useIn == CHECKENABLEon)
    488     VersionCondition::addPredefinedGlobalIdent("D_PreConditions");
    489 
    490   if (global.params.useOut == CHECKENABLEon)
    491     VersionCondition::addPredefinedGlobalIdent("D_PostConditions");
    492 
    493   if (global.params.useInvariants == CHECKENABLEon)
    494     VersionCondition::addPredefinedGlobalIdent("D_Invariants");
    495 
    496   if (global.params.useArrayBounds == CHECKENABLEoff)
    497     VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");
    498 
    499   if (global.params.betterC)
    500     VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
    501   else
    502     {
    503       VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
    504       VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
    505       VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
    506     }
    507 
    508   VersionCondition::addPredefinedGlobalIdent ("all");
    509 
    510   /* Emit all target-specific version identifiers.  */
    511   targetdm.d_cpu_versions ();
    512   targetdm.d_os_versions ();
    513 
    514   VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
    515 }
    516 
    517 /* A helper for d_build_builtins_module.  Return a new ALIAS for TYPE.
    518    Analogous to `alias ALIAS = TYPE' in D code.  */
    519 
    520 static AliasDeclaration *
    521 build_alias_declaration (const char *alias, Type *type)
    522 {
    523   return AliasDeclaration::create (Loc (), Identifier::idPool (alias), type);
    524 }
    525 
    526 /* A helper function for Target::loadModule.  Generates all code for the
    527    `gcc.builtins' module, whose frontend symbol should be M.  */
    528 
    529 void
    530 d_build_builtins_module (Module *m)
    531 {
    532   Dsymbols *members = d_gc_malloc<Dsymbols> ();
    533   tree decl;
    534 
    535   for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i)
    536     {
    537       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
    538       Type *t = build_frontend_type (TREE_TYPE (decl));
    539       TypeFunction *tf = t ? t->isTypeFunction () : NULL;
    540 
    541       /* Cannot create built-in function type for DECL.  */
    542       if (!tf)
    543 	continue;
    544 
    545       /* A few notes on D2 attributes applied to builtin functions:
    546 	 - It is assumed that built-ins solely provided by the compiler are
    547 	   considered @safe and pure.
    548 	 - Built-ins that correspond to `extern(C)' functions in the standard
    549 	   library that have `__attribute__(nothrow)' are considered `@trusted'.
    550 	 - The purity of a built-in can vary depending on compiler flags set
    551 	   upon initialization, or by the `-foptions' passed, such as
    552 	   flag_unsafe_math_optimizations.
    553 	 - Built-ins never use the GC or raise a D exception, and so are always
    554 	   marked as `nothrow' and `@nogc'.  */
    555       tf->purity = DECL_PURE_P (decl) ? PURE::const_
    556 	: TREE_READONLY (decl) ? PURE::const_
    557 	: DECL_IS_NOVOPS (decl) ? PURE::weak
    558 	: !DECL_ASSEMBLER_NAME_SET_P (decl) ? PURE::weak
    559 	: PURE::impure;
    560       tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUST::safe
    561 	: TREE_NOTHROW (decl) ? TRUST::trusted
    562 	: TRUST::system;
    563       tf->isnothrow (true);
    564       tf->isnogc (true);
    565 
    566       FuncDeclaration *func
    567 	= FuncDeclaration::create (Loc (), Loc (),
    568 				   Identifier::idPool (name),
    569 				   STCextern, tf);
    570       DECL_LANG_SPECIFIC (decl) = build_lang_decl (func);
    571       func->csym = decl;
    572       func->builtin = BUILTIN::gcc;
    573 
    574       members->push (func);
    575     }
    576 
    577   for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i)
    578     {
    579       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
    580       Type *t = build_frontend_type (TREE_TYPE (decl));
    581 
    582       /* Cannot create built-in type for DECL.  */
    583       if (!t)
    584 	continue;
    585 
    586       members->push (build_alias_declaration (name, t));
    587     }
    588 
    589   /* Iterate through the target-specific builtin types for va_list.  */
    590   if (targetm.enum_va_list_p)
    591     {
    592       const char *name;
    593       tree type;
    594 
    595       for (int i = 0; targetm.enum_va_list_p (i, &name, &type); ++i)
    596 	{
    597 	  Type *t = build_frontend_type (type);
    598 	  /* Cannot create built-in type.  */
    599 	  if (!t)
    600 	    continue;
    601 
    602 	  members->push (build_alias_declaration (name, t));
    603 	}
    604     }
    605 
    606   /* Push out declarations for any RECORD_TYPE types encountered when building
    607      all builtin functions and types.  */
    608   for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
    609     {
    610       /* Currently, there is no need to run semantic, but we do want to output
    611 	 initializers, typeinfo, and others on demand.  */
    612       Dsymbol *dsym = builtin_converted_decls[i].dsym;
    613       if (dsym != NULL && !dsym->isAnonymous ())
    614 	{
    615 	  dsym->parent = m;
    616 	  members->push (dsym);
    617 	}
    618     }
    619 
    620   /* Expose target-specific va_list type.  */
    621   Type *tvalist = target.va_listType (Loc (), NULL);
    622   TypeStruct *ts = tvalist->isTypeStruct ();
    623   if (ts == NULL || !ts->sym->isAnonymous ())
    624     members->push (build_alias_declaration ("__builtin_va_list", tvalist));
    625   else
    626     {
    627       ts->sym->ident = Identifier::idPool ("__builtin_va_list");
    628       members->push (ts->sym);
    629     }
    630 
    631   /* Expose target-specific integer types to the builtins module.  */
    632   {
    633     Type *t = build_frontend_type (long_integer_type_node);
    634     members->push (build_alias_declaration ("__builtin_clong", t));
    635 
    636     t = build_frontend_type (long_unsigned_type_node);
    637     members->push (build_alias_declaration ("__builtin_culong", t));
    638 
    639     t = build_frontend_type (long_long_integer_type_node);
    640     members->push (build_alias_declaration ("__builtin_clonglong", t));
    641 
    642     t = build_frontend_type (long_long_unsigned_type_node);
    643     members->push (build_alias_declaration ("__builtin_culonglong", t));
    644 
    645     t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 0));
    646     members->push (build_alias_declaration ("__builtin_machine_byte", t));
    647 
    648     t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 1));
    649     members->push (build_alias_declaration ("__builtin_machine_ubyte", t));
    650 
    651     t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 0));
    652     members->push (build_alias_declaration ("__builtin_machine_int", t));
    653 
    654     t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 1));
    655     members->push (build_alias_declaration ("__builtin_machine_uint", t));
    656 
    657     t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 0));
    658     members->push (build_alias_declaration ("__builtin_pointer_int", t));
    659 
    660     t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 1));
    661     members->push (build_alias_declaration ("__builtin_pointer_uint", t));
    662 
    663     /* _Unwind_Word has its own target specific mode.  */
    664     machine_mode mode = targetm.unwind_word_mode ();
    665     t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 0));
    666     members->push (build_alias_declaration ("__builtin_unwind_int", t));
    667 
    668     t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 1));
    669     members->push (build_alias_declaration ("__builtin_unwind_uint", t));
    670   }
    671 
    672   m->members->push (LinkDeclaration::create (Loc (), LINK::c, members));
    673 }
    674 
    675 /* Search for any `extern(C)' functions that match any known GCC library builtin
    676    function in D and override its internal back-end symbol.  */
    677 
    678 static void
    679 maybe_set_builtin_1 (Dsymbol *d)
    680 {
    681   AttribDeclaration *ad = d->isAttribDeclaration ();
    682   FuncDeclaration *fd = d->isFuncDeclaration ();
    683 
    684   if (ad != NULL)
    685     {
    686       /* Recursively search through attribute decls.  */
    687       Dsymbols *decls = ad->include (NULL);
    688       if (decls && decls->length)
    689 	{
    690 	  for (size_t i = 0; i < decls->length; i++)
    691 	    {
    692 	      Dsymbol *sym = (*decls)[i];
    693 	      maybe_set_builtin_1 (sym);
    694 	    }
    695 	}
    696     }
    697   else if (fd && !fd->fbody)
    698     {
    699       tree t;
    700 
    701       for (size_t i = 0; vec_safe_iterate (gcc_builtins_libfuncs, i, &t); ++i)
    702 	{
    703 	  gcc_assert (DECL_ASSEMBLER_NAME_SET_P (t));
    704 
    705 	  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
    706 	  if (fd->ident != Identifier::idPool (name))
    707 	    continue;
    708 
    709 	  /* Found a match, tell the frontend this is a builtin.  */
    710 	  DECL_LANG_SPECIFIC (t) = build_lang_decl (fd);
    711 	  fd->csym = t;
    712 	  fd->builtin = BUILTIN::gcc;
    713 	  return;
    714 	}
    715     }
    716 }
    717 
    718 /* A helper function for Target::loadModule.  Traverse all members in module M
    719    to search for any functions that can be mapped to any GCC builtin.  */
    720 
    721 void
    722 d_maybe_set_builtin (Module *m)
    723 {
    724   if (!m || !m->members)
    725     return;
    726 
    727   for (size_t i = 0; i < m->members->length; i++)
    728     {
    729       Dsymbol *sym = (*m->members)[i];
    730       maybe_set_builtin_1 (sym);
    731     }
    732 }
    733 
    734 /* Used to help initialize the builtin-types.def table.  When a type of
    735    the correct size doesn't exist, use error_mark_node instead of NULL.
    736    The latter results in segfaults even when a decl using the type doesn't
    737    get invoked.  */
    738 
    739 static tree
    740 builtin_type_for_size (int size, bool unsignedp)
    741 {
    742   tree type = lang_hooks.types.type_for_size (size, unsignedp);
    743   return type ? type : error_mark_node;
    744 }
    745 
    746 /* Support for DEF_BUILTIN.  */
    747 
    748 static void
    749 do_build_builtin_fn (built_in_function fncode,
    750 		     const char *name,
    751 		     built_in_class fnclass,
    752 		     tree fntype, bool both_p, bool fallback_p,
    753 		     tree fnattrs, bool implicit_p)
    754 {
    755   tree decl;
    756   const char *libname;
    757 
    758   if (fntype == error_mark_node)
    759     return;
    760 
    761   gcc_assert ((!both_p && !fallback_p)
    762 	      || startswith (name, "__builtin_"));
    763 
    764   libname = name + strlen ("__builtin_");
    765 
    766   decl = add_builtin_function (name, fntype, fncode, fnclass,
    767 			       fallback_p ? libname : NULL, fnattrs);
    768 
    769   set_builtin_decl (fncode, decl, implicit_p);
    770 }
    771 
    772 /* Standard data types to be used in builtin argument declarations.  */
    773 
    774 static GTY(()) tree string_type_node;
    775 static GTY(()) tree const_string_type_node;
    776 static GTY(()) tree wint_type_node;
    777 static GTY(()) tree intmax_type_node;
    778 static GTY(()) tree uintmax_type_node;
    779 static GTY(()) tree signed_size_type_node;
    780 
    781 
    782 /* Build nodes that would have been created by the C front-end; necessary
    783    for including builtin-types.def and ultimately builtins.def.  */
    784 
    785 static void
    786 d_build_c_type_nodes (void)
    787 {
    788   void_list_node = build_tree_list (NULL_TREE, void_type_node);
    789   string_type_node = build_pointer_type (char_type_node);
    790   const_string_type_node
    791     = build_pointer_type (build_qualified_type (char_type_node,
    792 						TYPE_QUAL_CONST));
    793 
    794   if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
    795     {
    796       intmax_type_node = integer_type_node;
    797       uintmax_type_node = unsigned_type_node;
    798     }
    799   else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
    800     {
    801       intmax_type_node = long_integer_type_node;
    802       uintmax_type_node = long_unsigned_type_node;
    803     }
    804   else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
    805     {
    806       intmax_type_node = long_long_integer_type_node;
    807       uintmax_type_node = long_long_unsigned_type_node;
    808     }
    809   else
    810     gcc_unreachable ();
    811 
    812   signed_size_type_node = signed_type_for (size_type_node);
    813   wint_type_node = unsigned_type_node;
    814   pid_type_node = integer_type_node;
    815 }
    816 
    817 /* Build nodes that are used by the D front-end.
    818    These are distinct from C types.  */
    819 
    820 static void
    821 d_build_d_type_nodes (void)
    822 {
    823   /* Integral types.  */
    824   d_byte_type = make_signed_type (8);
    825   d_ubyte_type = make_unsigned_type (8);
    826 
    827   d_short_type = make_signed_type (16);
    828   d_ushort_type = make_unsigned_type (16);
    829 
    830   d_int_type = make_signed_type (32);
    831   d_uint_type = make_unsigned_type (32);
    832 
    833   d_long_type = make_signed_type (64);
    834   d_ulong_type = make_unsigned_type (64);
    835 
    836   d_cent_type = make_signed_type (128);
    837   d_ucent_type = make_unsigned_type (128);
    838 
    839   {
    840     /* Re-define size_t as a D type.  */
    841     machine_mode type_mode = TYPE_MODE (size_type_node);
    842     size_type_node = lang_hooks.types.type_for_mode (type_mode, 1);
    843   }
    844 
    845   /* Bool and Character types.  */
    846   d_bool_type = make_unsigned_type (1);
    847   TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);
    848 
    849   d_bool_false_node = TYPE_MIN_VALUE (d_bool_type);
    850   d_bool_true_node = TYPE_MAX_VALUE (d_bool_type);
    851 
    852   char8_type_node = make_unsigned_type (8);
    853   TYPE_STRING_FLAG (char8_type_node) = 1;
    854 
    855   char16_type_node = make_unsigned_type (16);
    856   TYPE_STRING_FLAG (char16_type_node) = 1;
    857 
    858   char32_type_node = make_unsigned_type (32);
    859   TYPE_STRING_FLAG (char32_type_node) = 1;
    860 
    861   /* Imaginary types.  */
    862   ifloat_type_node = build_distinct_type_copy (float_type_node);
    863   TYPE_IMAGINARY_FLOAT (ifloat_type_node) = 1;
    864 
    865   idouble_type_node = build_distinct_type_copy (double_type_node);
    866   TYPE_IMAGINARY_FLOAT (idouble_type_node) = 1;
    867 
    868   ireal_type_node = build_distinct_type_copy (long_double_type_node);
    869   TYPE_IMAGINARY_FLOAT (ireal_type_node) = 1;
    870 
    871   /* Noreturn type.  */
    872   noreturn_type_node = build_distinct_type_copy (void_type_node);
    873 
    874   /* Calling build_ctype() links the front-end Type to the GCC node,
    875      and sets the TYPE_NAME to the D language type.  */
    876   for (unsigned ty = 0; ty < (unsigned) TY::TMAX; ty++)
    877     {
    878       if (Type::basic[ty] != NULL)
    879 	build_ctype (Type::basic[ty]);
    880     }
    881 
    882   /* Used for ModuleInfo, ClassInfo, and Interface decls.  */
    883   unknown_type_node = make_node (RECORD_TYPE);
    884 
    885   /* Make sure we get a unique function type, so we can give
    886      its pointer type a name.  (This wins for gdb).  */
    887   {
    888     tree vfunc_type = make_node (FUNCTION_TYPE);
    889     TREE_TYPE (vfunc_type) = d_int_type;
    890     TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
    891     layout_type (vfunc_type);
    892 
    893     vtable_entry_type = build_pointer_type (vfunc_type);
    894   }
    895 
    896   vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
    897   layout_type (vtbl_ptr_type_node);
    898 
    899   /* When an object is accessed via an interface, this type appears
    900      as the first entry in its vtable.  */
    901   {
    902     tree domain = build_index_type (size_int (3));
    903     vtbl_interface_type_node = build_array_type (ptr_type_node, domain);
    904   }
    905 
    906   /* Use `void[]' as a generic dynamic array type.  */
    907   array_type_node = make_struct_type ("__builtin_void[]", 2,
    908 				      get_identifier ("length"), size_type_node,
    909 				      get_identifier ("ptr"), ptr_type_node);
    910   TYPE_DYNAMIC_ARRAY (array_type_node) = 1;
    911 
    912   null_array_node = d_array_value (array_type_node, size_zero_node,
    913 				   null_pointer_node);
    914 }
    915 
    916 /* Handle default attributes.  */
    917 
    918 enum built_in_attribute
    919 {
    920 #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
    921 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
    922 #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
    923 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
    924 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
    925 #include "builtin-attrs.def"
    926 #undef DEF_ATTR_NULL_TREE
    927 #undef DEF_ATTR_INT
    928 #undef DEF_ATTR_STRING
    929 #undef DEF_ATTR_IDENT
    930 #undef DEF_ATTR_TREE_LIST
    931   ATTR_LAST
    932 };
    933 
    934 static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
    935 
    936 /* Initialize the attribute table for all the supported builtins.  */
    937 
    938 static void
    939 d_init_attributes (void)
    940 {
    941   /* Fill in the built_in_attributes array.  */
    942 #define DEF_ATTR_NULL_TREE(ENUM)	\
    943   built_in_attributes[(int) ENUM] = NULL_TREE;
    944 # define DEF_ATTR_INT(ENUM, VALUE)	\
    945   built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
    946 #define DEF_ATTR_STRING(ENUM, VALUE)	\
    947   built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
    948 #define DEF_ATTR_IDENT(ENUM, STRING)	\
    949   built_in_attributes[(int) ENUM] = get_identifier (STRING);
    950 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)	\
    951   built_in_attributes[(int) ENUM]			\
    952   = tree_cons (built_in_attributes[(int) PURPOSE],	\
    953 	       built_in_attributes[(int) VALUE],	\
    954 	       built_in_attributes[(int) CHAIN]);
    955 #include "builtin-attrs.def"
    956 #undef DEF_ATTR_NULL_TREE
    957 #undef DEF_ATTR_INT
    958 #undef DEF_ATTR_STRING
    959 #undef DEF_ATTR_IDENT
    960 #undef DEF_ATTR_TREE_LIST
    961 }
    962 
    963 /* Builtin types.  */
    964 
    965 enum d_builtin_type
    966 {
    967 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
    968 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
    969 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
    970 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
    971 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
    972 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
    973 #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
    974 #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    975 			    ARG6) NAME,
    976 #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    977 			    ARG6, ARG7) NAME,
    978 #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    979 			    ARG6, ARG7, ARG8) NAME,
    980 #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    981 			    ARG6, ARG7, ARG8, ARG9) NAME,
    982 #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    983 			     ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
    984 #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    985 			     ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
    986 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
    987 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
    988 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
    989 #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
    990 #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
    991 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
    992 				NAME,
    993 #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    994 				ARG6) NAME,
    995 #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    996 				ARG6, ARG7) NAME,
    997 #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
    998 				 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
    999 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
   1000 #include "builtin-types.def"
   1001 #undef DEF_PRIMITIVE_TYPE
   1002 #undef DEF_FUNCTION_TYPE_0
   1003 #undef DEF_FUNCTION_TYPE_1
   1004 #undef DEF_FUNCTION_TYPE_2
   1005 #undef DEF_FUNCTION_TYPE_3
   1006 #undef DEF_FUNCTION_TYPE_4
   1007 #undef DEF_FUNCTION_TYPE_5
   1008 #undef DEF_FUNCTION_TYPE_6
   1009 #undef DEF_FUNCTION_TYPE_7
   1010 #undef DEF_FUNCTION_TYPE_8
   1011 #undef DEF_FUNCTION_TYPE_9
   1012 #undef DEF_FUNCTION_TYPE_10
   1013 #undef DEF_FUNCTION_TYPE_11
   1014 #undef DEF_FUNCTION_TYPE_VAR_0
   1015 #undef DEF_FUNCTION_TYPE_VAR_1
   1016 #undef DEF_FUNCTION_TYPE_VAR_2
   1017 #undef DEF_FUNCTION_TYPE_VAR_3
   1018 #undef DEF_FUNCTION_TYPE_VAR_4
   1019 #undef DEF_FUNCTION_TYPE_VAR_5
   1020 #undef DEF_FUNCTION_TYPE_VAR_6
   1021 #undef DEF_FUNCTION_TYPE_VAR_7
   1022 #undef DEF_FUNCTION_TYPE_VAR_11
   1023 #undef DEF_POINTER_TYPE
   1024   BT_LAST
   1025 };
   1026 
   1027 typedef enum d_builtin_type builtin_type;
   1028 
   1029 /* A temporary array used in communication with def_fn_type.  */
   1030 static GTY(()) tree builtin_types[(int) BT_LAST + 1];
   1031 
   1032 /* A helper function for d_init_builtins.  Build function type for DEF with
   1033    return type RET and N arguments.  If VAR is true, then the function should
   1034    be variadic after those N arguments.
   1035 
   1036    Takes special care not to ICE if any of the types involved are
   1037    error_mark_node, which indicates that said type is not in fact available
   1038    (see builtin_type_for_size).  In which case the function type as a whole
   1039    should be error_mark_node.  */
   1040 
   1041 static void
   1042 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
   1043 {
   1044   tree t;
   1045   tree *args = XALLOCAVEC (tree, n);
   1046   va_list list;
   1047   int i;
   1048 
   1049   va_start (list, n);
   1050   for (i = 0; i < n; ++i)
   1051     {
   1052       builtin_type a = (builtin_type) va_arg (list, int);
   1053       t = builtin_types[a];
   1054       if (t == error_mark_node)
   1055 	goto egress;
   1056       args[i] = t;
   1057     }
   1058 
   1059   t = builtin_types[ret];
   1060   if (t == error_mark_node)
   1061     goto egress;
   1062   if (var)
   1063     t = build_varargs_function_type_array (t, n, args);
   1064   else
   1065     t = build_function_type_array (t, n, args);
   1066 
   1067  egress:
   1068   builtin_types[def] = t;
   1069   va_end (list);
   1070 }
   1071 
   1072 /* Create builtin types and functions.  VA_LIST_REF_TYPE_NODE and
   1073    VA_LIST_ARG_TYPE_NODE are used in builtin-types.def.  */
   1074 
   1075 static void
   1076 d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
   1077 		   tree va_list_arg_type_node ATTRIBUTE_UNUSED)
   1078 {
   1079 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
   1080   builtin_types[(int) ENUM] = VALUE;
   1081 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
   1082   def_fn_type (ENUM, RETURN, 0, 0);
   1083 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
   1084   def_fn_type (ENUM, RETURN, 0, 1, ARG1);
   1085 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
   1086   def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
   1087 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
   1088   def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
   1089 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
   1090   def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
   1091 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
   1092   def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
   1093 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1094 			    ARG6)					\
   1095   def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
   1096 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1097 			    ARG6, ARG7)					\
   1098   def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
   1099 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1100 			    ARG6, ARG7, ARG8)				\
   1101   def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
   1102 	       ARG7, ARG8);
   1103 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1104 			    ARG6, ARG7, ARG8, ARG9)			\
   1105   def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
   1106 	       ARG7, ARG8, ARG9);
   1107 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1108 			    ARG6, ARG7, ARG8, ARG9, ARG10)		 \
   1109   def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
   1110 	       ARG7, ARG8, ARG9, ARG10);
   1111 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1112 			    ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)	 \
   1113   def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,  \
   1114 	       ARG7, ARG8, ARG9, ARG10, ARG11);
   1115 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
   1116   def_fn_type (ENUM, RETURN, 1, 0);
   1117 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
   1118   def_fn_type (ENUM, RETURN, 1, 1, ARG1);
   1119 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
   1120   def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
   1121 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
   1122   def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
   1123 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
   1124   def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
   1125 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
   1126   def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
   1127 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1128 				ARG6)					    \
   1129   def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
   1130 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1131 				ARG6, ARG7)				    \
   1132   def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
   1133 #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
   1134 				 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11)       \
   1135   def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6,      \
   1136 	       ARG7, ARG8, ARG9, ARG10, ARG11);
   1137 #define DEF_POINTER_TYPE(ENUM, TYPE) \
   1138   builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
   1139 
   1140 #include "builtin-types.def"
   1141 
   1142 #undef DEF_PRIMITIVE_TYPE
   1143 #undef DEF_FUNCTION_TYPE_1
   1144 #undef DEF_FUNCTION_TYPE_2
   1145 #undef DEF_FUNCTION_TYPE_3
   1146 #undef DEF_FUNCTION_TYPE_4
   1147 #undef DEF_FUNCTION_TYPE_5
   1148 #undef DEF_FUNCTION_TYPE_6
   1149 #undef DEF_FUNCTION_TYPE_7
   1150 #undef DEF_FUNCTION_TYPE_8
   1151 #undef DEF_FUNCTION_TYPE_9
   1152 #undef DEF_FUNCTION_TYPE_10
   1153 #undef DEF_FUNCTION_TYPE_11
   1154 #undef DEF_FUNCTION_TYPE_VAR_0
   1155 #undef DEF_FUNCTION_TYPE_VAR_1
   1156 #undef DEF_FUNCTION_TYPE_VAR_2
   1157 #undef DEF_FUNCTION_TYPE_VAR_3
   1158 #undef DEF_FUNCTION_TYPE_VAR_4
   1159 #undef DEF_FUNCTION_TYPE_VAR_5
   1160 #undef DEF_FUNCTION_TYPE_VAR_6
   1161 #undef DEF_FUNCTION_TYPE_VAR_7
   1162 #undef DEF_FUNCTION_TYPE_VAR_11
   1163 #undef DEF_POINTER_TYPE
   1164   builtin_types[(int) BT_LAST] = NULL_TREE;
   1165 
   1166   d_init_attributes ();
   1167 
   1168 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
   1169 		    NONANSI_P, ATTRS, IMPLICIT, COND)			  \
   1170   if (NAME && COND)							  \
   1171     do_build_builtin_fn (ENUM, NAME, CLASS,				  \
   1172 			 builtin_types[(int) TYPE],			  \
   1173 			 BOTH_P, FALLBACK_P,				  \
   1174 			 built_in_attributes[(int) ATTRS], IMPLICIT);
   1175 #include "builtins.def"
   1176 #undef DEF_BUILTIN
   1177 }
   1178 
   1179 /* Build builtin functions and types for the D language frontend.  */
   1180 
   1181 void
   1182 d_init_builtins (void)
   1183 {
   1184   d_build_c_type_nodes ();
   1185   d_build_d_type_nodes ();
   1186 
   1187   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
   1188     {
   1189       /* It might seem natural to make the argument type a pointer, but there
   1190 	 is no implicit casting from arrays to pointers in D.  */
   1191       d_define_builtins (va_list_type_node, va_list_type_node);
   1192     }
   1193   else
   1194     {
   1195       d_define_builtins (build_reference_type (va_list_type_node),
   1196 			 va_list_type_node);
   1197     }
   1198 
   1199   targetm.init_builtins ();
   1200   build_common_builtin_nodes ();
   1201 }
   1202 
   1203 /* Registration of machine- or os-specific builtin types.
   1204    Add to builtin types list for maybe processing later
   1205    if `gcc.builtins' was imported into the current module.  */
   1206 
   1207 void
   1208 d_register_builtin_type (tree type, const char *name)
   1209 {
   1210   tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
   1211 			  get_identifier (name), type);
   1212   DECL_ARTIFICIAL (decl) = 1;
   1213 
   1214   if (!TYPE_NAME (type))
   1215     TYPE_NAME (type) = decl;
   1216 
   1217   vec_safe_push (gcc_builtins_types, decl);
   1218 }
   1219 
   1220 /* Add DECL to builtin functions list for maybe processing later
   1221    if `gcc.builtins' was imported into the current module.  */
   1222 
   1223 tree
   1224 d_builtin_function (tree decl)
   1225 {
   1226   if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))
   1227     vec_safe_push (gcc_builtins_libfuncs, decl);
   1228 
   1229   vec_safe_push (gcc_builtins_functions, decl);
   1230   return decl;
   1231 }
   1232 
   1233 /* Same as d_builtin_function, but used to delay putting in back-end builtin
   1234    functions until the ISA that defines the builtin has been declared.
   1235    However in D, there is no global namespace.  All builtins get pushed into the
   1236    `gcc.builtins' module, which is constructed during the semantic analysis
   1237    pass, which has already finished by the time target attributes are evaluated.
   1238    So builtins are not pushed because they would be ultimately ignored.
   1239    The purpose of having this function then is to improve compile-time
   1240    reflection support to allow user-code to determine whether a given back end
   1241    function is enabled by the ISA.  */
   1242 
   1243 tree
   1244 d_builtin_function_ext_scope (tree decl)
   1245 {
   1246   return decl;
   1247 }
   1248 
   1249 #include "gt-d-d-builtins.h"
   1250