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