d: Merge upstream dmd a5c86f5b9
[official-gcc.git] / gcc / d / d-builtins.cc
blob26ccd00c79a25252ae2c9668673e0d1491dade71
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 for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
85 tree t = builtin_converted_decls[i].ctype;
86 if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type))
87 return builtin_converted_decls[i].dtype;
90 switch (TREE_CODE (type))
92 case POINTER_TYPE:
93 dtype = build_frontend_type (TREE_TYPE (type));
94 if (dtype)
96 /* Check for char * first. Needs to be done for chars/string. */
97 if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)
98 return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);
100 if (dtype->ty == Tfunction)
101 return (TypePointer::create (dtype))->addMod (mod);
103 return dtype->pointerTo ()->addMod (mod);
105 break;
107 case REFERENCE_TYPE:
108 dtype = build_frontend_type (TREE_TYPE (type));
109 if (dtype)
111 /* Want to assign ctype directly so that the REFERENCE_TYPE code
112 can be turned into as an `inout' argument. Can't use pointerTo(),
113 because the returned Type is shared. */
114 dtype = (TypePointer::create (dtype))->addMod (mod);
115 dtype->ctype = type;
116 builtin_converted_decls.safe_push (builtin_data (dtype, type));
117 return dtype;
119 break;
121 case BOOLEAN_TYPE:
122 /* Should be no need for size checking. */
123 return Type::tbool->addMod (mod);
125 case INTEGER_TYPE:
127 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
128 bool unsignedp = TYPE_UNSIGNED (type);
130 /* For now, skip support for cent/ucent until the frontend
131 has better support for handling it. */
132 for (size_t i = Tint8; i <= Tuns64; i++)
134 dtype = Type::basic[i];
136 /* Search for type matching size and signedness. */
137 if (unsignedp != dtype->isunsigned ()
138 || size != dtype->size ())
139 continue;
141 return dtype->addMod (mod);
143 break;
146 case REAL_TYPE:
148 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
150 for (size_t i = Tfloat32; i <= Tfloat80; i++)
152 dtype = Type::basic[i];
154 /* Search for type matching size. */
155 if (dtype->size () != size)
156 continue;
158 return dtype->addMod (mod);
160 break;
163 case COMPLEX_TYPE:
165 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
166 for (size_t i = Tcomplex32; i <= Tcomplex80; i++)
168 dtype = Type::basic[i];
170 /* Search for type matching size. */
171 if (dtype->size () != size)
172 continue;
174 return dtype->addMod (mod);
176 break;
179 case VOID_TYPE:
180 return Type::tvoid->addMod (mod);
182 case ARRAY_TYPE:
183 dtype = build_frontend_type (TREE_TYPE (type));
184 if (dtype)
186 tree index = TYPE_DOMAIN (type);
187 tree ub = TYPE_MAX_VALUE (index);
188 tree lb = TYPE_MIN_VALUE (index);
190 tree length = fold_build2 (MINUS_EXPR, TREE_TYPE (lb), ub, lb);
191 length = size_binop (PLUS_EXPR, size_one_node,
192 convert (sizetype, length));
194 dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
195 builtin_converted_decls.safe_push (builtin_data (dtype, type));
196 return dtype;
198 break;
200 case VECTOR_TYPE:
202 unsigned HOST_WIDE_INT nunits;
203 if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits))
204 break;
206 dtype = build_frontend_type (TREE_TYPE (type));
207 if (!dtype)
208 break;
210 dtype = dtype->sarrayOf (nunits)->addMod (mod);
211 if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ()))
212 break;
214 dtype = (TypeVector::create (dtype))->addMod (mod);
215 builtin_converted_decls.safe_push (builtin_data (dtype, type));
216 return dtype;
219 case RECORD_TYPE:
221 Identifier *ident = TYPE_IDENTIFIER (type) ?
222 Identifier::idPool (IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))) : NULL;
224 /* Neither the `object' and `gcc.builtins' modules will not exist when
225 this is called. Use a stub `object' module parent in the meantime.
226 If `gcc.builtins' is later imported, the parent will be overridden
227 with the correct module symbol. */
228 static Identifier *object = Identifier::idPool ("object");
229 static Module *stubmod = Module::create ("object.d", object, 0, 0);
231 StructDeclaration *sdecl = StructDeclaration::create (Loc (), ident,
232 false);
233 sdecl->parent = stubmod;
234 sdecl->structsize = int_size_in_bytes (type);
235 sdecl->alignsize = TYPE_ALIGN_UNIT (type);
236 sdecl->alignment = STRUCTALIGN_DEFAULT;
237 sdecl->sizeok = SIZEOKdone;
238 sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
239 sdecl->type->ctype = type;
240 sdecl->type->merge2 ();
242 /* Add both named and anonymous fields as members of the struct.
243 Anonymous fields still need a name in D, so call them "__pad%d". */
244 int anonfield_id = 0;
245 sdecl->members = new Dsymbols;
247 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
249 Type *ftype = build_frontend_type (TREE_TYPE (field));
250 if (!ftype)
252 delete sdecl->members;
253 return NULL;
256 Identifier *fident;
257 if (DECL_NAME (field) == NULL_TREE)
258 fident = Identifier::generateId ("__pad", anonfield_id++);
259 else
261 const char *name = IDENTIFIER_POINTER (DECL_NAME (field));
262 fident = Identifier::idPool (name);
265 VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
266 NULL);
267 vd->parent = sdecl;
268 vd->offset = tree_to_uhwi (byte_position (field));
269 vd->semanticRun = PASSsemanticdone;
270 vd->csym = field;
271 sdecl->members->push (vd);
272 sdecl->fields.push (vd);
275 dtype = sdecl->type;
276 builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));
277 return dtype;
280 case FUNCTION_TYPE:
281 dtype = build_frontend_type (TREE_TYPE (type));
282 if (dtype)
284 tree parms = TYPE_ARG_TYPES (type);
285 VarArg varargs_p = VARARGvariadic;
287 Parameters *args = new Parameters;
288 args->reserve (list_length (parms));
290 /* Attempt to convert all parameter types. */
291 for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))
293 tree argtype = TREE_VALUE (parm);
294 if (argtype == void_type_node)
296 varargs_p = VARARGnone;
297 break;
300 StorageClass sc = STCundefined;
301 if (TREE_CODE (argtype) == REFERENCE_TYPE)
303 argtype = TREE_TYPE (argtype);
304 sc |= STCref;
307 Type *targ = build_frontend_type (argtype);
308 if (!targ)
310 delete args;
311 return NULL;
314 args->push (Parameter::create (sc, targ, NULL, NULL));
317 /* GCC generic and placeholder built-ins are marked as variadic, yet
318 have no named parameters, and so can't be represented in D. */
319 if (args->length != 0 || varargs_p == VARARGnone)
321 dtype = TypeFunction::create (args, dtype, varargs_p, LINKc);
322 return dtype->addMod (mod);
325 break;
327 default:
328 break;
331 return NULL;
334 /* Attempt to convert GCC evaluated CST to a D Frontend Expression.
335 LOC is the location in the source file where this CST is being evaluated.
336 This is used for getting the CTFE value out of a const-folded builtin,
337 returns NULL if it cannot convert CST. */
339 Expression *
340 d_eval_constant_expression (const Loc &loc, tree cst)
342 STRIP_TYPE_NOPS (cst);
343 Type *type = build_frontend_type (TREE_TYPE (cst));
345 if (type)
347 /* Convert our GCC CST tree into a D Expression. This seems like we are
348 trying too hard, as these will only be converted back to a tree again
349 later in the codegen pass, but satisfies the need to have GCC built-ins
350 CTFE-able in the frontend. */
351 tree_code code = TREE_CODE (cst);
352 if (code == COMPLEX_CST)
354 real_value re = TREE_REAL_CST (TREE_REALPART (cst));
355 real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
356 complex_t value = complex_t (ldouble (re), ldouble (im));
357 return ComplexExp::create (loc, value, type);
359 else if (code == INTEGER_CST)
361 dinteger_t value = TREE_INT_CST_LOW (cst);
362 return IntegerExp::create (loc, value, type);
364 else if (code == REAL_CST)
366 real_value value = TREE_REAL_CST (cst);
367 return RealExp::create (loc, ldouble (value), type);
369 else if (code == STRING_CST)
371 const void *string = TREE_STRING_POINTER (cst);
372 size_t len = TREE_STRING_LENGTH (cst);
373 return StringExp::create (loc, CONST_CAST (void *, string), len);
375 else if (code == VECTOR_CST)
377 dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant ();
378 Expressions *elements = new Expressions;
379 elements->setDim (nunits);
381 for (size_t i = 0; i < nunits; i++)
383 Expression *elem
384 = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
385 if (elem == NULL)
386 return NULL;
388 (*elements)[i] = elem;
391 Expression *e = ArrayLiteralExp::create (loc, elements);
392 e->type = type->isTypeVector ()->basetype;
394 return VectorExp::create (loc, e, type);
396 else if (code == ADDR_EXPR)
398 /* Special handling for trees constructed by build_string_literal.
399 What we receive is an `&"string"[0]' expression, strip off the
400 outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
401 tree pointee = TREE_OPERAND (cst, 0);
403 if (TREE_CODE (pointee) != ARRAY_REF
404 || TREE_OPERAND (pointee, 1) != integer_zero_node
405 || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
406 return NULL;
408 return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
412 return NULL;
415 /* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.
416 Adds IDENT to the list of predefined version identifiers. */
418 void
419 d_add_builtin_version (const char* ident)
421 /* For now, we need to tell the D frontend what platform is being targeted.
422 This should be removed once the frontend has been fixed. */
423 if (strcmp (ident, "linux") == 0)
424 global.params.isLinux = true;
425 else if (strcmp (ident, "OSX") == 0)
426 global.params.isOSX = true;
427 else if (strcmp (ident, "Windows") == 0)
428 global.params.isWindows = true;
429 else if (strcmp (ident, "FreeBSD") == 0)
430 global.params.isFreeBSD = true;
431 else if (strcmp (ident, "OpenBSD") == 0)
432 global.params.isOpenBSD = true;
433 else if (strcmp (ident, "Solaris") == 0)
434 global.params.isSolaris = true;
435 /* The is64bit field only refers to x86_64 target. */
436 else if (strcmp (ident, "X86_64") == 0)
437 global.params.is64bit = true;
438 /* No other fields are required to be set for the frontend. */
440 VersionCondition::addPredefinedGlobalIdent (ident);
443 /* Initialize the list of all the predefined version identifiers. */
445 void
446 d_init_versions (void)
448 VersionCondition::addPredefinedGlobalIdent ("GNU");
449 VersionCondition::addPredefinedGlobalIdent ("D_Version2");
451 if (BYTES_BIG_ENDIAN)
452 VersionCondition::addPredefinedGlobalIdent ("BigEndian");
453 else
454 VersionCondition::addPredefinedGlobalIdent ("LittleEndian");
456 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
457 VersionCondition::addPredefinedGlobalIdent ("GNU_SjLj_Exceptions");
458 else if (targetm_common.except_unwind_info (&global_options) == UI_SEH)
459 VersionCondition::addPredefinedGlobalIdent ("GNU_SEH_Exceptions");
460 else if (targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
461 VersionCondition::addPredefinedGlobalIdent ("GNU_DWARF2_Exceptions");
463 if (!targetm.have_tls)
464 VersionCondition::addPredefinedGlobalIdent ("GNU_EMUTLS");
466 if (STACK_GROWS_DOWNWARD)
467 VersionCondition::addPredefinedGlobalIdent ("GNU_StackGrowsDown");
469 /* Should define this anyway to set us apart from the competition. */
470 VersionCondition::addPredefinedGlobalIdent ("GNU_InlineAsm");
472 /* LP64 only means 64bit pointers in D. */
473 if (global.params.isLP64)
474 VersionCondition::addPredefinedGlobalIdent ("D_LP64");
476 /* Setting `global.params.cov' forces module info generation which is
477 not needed for the GCC coverage implementation. Instead, just
478 test flag_test_coverage while leaving `global.params.cov' unset. */
479 if (flag_test_coverage)
480 VersionCondition::addPredefinedGlobalIdent ("D_Coverage");
481 if (flag_pic)
482 VersionCondition::addPredefinedGlobalIdent ("D_PIC");
484 if (global.params.doDocComments)
485 VersionCondition::addPredefinedGlobalIdent ("D_Ddoc");
487 if (global.params.useUnitTests)
488 VersionCondition::addPredefinedGlobalIdent ("unittest");
490 if (global.params.useAssert == CHECKENABLEon)
491 VersionCondition::addPredefinedGlobalIdent ("assert");
493 if (global.params.useArrayBounds == CHECKENABLEoff)
494 VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");
496 if (global.params.betterC)
497 VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
498 else
500 VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
501 VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
502 VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
505 VersionCondition::addPredefinedGlobalIdent ("all");
507 /* Emit all target-specific version identifiers. */
508 targetdm.d_cpu_versions ();
509 targetdm.d_os_versions ();
511 VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
514 /* A helper for d_build_builtins_module. Return a new ALIAS for TYPE.
515 Analogous to `alias ALIAS = TYPE' in D code. */
517 static AliasDeclaration *
518 build_alias_declaration (const char *alias, Type *type)
520 return AliasDeclaration::create (Loc (), Identifier::idPool (alias), type);
523 /* A helper function for Target::loadModule. Generates all code for the
524 `gcc.builtins' module, whose frontend symbol should be M. */
526 void
527 d_build_builtins_module (Module *m)
529 Dsymbols *members = new Dsymbols;
530 tree decl;
532 for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i)
534 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
535 Type *t = build_frontend_type (TREE_TYPE (decl));
536 TypeFunction *tf = t ? t->isTypeFunction () : NULL;
538 /* Cannot create built-in function type for DECL. */
539 if (!tf)
540 continue;
542 /* A few notes on D2 attributes applied to builtin functions:
543 - It is assumed that built-ins solely provided by the compiler are
544 considered @safe and pure.
545 - Built-ins that correspond to `extern(C)' functions in the standard
546 library that have `__attribute__(nothrow)' are considered `@trusted'.
547 - The purity of a built-in can vary depending on compiler flags set
548 upon initialization, or by the `-foptions' passed, such as
549 flag_unsafe_math_optimizations.
550 - Built-ins never use the GC or raise a D exception, and so are always
551 marked as `nothrow' and `@nogc'. */
552 tf->purity = DECL_PURE_P (decl) ? PUREstrong
553 : TREE_READONLY (decl) ? PUREconst
554 : DECL_IS_NOVOPS (decl) ? PUREweak
555 : !DECL_ASSEMBLER_NAME_SET_P (decl) ? PUREweak
556 : PUREimpure;
557 tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUSTsafe
558 : TREE_NOTHROW (decl) ? TRUSTtrusted
559 : TRUSTsystem;
560 tf->isnothrow = true;
561 tf->isnogc = true;
563 FuncDeclaration *func
564 = FuncDeclaration::create (Loc (), Loc (),
565 Identifier::idPool (name),
566 STCextern, tf);
567 DECL_LANG_SPECIFIC (decl) = build_lang_decl (func);
568 func->csym = decl;
569 func->builtin = BUILTINyes;
571 members->push (func);
574 for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i)
576 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
577 Type *t = build_frontend_type (TREE_TYPE (decl));
579 /* Cannot create built-in type for DECL. */
580 if (!t)
581 continue;
583 members->push (build_alias_declaration (name, t));
586 /* Iterate through the target-specific builtin types for va_list. */
587 if (targetm.enum_va_list_p)
589 const char *name;
590 tree type;
592 for (int i = 0; targetm.enum_va_list_p (i, &name, &type); ++i)
594 Type *t = build_frontend_type (type);
595 /* Cannot create built-in type. */
596 if (!t)
597 continue;
599 members->push (build_alias_declaration (name, t));
603 /* Push out declarations for any RECORD_TYPE types encountered when building
604 all builtin functions and types. */
605 for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
607 /* Currently, there is no need to run semantic, but we do want to output
608 initializers, typeinfo, and others on demand. */
609 Dsymbol *dsym = builtin_converted_decls[i].dsym;
610 if (dsym != NULL && !dsym->isAnonymous ())
612 dsym->parent = m;
613 members->push (dsym);
617 /* Expose target-specific va_list type. */
618 Type *tvalist = target.va_listType (Loc (), NULL);
619 TypeStruct *ts = tvalist->isTypeStruct ();
620 if (ts == NULL || !ts->sym->isAnonymous ())
621 members->push (build_alias_declaration ("__builtin_va_list", tvalist));
622 else
624 ts->sym->ident = Identifier::idPool ("__builtin_va_list");
625 members->push (ts->sym);
628 /* Expose target-specific integer types to the builtins module. */
630 Type *t = build_frontend_type (long_integer_type_node);
631 members->push (build_alias_declaration ("__builtin_clong", t));
633 t = build_frontend_type (long_unsigned_type_node);
634 members->push (build_alias_declaration ("__builtin_culong", t));
636 t = build_frontend_type (long_long_integer_type_node);
637 members->push (build_alias_declaration ("__builtin_clonglong", t));
639 t = build_frontend_type (long_long_unsigned_type_node);
640 members->push (build_alias_declaration ("__builtin_culonglong", t));
642 t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 0));
643 members->push (build_alias_declaration ("__builtin_machine_byte", t));
645 t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 1));
646 members->push (build_alias_declaration ("__builtin_machine_ubyte", t));
648 t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 0));
649 members->push (build_alias_declaration ("__builtin_machine_int", t));
651 t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 1));
652 members->push (build_alias_declaration ("__builtin_machine_uint", t));
654 t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 0));
655 members->push (build_alias_declaration ("__builtin_pointer_int", t));
657 t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 1));
658 members->push (build_alias_declaration ("__builtin_pointer_uint", t));
660 /* _Unwind_Word has its own target specific mode. */
661 machine_mode mode = targetm.unwind_word_mode ();
662 t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 0));
663 members->push (build_alias_declaration ("__builtin_unwind_int", t));
665 t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 1));
666 members->push (build_alias_declaration ("__builtin_unwind_uint", t));
669 m->members->push (LinkDeclaration::create (LINKc, members));
672 /* Search for any `extern(C)' functions that match any known GCC library builtin
673 function in D and override its internal back-end symbol. */
675 static void
676 maybe_set_builtin_1 (Dsymbol *d)
678 AttribDeclaration *ad = d->isAttribDeclaration ();
679 FuncDeclaration *fd = d->isFuncDeclaration ();
681 if (ad != NULL)
683 /* Recursively search through attribute decls. */
684 Dsymbols *decls = ad->include (NULL);
685 if (decls && decls->length)
687 for (size_t i = 0; i < decls->length; i++)
689 Dsymbol *sym = (*decls)[i];
690 maybe_set_builtin_1 (sym);
694 else if (fd && !fd->fbody)
696 tree t;
698 for (size_t i = 0; vec_safe_iterate (gcc_builtins_libfuncs, i, &t); ++i)
700 gcc_assert (DECL_ASSEMBLER_NAME_SET_P (t));
702 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
703 if (fd->ident != Identifier::idPool (name))
704 continue;
706 /* Found a match, tell the frontend this is a builtin. */
707 DECL_LANG_SPECIFIC (t) = build_lang_decl (fd);
708 fd->csym = t;
709 fd->builtin = BUILTINyes;
710 return;
715 /* A helper function for Target::loadModule. Traverse all members in module M
716 to search for any functions that can be mapped to any GCC builtin. */
718 void
719 d_maybe_set_builtin (Module *m)
721 if (!m || !m->members)
722 return;
724 for (size_t i = 0; i < m->members->length; i++)
726 Dsymbol *sym = (*m->members)[i];
727 maybe_set_builtin_1 (sym);
731 /* Used to help initialize the builtin-types.def table. When a type of
732 the correct size doesn't exist, use error_mark_node instead of NULL.
733 The latter results in segfaults even when a decl using the type doesn't
734 get invoked. */
736 static tree
737 builtin_type_for_size (int size, bool unsignedp)
739 tree type = lang_hooks.types.type_for_size (size, unsignedp);
740 return type ? type : error_mark_node;
743 /* Support for DEF_BUILTIN. */
745 static void
746 do_build_builtin_fn (built_in_function fncode,
747 const char *name,
748 built_in_class fnclass,
749 tree fntype, bool both_p, bool fallback_p,
750 tree fnattrs, bool implicit_p)
752 tree decl;
753 const char *libname;
755 if (fntype == error_mark_node)
756 return;
758 gcc_assert ((!both_p && !fallback_p)
759 || !strncmp (name, "__builtin_",
760 strlen ("__builtin_")));
762 libname = name + strlen ("__builtin_");
764 decl = add_builtin_function (name, fntype, fncode, fnclass,
765 fallback_p ? libname : NULL, fnattrs);
767 set_builtin_decl (fncode, decl, implicit_p);
770 /* Standard data types to be used in builtin argument declarations. */
772 static GTY(()) tree string_type_node;
773 static GTY(()) tree const_string_type_node;
774 static GTY(()) tree wint_type_node;
775 static GTY(()) tree intmax_type_node;
776 static GTY(()) tree uintmax_type_node;
777 static GTY(()) tree signed_size_type_node;
780 /* Build nodes that would have been created by the C front-end; necessary
781 for including builtin-types.def and ultimately builtins.def. */
783 static void
784 d_build_c_type_nodes (void)
786 void_list_node = build_tree_list (NULL_TREE, void_type_node);
787 string_type_node = build_pointer_type (char_type_node);
788 const_string_type_node
789 = build_pointer_type (build_qualified_type (char_type_node,
790 TYPE_QUAL_CONST));
792 if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
794 intmax_type_node = integer_type_node;
795 uintmax_type_node = unsigned_type_node;
797 else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
799 intmax_type_node = long_integer_type_node;
800 uintmax_type_node = long_unsigned_type_node;
802 else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
804 intmax_type_node = long_long_integer_type_node;
805 uintmax_type_node = long_long_unsigned_type_node;
807 else
808 gcc_unreachable ();
810 signed_size_type_node = signed_type_for (size_type_node);
811 wint_type_node = unsigned_type_node;
812 pid_type_node = integer_type_node;
815 /* Build nodes that are used by the D front-end.
816 These are distinct from C types. */
818 static void
819 d_build_d_type_nodes (void)
821 /* Integral types. */
822 d_byte_type = make_signed_type (8);
823 d_ubyte_type = make_unsigned_type (8);
825 d_short_type = make_signed_type (16);
826 d_ushort_type = make_unsigned_type (16);
828 d_int_type = make_signed_type (32);
829 d_uint_type = make_unsigned_type (32);
831 d_long_type = make_signed_type (64);
832 d_ulong_type = make_unsigned_type (64);
834 d_cent_type = make_signed_type (128);
835 d_ucent_type = make_unsigned_type (128);
838 /* Re-define size_t as a D type. */
839 machine_mode type_mode = TYPE_MODE (size_type_node);
840 size_type_node = lang_hooks.types.type_for_mode (type_mode, 1);
843 /* Bool and Character types. */
844 d_bool_type = make_unsigned_type (1);
845 TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);
847 char8_type_node = make_unsigned_type (8);
848 TYPE_STRING_FLAG (char8_type_node) = 1;
850 char16_type_node = make_unsigned_type (16);
851 TYPE_STRING_FLAG (char16_type_node) = 1;
853 char32_type_node = make_unsigned_type (32);
854 TYPE_STRING_FLAG (char32_type_node) = 1;
856 /* Imaginary types. */
857 ifloat_type_node = build_distinct_type_copy (float_type_node);
858 TYPE_IMAGINARY_FLOAT (ifloat_type_node) = 1;
860 idouble_type_node = build_distinct_type_copy (double_type_node);
861 TYPE_IMAGINARY_FLOAT (idouble_type_node) = 1;
863 ireal_type_node = build_distinct_type_copy (long_double_type_node);
864 TYPE_IMAGINARY_FLOAT (ireal_type_node) = 1;
866 /* Calling build_ctype() links the front-end Type to the GCC node,
867 and sets the TYPE_NAME to the D language type. */
868 for (unsigned ty = 0; ty < TMAX; ty++)
870 if (Type::basic[ty] != NULL)
871 build_ctype (Type::basic[ty]);
874 /* Used for ModuleInfo, ClassInfo, and Interface decls. */
875 unknown_type_node = make_node (RECORD_TYPE);
877 /* Make sure we get a unique function type, so we can give
878 its pointer type a name. (This wins for gdb). */
880 tree vfunc_type = make_node (FUNCTION_TYPE);
881 TREE_TYPE (vfunc_type) = d_int_type;
882 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
883 layout_type (vfunc_type);
885 vtable_entry_type = build_pointer_type (vfunc_type);
888 vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
889 layout_type (vtbl_ptr_type_node);
891 /* When an object is accessed via an interface, this type appears
892 as the first entry in its vtable. */
894 tree domain = build_index_type (size_int (3));
895 vtbl_interface_type_node = build_array_type (ptr_type_node, domain);
898 /* Use `void[]' as a generic dynamic array type. */
899 array_type_node = make_struct_type ("__builtin_void[]", 2,
900 get_identifier ("length"), size_type_node,
901 get_identifier ("ptr"), ptr_type_node);
902 TYPE_DYNAMIC_ARRAY (array_type_node) = 1;
904 null_array_node = d_array_value (array_type_node, size_zero_node,
905 null_pointer_node);
908 /* Handle default attributes. */
910 enum built_in_attribute
912 #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
913 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
914 #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
915 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
916 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
917 #include "builtin-attrs.def"
918 #undef DEF_ATTR_NULL_TREE
919 #undef DEF_ATTR_INT
920 #undef DEF_ATTR_STRING
921 #undef DEF_ATTR_IDENT
922 #undef DEF_ATTR_TREE_LIST
923 ATTR_LAST
926 static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
928 /* Initialize the attribute table for all the supported builtins. */
930 static void
931 d_init_attributes (void)
933 /* Fill in the built_in_attributes array. */
934 #define DEF_ATTR_NULL_TREE(ENUM) \
935 built_in_attributes[(int) ENUM] = NULL_TREE;
936 # define DEF_ATTR_INT(ENUM, VALUE) \
937 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
938 #define DEF_ATTR_STRING(ENUM, VALUE) \
939 built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
940 #define DEF_ATTR_IDENT(ENUM, STRING) \
941 built_in_attributes[(int) ENUM] = get_identifier (STRING);
942 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
943 built_in_attributes[(int) ENUM] \
944 = tree_cons (built_in_attributes[(int) PURPOSE], \
945 built_in_attributes[(int) VALUE], \
946 built_in_attributes[(int) CHAIN]);
947 #include "builtin-attrs.def"
948 #undef DEF_ATTR_NULL_TREE
949 #undef DEF_ATTR_INT
950 #undef DEF_ATTR_STRING
951 #undef DEF_ATTR_IDENT
952 #undef DEF_ATTR_TREE_LIST
955 /* Builtin types. */
957 enum d_builtin_type
959 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
960 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
961 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
962 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
963 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
964 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
965 #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
966 #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
967 ARG6) NAME,
968 #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
969 ARG6, ARG7) NAME,
970 #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
971 ARG6, ARG7, ARG8) NAME,
972 #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
973 ARG6, ARG7, ARG8, ARG9) NAME,
974 #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
975 ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
976 #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
977 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
978 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
979 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
980 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
981 #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
982 #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
983 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
984 NAME,
985 #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
986 ARG6) NAME,
987 #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
988 ARG6, ARG7) NAME,
989 #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
990 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
991 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
992 #include "builtin-types.def"
993 #undef DEF_PRIMITIVE_TYPE
994 #undef DEF_FUNCTION_TYPE_0
995 #undef DEF_FUNCTION_TYPE_1
996 #undef DEF_FUNCTION_TYPE_2
997 #undef DEF_FUNCTION_TYPE_3
998 #undef DEF_FUNCTION_TYPE_4
999 #undef DEF_FUNCTION_TYPE_5
1000 #undef DEF_FUNCTION_TYPE_6
1001 #undef DEF_FUNCTION_TYPE_7
1002 #undef DEF_FUNCTION_TYPE_8
1003 #undef DEF_FUNCTION_TYPE_9
1004 #undef DEF_FUNCTION_TYPE_10
1005 #undef DEF_FUNCTION_TYPE_11
1006 #undef DEF_FUNCTION_TYPE_VAR_0
1007 #undef DEF_FUNCTION_TYPE_VAR_1
1008 #undef DEF_FUNCTION_TYPE_VAR_2
1009 #undef DEF_FUNCTION_TYPE_VAR_3
1010 #undef DEF_FUNCTION_TYPE_VAR_4
1011 #undef DEF_FUNCTION_TYPE_VAR_5
1012 #undef DEF_FUNCTION_TYPE_VAR_6
1013 #undef DEF_FUNCTION_TYPE_VAR_7
1014 #undef DEF_FUNCTION_TYPE_VAR_11
1015 #undef DEF_POINTER_TYPE
1016 BT_LAST
1019 typedef enum d_builtin_type builtin_type;
1021 /* A temporary array used in communication with def_fn_type. */
1022 static GTY(()) tree builtin_types[(int) BT_LAST + 1];
1024 /* A helper function for d_init_builtins. Build function type for DEF with
1025 return type RET and N arguments. If VAR is true, then the function should
1026 be variadic after those N arguments.
1028 Takes special care not to ICE if any of the types involved are
1029 error_mark_node, which indicates that said type is not in fact available
1030 (see builtin_type_for_size). In which case the function type as a whole
1031 should be error_mark_node. */
1033 static void
1034 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
1036 tree t;
1037 tree *args = XALLOCAVEC (tree, n);
1038 va_list list;
1039 int i;
1041 va_start (list, n);
1042 for (i = 0; i < n; ++i)
1044 builtin_type a = (builtin_type) va_arg (list, int);
1045 t = builtin_types[a];
1046 if (t == error_mark_node)
1047 goto egress;
1048 args[i] = t;
1051 t = builtin_types[ret];
1052 if (t == error_mark_node)
1053 goto egress;
1054 if (var)
1055 t = build_varargs_function_type_array (t, n, args);
1056 else
1057 t = build_function_type_array (t, n, args);
1059 egress:
1060 builtin_types[def] = t;
1061 va_end (list);
1064 /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
1065 VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
1067 static void
1068 d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
1069 tree va_list_arg_type_node ATTRIBUTE_UNUSED)
1071 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
1072 builtin_types[(int) ENUM] = VALUE;
1073 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
1074 def_fn_type (ENUM, RETURN, 0, 0);
1075 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
1076 def_fn_type (ENUM, RETURN, 0, 1, ARG1);
1077 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
1078 def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
1079 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1080 def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
1081 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1082 def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
1083 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1084 def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1085 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1086 ARG6) \
1087 def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1088 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1089 ARG6, ARG7) \
1090 def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1091 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1092 ARG6, ARG7, ARG8) \
1093 def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1094 ARG7, ARG8);
1095 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1096 ARG6, ARG7, ARG8, ARG9) \
1097 def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1098 ARG7, ARG8, ARG9);
1099 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1100 ARG6, ARG7, ARG8, ARG9, ARG10) \
1101 def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1102 ARG7, ARG8, ARG9, ARG10);
1103 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1104 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1105 def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1106 ARG7, ARG8, ARG9, ARG10, ARG11);
1107 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
1108 def_fn_type (ENUM, RETURN, 1, 0);
1109 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
1110 def_fn_type (ENUM, RETURN, 1, 1, ARG1);
1111 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
1112 def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
1113 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1114 def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
1115 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1116 def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
1117 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1118 def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1119 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1120 ARG6) \
1121 def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1122 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1123 ARG6, ARG7) \
1124 def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1125 #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1126 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1127 def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1128 ARG7, ARG8, ARG9, ARG10, ARG11);
1129 #define DEF_POINTER_TYPE(ENUM, TYPE) \
1130 builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
1132 #include "builtin-types.def"
1134 #undef DEF_PRIMITIVE_TYPE
1135 #undef DEF_FUNCTION_TYPE_1
1136 #undef DEF_FUNCTION_TYPE_2
1137 #undef DEF_FUNCTION_TYPE_3
1138 #undef DEF_FUNCTION_TYPE_4
1139 #undef DEF_FUNCTION_TYPE_5
1140 #undef DEF_FUNCTION_TYPE_6
1141 #undef DEF_FUNCTION_TYPE_7
1142 #undef DEF_FUNCTION_TYPE_8
1143 #undef DEF_FUNCTION_TYPE_9
1144 #undef DEF_FUNCTION_TYPE_10
1145 #undef DEF_FUNCTION_TYPE_11
1146 #undef DEF_FUNCTION_TYPE_VAR_0
1147 #undef DEF_FUNCTION_TYPE_VAR_1
1148 #undef DEF_FUNCTION_TYPE_VAR_2
1149 #undef DEF_FUNCTION_TYPE_VAR_3
1150 #undef DEF_FUNCTION_TYPE_VAR_4
1151 #undef DEF_FUNCTION_TYPE_VAR_5
1152 #undef DEF_FUNCTION_TYPE_VAR_6
1153 #undef DEF_FUNCTION_TYPE_VAR_7
1154 #undef DEF_FUNCTION_TYPE_VAR_11
1155 #undef DEF_POINTER_TYPE
1156 builtin_types[(int) BT_LAST] = NULL_TREE;
1158 d_init_attributes ();
1160 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
1161 NONANSI_P, ATTRS, IMPLICIT, COND) \
1162 if (NAME && COND) \
1163 do_build_builtin_fn (ENUM, NAME, CLASS, \
1164 builtin_types[(int) TYPE], \
1165 BOTH_P, FALLBACK_P, \
1166 built_in_attributes[(int) ATTRS], IMPLICIT);
1167 #include "builtins.def"
1168 #undef DEF_BUILTIN
1171 /* Build builtin functions and types for the D language frontend. */
1173 void
1174 d_init_builtins (void)
1176 d_build_c_type_nodes ();
1177 d_build_d_type_nodes ();
1179 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
1181 /* It might seem natural to make the argument type a pointer, but there
1182 is no implicit casting from arrays to pointers in D. */
1183 d_define_builtins (va_list_type_node, va_list_type_node);
1185 else
1187 d_define_builtins (build_reference_type (va_list_type_node),
1188 va_list_type_node);
1191 targetm.init_builtins ();
1192 build_common_builtin_nodes ();
1195 /* Registration of machine- or os-specific builtin types.
1196 Add to builtin types list for maybe processing later
1197 if `gcc.builtins' was imported into the current module. */
1199 void
1200 d_register_builtin_type (tree type, const char *name)
1202 tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
1203 get_identifier (name), type);
1204 DECL_ARTIFICIAL (decl) = 1;
1206 if (!TYPE_NAME (type))
1207 TYPE_NAME (type) = decl;
1209 vec_safe_push (gcc_builtins_types, decl);
1212 /* Add DECL to builtin functions list for maybe processing later
1213 if `gcc.builtins' was imported into the current module. */
1215 tree
1216 d_builtin_function (tree decl)
1218 if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))
1219 vec_safe_push (gcc_builtins_libfuncs, decl);
1221 vec_safe_push (gcc_builtins_functions, decl);
1222 return decl;
1226 #include "gt-d-d-builtins.h"