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