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