Fix issue for pointers to anonymous types with -fdump-ada-spec
[official-gcc.git] / gcc / d / d-builtins.cc
blob73b476666e5d779c9f8b81187c8f3bdbfdbdc386
1 /* d-builtins.cc -- GCC builtins support for D.
2 Copyright (C) 2006-2022 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-frontend.h"
43 #include "d-target.h"
46 static GTY(()) vec <tree, va_gc> *gcc_builtins_functions = NULL;
47 static GTY(()) vec <tree, va_gc> *gcc_builtins_libfuncs = NULL;
48 static GTY(()) vec <tree, va_gc> *gcc_builtins_types = NULL;
50 /* Record built-in types and their associated decls for re-use when
51 generating the `gcc.builtins' module. */
53 struct builtin_data
55 Type *dtype;
56 tree ctype;
57 Dsymbol *dsym;
59 builtin_data (Type *t, tree c, Dsymbol *d = NULL)
60 : dtype(t), ctype(c), dsym(d)
61 { }
64 static vec <builtin_data> builtin_converted_decls;
66 /* Build D frontend type from tree TYPE type given. This will set the
67 back-end type symbol directly for complex types to save build_ctype()
68 the work. For other types, it is not useful or will cause errors, such
69 as casting from `C char' to `D char', which also means that `char *`
70 needs to be specially handled. */
72 Type *
73 build_frontend_type (tree type)
75 Type *dtype;
76 MOD mod = 0;
78 if (TYPE_READONLY (type))
79 mod |= MODconst;
80 if (TYPE_VOLATILE (type))
81 mod |= MODshared;
83 /* If we've seen the type before, re-use the converted decl. */
84 unsigned saved_builtin_decls_length = builtin_converted_decls.length ();
85 for (size_t i = 0; i < saved_builtin_decls_length; ++i)
87 tree t = builtin_converted_decls[i].ctype;
88 if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type))
89 return builtin_converted_decls[i].dtype;
92 switch (TREE_CODE (type))
94 case POINTER_TYPE:
95 dtype = build_frontend_type (TREE_TYPE (type));
96 if (dtype)
98 /* Check for char * first. Needs to be done for chars/string. */
99 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)
100 return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);
102 if (dtype->ty == TY::Tfunction)
103 return (TypePointer::create (dtype))->addMod (mod);
105 return dtype->pointerTo ()->addMod (mod);
107 break;
109 case REFERENCE_TYPE:
110 dtype = build_frontend_type (TREE_TYPE (type));
111 if (dtype)
113 /* Want to assign ctype directly so that the REFERENCE_TYPE code
114 can be turned into as an `inout' argument. Can't use pointerTo(),
115 because the returned Type is shared. */
116 dtype = (TypePointer::create (dtype))->addMod (mod);
117 dtype->ctype = type;
118 builtin_converted_decls.safe_push (builtin_data (dtype, type));
119 return dtype;
121 break;
123 case BOOLEAN_TYPE:
124 /* Should be no need for size checking. */
125 return Type::tbool->addMod (mod);
127 case INTEGER_TYPE:
129 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
130 bool unsignedp = TYPE_UNSIGNED (type);
132 /* For now, skip support for cent/ucent until the frontend
133 has better support for handling it. */
134 for (size_t i = (size_t) TY::Tint8; i <= (size_t) TY::Tuns64; i++)
136 dtype = Type::basic[i];
138 /* Search for type matching size and signedness. */
139 if (unsignedp != dtype->isunsigned ()
140 || size != dtype->size ())
141 continue;
143 return dtype->addMod (mod);
145 break;
148 case REAL_TYPE:
150 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
152 for (size_t i = (size_t) TY::Tfloat32; i <= (size_t) TY::Tfloat80; i++)
154 dtype = Type::basic[i];
156 /* Search for type matching size. */
157 if (dtype->size () != size)
158 continue;
160 return dtype->addMod (mod);
162 break;
165 case COMPLEX_TYPE:
167 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
168 for (size_t i = (size_t) TY::Tcomplex32; i <= (size_t) TY::Tcomplex80;
169 i++)
171 dtype = Type::basic[i];
173 /* Search for type matching size. */
174 if (dtype->size () != size)
175 continue;
177 return dtype->addMod (mod);
179 break;
182 case VOID_TYPE:
183 return Type::tvoid->addMod (mod);
185 case ARRAY_TYPE:
186 dtype = build_frontend_type (TREE_TYPE (type));
187 if (dtype)
189 tree index = TYPE_DOMAIN (type);
190 tree ub = TYPE_MAX_VALUE (index);
191 tree lb = TYPE_MIN_VALUE (index);
193 tree length = fold_build2 (MINUS_EXPR, TREE_TYPE (lb), ub, lb);
194 length = size_binop (PLUS_EXPR, size_one_node,
195 convert (sizetype, length));
197 dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
198 builtin_converted_decls.safe_push (builtin_data (dtype, type));
199 return dtype;
201 break;
203 case VECTOR_TYPE:
205 unsigned HOST_WIDE_INT nunits;
206 if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits))
207 break;
209 dtype = build_frontend_type (TREE_TYPE (type));
210 if (!dtype)
211 break;
213 dtype = dtype->sarrayOf (nunits)->addMod (mod);
214 if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ()))
215 break;
217 dtype = (TypeVector::create (dtype))->addMod (mod);
218 builtin_converted_decls.safe_push (builtin_data (dtype, type));
219 return dtype;
222 case RECORD_TYPE:
224 Identifier *ident = TYPE_IDENTIFIER (type) ?
225 Identifier::idPool (IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))) : NULL;
227 /* Neither the `object' and `gcc.builtins' modules will not exist when
228 this is called. Use a stub `object' module parent in the meantime.
229 If `gcc.builtins' is later imported, the parent will be overridden
230 with the correct module symbol. */
231 static Identifier *object = Identifier::idPool ("object");
232 static Module *stubmod = Module::create ("object.d", object, 0, 0);
234 StructDeclaration *sdecl = StructDeclaration::create (Loc (), ident,
235 false);
236 sdecl->parent = stubmod;
237 sdecl->structsize = int_size_in_bytes (type);
238 sdecl->alignsize = TYPE_ALIGN_UNIT (type);
239 sdecl->alignment.setDefault ();
240 sdecl->sizeok = Sizeok::done;
241 sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
242 sdecl->type->ctype = type;
243 sdecl->type->merge2 ();
245 /* Add both named and anonymous fields as members of the struct.
246 Anonymous fields still need a name in D, so call them "__pad%u". */
247 unsigned anonfield_id = 0;
248 sdecl->members = d_gc_malloc<Dsymbols> ();
250 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
252 Type *ftype = build_frontend_type (TREE_TYPE (field));
253 if (!ftype)
255 /* Drop any field types that got cached before the conversion
256 of this record type failed. */
257 builtin_converted_decls.truncate (saved_builtin_decls_length);
258 return NULL;
261 Identifier *fident;
262 if (DECL_NAME (field) == NULL_TREE)
264 char name[16];
265 snprintf (name, sizeof (name), "__pad%u", anonfield_id++);
266 fident = Identifier::idPool (name);
268 else
270 const char *name = IDENTIFIER_POINTER (DECL_NAME (field));
271 fident = Identifier::idPool (name);
274 VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
275 NULL);
276 vd->parent = sdecl;
277 vd->offset = tree_to_uhwi (byte_position (field));
278 vd->semanticRun = PASS::semanticdone;
279 vd->csym = field;
280 sdecl->members->push (vd);
281 sdecl->fields.push (vd);
284 dtype = sdecl->type;
285 builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));
286 return dtype;
289 case FUNCTION_TYPE:
290 dtype = build_frontend_type (TREE_TYPE (type));
291 if (dtype)
293 tree parms = TYPE_ARG_TYPES (type);
294 VarArg varargs_p = VARARGvariadic;
296 Parameters *args = d_gc_malloc<Parameters> ();
297 args->reserve (list_length (parms));
299 /* Attempt to convert all parameter types. */
300 for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))
302 tree argtype = TREE_VALUE (parm);
303 if (argtype == void_type_node)
305 varargs_p = VARARGnone;
306 break;
309 StorageClass sc = STCundefined;
310 if (TREE_CODE (argtype) == REFERENCE_TYPE)
312 argtype = TREE_TYPE (argtype);
313 sc |= STCref;
316 Type *targ = build_frontend_type (argtype);
317 if (!targ)
319 /* Drop any parameter types that got cached before the
320 conversion of this function type failed. */
321 builtin_converted_decls.truncate (saved_builtin_decls_length);
322 return NULL;
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, LINK::c);
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 = d_gc_malloc<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 = d_gc_malloc<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) ? PURE::const_
547 : TREE_READONLY (decl) ? PURE::const_
548 : DECL_IS_NOVOPS (decl) ? PURE::weak
549 : !DECL_ASSEMBLER_NAME_SET_P (decl) ? PURE::weak
550 : PURE::impure;
551 tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUST::safe
552 : TREE_NOTHROW (decl) ? TRUST::trusted
553 : TRUST::system;
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 = BUILTIN::gcc;
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 (Loc (), LINK::c, 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 = BUILTIN::gcc;
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 /* Noreturn type. */
860 noreturn_type_node = build_distinct_type_copy (void_type_node);
862 /* Calling build_ctype() links the front-end Type to the GCC node,
863 and sets the TYPE_NAME to the D language type. */
864 for (unsigned ty = 0; ty < (unsigned) TY::TMAX; ty++)
866 if (Type::basic[ty] != NULL)
867 build_ctype (Type::basic[ty]);
870 /* Used for ModuleInfo, ClassInfo, and Interface decls. */
871 unknown_type_node = make_node (RECORD_TYPE);
873 /* Make sure we get a unique function type, so we can give
874 its pointer type a name. (This wins for gdb). */
876 tree vfunc_type = make_node (FUNCTION_TYPE);
877 TREE_TYPE (vfunc_type) = d_int_type;
878 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
879 layout_type (vfunc_type);
881 vtable_entry_type = build_pointer_type (vfunc_type);
884 vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
885 layout_type (vtbl_ptr_type_node);
887 /* When an object is accessed via an interface, this type appears
888 as the first entry in its vtable. */
890 tree domain = build_index_type (size_int (3));
891 vtbl_interface_type_node = build_array_type (ptr_type_node, domain);
894 /* Use `void[]' as a generic dynamic array type. */
895 array_type_node = make_struct_type ("__builtin_void[]", 2,
896 get_identifier ("length"), size_type_node,
897 get_identifier ("ptr"), ptr_type_node);
898 TYPE_DYNAMIC_ARRAY (array_type_node) = 1;
900 null_array_node = d_array_value (array_type_node, size_zero_node,
901 null_pointer_node);
904 /* Handle default attributes. */
906 enum built_in_attribute
908 #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
909 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
910 #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
911 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
912 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
913 #include "builtin-attrs.def"
914 #undef DEF_ATTR_NULL_TREE
915 #undef DEF_ATTR_INT
916 #undef DEF_ATTR_STRING
917 #undef DEF_ATTR_IDENT
918 #undef DEF_ATTR_TREE_LIST
919 ATTR_LAST
922 static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
924 /* Initialize the attribute table for all the supported builtins. */
926 static void
927 d_init_attributes (void)
929 /* Fill in the built_in_attributes array. */
930 #define DEF_ATTR_NULL_TREE(ENUM) \
931 built_in_attributes[(int) ENUM] = NULL_TREE;
932 # define DEF_ATTR_INT(ENUM, VALUE) \
933 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
934 #define DEF_ATTR_STRING(ENUM, VALUE) \
935 built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
936 #define DEF_ATTR_IDENT(ENUM, STRING) \
937 built_in_attributes[(int) ENUM] = get_identifier (STRING);
938 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
939 built_in_attributes[(int) ENUM] \
940 = tree_cons (built_in_attributes[(int) PURPOSE], \
941 built_in_attributes[(int) VALUE], \
942 built_in_attributes[(int) CHAIN]);
943 #include "builtin-attrs.def"
944 #undef DEF_ATTR_NULL_TREE
945 #undef DEF_ATTR_INT
946 #undef DEF_ATTR_STRING
947 #undef DEF_ATTR_IDENT
948 #undef DEF_ATTR_TREE_LIST
951 /* Builtin types. */
953 enum d_builtin_type
955 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
956 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
957 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
958 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
959 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
960 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
961 #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
962 #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
963 ARG6) NAME,
964 #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
965 ARG6, ARG7) NAME,
966 #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
967 ARG6, ARG7, ARG8) NAME,
968 #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
969 ARG6, ARG7, ARG8, ARG9) NAME,
970 #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
971 ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
972 #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
973 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
974 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
975 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
976 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
977 #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
978 #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
979 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
980 NAME,
981 #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
982 ARG6) NAME,
983 #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
984 ARG6, ARG7) NAME,
985 #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
986 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
987 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
988 #include "builtin-types.def"
989 #undef DEF_PRIMITIVE_TYPE
990 #undef DEF_FUNCTION_TYPE_0
991 #undef DEF_FUNCTION_TYPE_1
992 #undef DEF_FUNCTION_TYPE_2
993 #undef DEF_FUNCTION_TYPE_3
994 #undef DEF_FUNCTION_TYPE_4
995 #undef DEF_FUNCTION_TYPE_5
996 #undef DEF_FUNCTION_TYPE_6
997 #undef DEF_FUNCTION_TYPE_7
998 #undef DEF_FUNCTION_TYPE_8
999 #undef DEF_FUNCTION_TYPE_9
1000 #undef DEF_FUNCTION_TYPE_10
1001 #undef DEF_FUNCTION_TYPE_11
1002 #undef DEF_FUNCTION_TYPE_VAR_0
1003 #undef DEF_FUNCTION_TYPE_VAR_1
1004 #undef DEF_FUNCTION_TYPE_VAR_2
1005 #undef DEF_FUNCTION_TYPE_VAR_3
1006 #undef DEF_FUNCTION_TYPE_VAR_4
1007 #undef DEF_FUNCTION_TYPE_VAR_5
1008 #undef DEF_FUNCTION_TYPE_VAR_6
1009 #undef DEF_FUNCTION_TYPE_VAR_7
1010 #undef DEF_FUNCTION_TYPE_VAR_11
1011 #undef DEF_POINTER_TYPE
1012 BT_LAST
1015 typedef enum d_builtin_type builtin_type;
1017 /* A temporary array used in communication with def_fn_type. */
1018 static GTY(()) tree builtin_types[(int) BT_LAST + 1];
1020 /* A helper function for d_init_builtins. Build function type for DEF with
1021 return type RET and N arguments. If VAR is true, then the function should
1022 be variadic after those N arguments.
1024 Takes special care not to ICE if any of the types involved are
1025 error_mark_node, which indicates that said type is not in fact available
1026 (see builtin_type_for_size). In which case the function type as a whole
1027 should be error_mark_node. */
1029 static void
1030 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
1032 tree t;
1033 tree *args = XALLOCAVEC (tree, n);
1034 va_list list;
1035 int i;
1037 va_start (list, n);
1038 for (i = 0; i < n; ++i)
1040 builtin_type a = (builtin_type) va_arg (list, int);
1041 t = builtin_types[a];
1042 if (t == error_mark_node)
1043 goto egress;
1044 args[i] = t;
1047 t = builtin_types[ret];
1048 if (t == error_mark_node)
1049 goto egress;
1050 if (var)
1051 t = build_varargs_function_type_array (t, n, args);
1052 else
1053 t = build_function_type_array (t, n, args);
1055 egress:
1056 builtin_types[def] = t;
1057 va_end (list);
1060 /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
1061 VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
1063 static void
1064 d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
1065 tree va_list_arg_type_node ATTRIBUTE_UNUSED)
1067 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
1068 builtin_types[(int) ENUM] = VALUE;
1069 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
1070 def_fn_type (ENUM, RETURN, 0, 0);
1071 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
1072 def_fn_type (ENUM, RETURN, 0, 1, ARG1);
1073 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
1074 def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
1075 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1076 def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
1077 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1078 def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
1079 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1080 def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1081 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1082 ARG6) \
1083 def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1084 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1085 ARG6, ARG7) \
1086 def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1087 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1088 ARG6, ARG7, ARG8) \
1089 def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1090 ARG7, ARG8);
1091 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1092 ARG6, ARG7, ARG8, ARG9) \
1093 def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1094 ARG7, ARG8, ARG9);
1095 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1096 ARG6, ARG7, ARG8, ARG9, ARG10) \
1097 def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1098 ARG7, ARG8, ARG9, ARG10);
1099 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1100 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1101 def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1102 ARG7, ARG8, ARG9, ARG10, ARG11);
1103 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
1104 def_fn_type (ENUM, RETURN, 1, 0);
1105 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
1106 def_fn_type (ENUM, RETURN, 1, 1, ARG1);
1107 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
1108 def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
1109 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1110 def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
1111 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1112 def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
1113 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1114 def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1115 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1116 ARG6) \
1117 def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1118 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1119 ARG6, ARG7) \
1120 def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1121 #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1122 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1123 def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1124 ARG7, ARG8, ARG9, ARG10, ARG11);
1125 #define DEF_POINTER_TYPE(ENUM, TYPE) \
1126 builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
1128 #include "builtin-types.def"
1130 #undef DEF_PRIMITIVE_TYPE
1131 #undef DEF_FUNCTION_TYPE_1
1132 #undef DEF_FUNCTION_TYPE_2
1133 #undef DEF_FUNCTION_TYPE_3
1134 #undef DEF_FUNCTION_TYPE_4
1135 #undef DEF_FUNCTION_TYPE_5
1136 #undef DEF_FUNCTION_TYPE_6
1137 #undef DEF_FUNCTION_TYPE_7
1138 #undef DEF_FUNCTION_TYPE_8
1139 #undef DEF_FUNCTION_TYPE_9
1140 #undef DEF_FUNCTION_TYPE_10
1141 #undef DEF_FUNCTION_TYPE_11
1142 #undef DEF_FUNCTION_TYPE_VAR_0
1143 #undef DEF_FUNCTION_TYPE_VAR_1
1144 #undef DEF_FUNCTION_TYPE_VAR_2
1145 #undef DEF_FUNCTION_TYPE_VAR_3
1146 #undef DEF_FUNCTION_TYPE_VAR_4
1147 #undef DEF_FUNCTION_TYPE_VAR_5
1148 #undef DEF_FUNCTION_TYPE_VAR_6
1149 #undef DEF_FUNCTION_TYPE_VAR_7
1150 #undef DEF_FUNCTION_TYPE_VAR_11
1151 #undef DEF_POINTER_TYPE
1152 builtin_types[(int) BT_LAST] = NULL_TREE;
1154 d_init_attributes ();
1156 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
1157 NONANSI_P, ATTRS, IMPLICIT, COND) \
1158 if (NAME && COND) \
1159 do_build_builtin_fn (ENUM, NAME, CLASS, \
1160 builtin_types[(int) TYPE], \
1161 BOTH_P, FALLBACK_P, \
1162 built_in_attributes[(int) ATTRS], IMPLICIT);
1163 #include "builtins.def"
1164 #undef DEF_BUILTIN
1167 /* Build builtin functions and types for the D language frontend. */
1169 void
1170 d_init_builtins (void)
1172 d_build_c_type_nodes ();
1173 d_build_d_type_nodes ();
1175 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
1177 /* It might seem natural to make the argument type a pointer, but there
1178 is no implicit casting from arrays to pointers in D. */
1179 d_define_builtins (va_list_type_node, va_list_type_node);
1181 else
1183 d_define_builtins (build_reference_type (va_list_type_node),
1184 va_list_type_node);
1187 targetm.init_builtins ();
1188 build_common_builtin_nodes ();
1191 /* Registration of machine- or os-specific builtin types.
1192 Add to builtin types list for maybe processing later
1193 if `gcc.builtins' was imported into the current module. */
1195 void
1196 d_register_builtin_type (tree type, const char *name)
1198 tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
1199 get_identifier (name), type);
1200 DECL_ARTIFICIAL (decl) = 1;
1202 if (!TYPE_NAME (type))
1203 TYPE_NAME (type) = decl;
1205 vec_safe_push (gcc_builtins_types, decl);
1208 /* Add DECL to builtin functions list for maybe processing later
1209 if `gcc.builtins' was imported into the current module. */
1211 tree
1212 d_builtin_function (tree decl)
1214 if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))
1215 vec_safe_push (gcc_builtins_libfuncs, decl);
1217 vec_safe_push (gcc_builtins_functions, decl);
1218 return decl;
1221 /* Same as d_builtin_function, but used to delay putting in back-end builtin
1222 functions until the ISA that defines the builtin has been declared.
1223 However in D, there is no global namespace. All builtins get pushed into the
1224 `gcc.builtins' module, which is constructed during the semantic analysis
1225 pass, which has already finished by the time target attributes are evaluated.
1226 So builtins are not pushed because they would be ultimately ignored.
1227 The purpose of having this function then is to improve compile-time
1228 reflection support to allow user-code to determine whether a given back end
1229 function is enabled by the ISA. */
1231 tree
1232 d_builtin_function_ext_scope (tree decl)
1234 return decl;
1237 #include "gt-d-d-builtins.h"