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