]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/d/d-builtins.cc
d: Compile-time reflection for supported built-ins (PR101127)
[thirdparty/gcc.git] / gcc / d / d-builtins.cc
CommitLineData
b4c522fa 1/* d-builtins.cc -- GCC builtins support for D.
99dee823 2 Copyright (C) 2006-2021 Free Software Foundation, Inc.
b4c522fa
IB
3
4GCC is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 3, or (at your option)
7any later version.
8
9GCC is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with GCC; see the file COPYING3. If not see
16<http://www.gnu.org/licenses/>. */
17
18#include "config.h"
19#include "system.h"
20#include "coretypes.h"
21
22#include "dmd/attrib.h"
23#include "dmd/aggregate.h"
24#include "dmd/cond.h"
25#include "dmd/declaration.h"
26#include "dmd/expression.h"
27#include "dmd/identifier.h"
28#include "dmd/module.h"
29#include "dmd/mtype.h"
5905cbdb 30#include "dmd/target.h"
b4c522fa
IB
31
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"
40
41#include "d-tree.h"
42#include "d-target.h"
43
44
af3c19f0
IB
45static GTY(()) vec <tree, va_gc> *gcc_builtins_functions = NULL;
46static GTY(()) vec <tree, va_gc> *gcc_builtins_libfuncs = NULL;
47static GTY(()) vec <tree, va_gc> *gcc_builtins_types = NULL;
b4c522fa
IB
48
49/* Record built-in types and their associated decls for re-use when
50 generating the `gcc.builtins' module. */
51
52struct builtin_data
53{
54 Type *dtype;
55 tree ctype;
56 Dsymbol *dsym;
57
58 builtin_data (Type *t, tree c, Dsymbol *d = NULL)
59 : dtype(t), ctype(c), dsym(d)
60 { }
61};
62
af3c19f0 63static vec <builtin_data> builtin_converted_decls;
b4c522fa
IB
64
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. */
70
5905cbdb 71Type *
b4c522fa
IB
72build_frontend_type (tree type)
73{
74 Type *dtype;
75 MOD mod = 0;
76
77 if (TYPE_READONLY (type))
78 mod |= MODconst;
79 if (TYPE_VOLATILE (type))
80 mod |= MODshared;
81
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)
84 {
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;
88 }
89
90 switch (TREE_CODE (type))
91 {
92 case POINTER_TYPE:
93 dtype = build_frontend_type (TREE_TYPE (type));
94 if (dtype)
95 {
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);
99
100 if (dtype->ty == Tfunction)
101 return (TypePointer::create (dtype))->addMod (mod);
102
103 return dtype->pointerTo ()->addMod (mod);
104 }
105 break;
106
107 case REFERENCE_TYPE:
108 dtype = build_frontend_type (TREE_TYPE (type));
109 if (dtype)
110 {
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;
118 }
119 break;
120
121 case BOOLEAN_TYPE:
122 /* Should be no need for size checking. */
123 return Type::tbool->addMod (mod);
124
125 case INTEGER_TYPE:
126 {
127 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
128 bool unsignedp = TYPE_UNSIGNED (type);
129
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++)
133 {
134 dtype = Type::basic[i];
135
136 /* Search for type matching size and signedness. */
137 if (unsignedp != dtype->isunsigned ()
138 || size != dtype->size ())
139 continue;
140
141 return dtype->addMod (mod);
142 }
143 break;
144 }
145
146 case REAL_TYPE:
147 {
148 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
149
150 for (size_t i = Tfloat32; i <= Tfloat80; i++)
151 {
152 dtype = Type::basic[i];
153
154 /* Search for type matching size. */
155 if (dtype->size () != size)
156 continue;
157
158 return dtype->addMod (mod);
159 }
160 break;
161 }
162
163 case COMPLEX_TYPE:
164 {
165 unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
166 for (size_t i = Tcomplex32; i <= Tcomplex80; i++)
167 {
168 dtype = Type::basic[i];
169
170 /* Search for type matching size. */
171 if (dtype->size () != size)
172 continue;
173
174 return dtype->addMod (mod);
175 }
176 break;
177 }
178
179 case VOID_TYPE:
180 return Type::tvoid->addMod (mod);
181
182 case ARRAY_TYPE:
183 dtype = build_frontend_type (TREE_TYPE (type));
184 if (dtype)
185 {
186 tree index = TYPE_DOMAIN (type);
187 tree ub = TYPE_MAX_VALUE (index);
188 tree lb = TYPE_MIN_VALUE (index);
189
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));
193
194 dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
195 builtin_converted_decls.safe_push (builtin_data (dtype, type));
196 return dtype;
197 }
198 break;
199
200 case VECTOR_TYPE:
a1b68059
RS
201 {
202 unsigned HOST_WIDE_INT nunits;
203 if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits))
204 break;
205
b4c522fa 206 dtype = build_frontend_type (TREE_TYPE (type));
a1b68059
RS
207 if (!dtype)
208 break;
b4c522fa 209
a1b68059 210 dtype = dtype->sarrayOf (nunits)->addMod (mod);
f0a3bab4 211 if (target.isVectorTypeSupported (dtype->size (), dtype->nextOf ()))
a1b68059 212 break;
b4c522fa 213
98866120 214 dtype = (TypeVector::create (dtype))->addMod (mod);
a1b68059
RS
215 builtin_converted_decls.safe_push (builtin_data (dtype, type));
216 return dtype;
217 }
b4c522fa
IB
218
219 case RECORD_TYPE:
2ee3ea4b
IB
220 {
221 Identifier *ident = TYPE_IDENTIFIER (type) ?
222 Identifier::idPool (IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))) : NULL;
223
224 /* Neither the `object' and `gcc.builtins' modules will not exist when
cdbf48be 225 this is called. Use a stub `object' module parent in the meantime.
2ee3ea4b
IB
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);
230
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 ();
241
70f63204
IB
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;
2ee3ea4b
IB
245 sdecl->members = new Dsymbols;
246
247 for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
b4c522fa 248 {
2ee3ea4b
IB
249 Type *ftype = build_frontend_type (TREE_TYPE (field));
250 if (!ftype)
251 {
252 delete sdecl->members;
253 return NULL;
254 }
255
70f63204
IB
256 Identifier *fident;
257 if (DECL_NAME (field) == NULL_TREE)
258 fident = Identifier::generateId ("__pad", anonfield_id++);
259 else
260 {
261 const char *name = IDENTIFIER_POINTER (DECL_NAME (field));
262 fident = Identifier::idPool (name);
263 }
264
2ee3ea4b
IB
265 VarDeclaration *vd = VarDeclaration::create (Loc (), ftype, fident,
266 NULL);
2370bdbb 267 vd->parent = sdecl;
70f63204 268 vd->offset = tree_to_uhwi (byte_position (field));
2ee3ea4b
IB
269 vd->semanticRun = PASSsemanticdone;
270 vd->csym = field;
271 sdecl->members->push (vd);
272 sdecl->fields.push (vd);
b4c522fa 273 }
2ee3ea4b
IB
274
275 dtype = sdecl->type;
276 builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));
277 return dtype;
278 }
b4c522fa
IB
279
280 case FUNCTION_TYPE:
281 dtype = build_frontend_type (TREE_TYPE (type));
282 if (dtype)
283 {
284 tree parms = TYPE_ARG_TYPES (type);
c3a2ba10 285 VarArg varargs_p = VARARGvariadic;
b4c522fa
IB
286
287 Parameters *args = new Parameters;
288 args->reserve (list_length (parms));
289
290 /* Attempt to convert all parameter types. */
291 for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))
292 {
293 tree argtype = TREE_VALUE (parm);
294 if (argtype == void_type_node)
295 {
c3a2ba10 296 varargs_p = VARARGnone;
b4c522fa
IB
297 break;
298 }
299
300 StorageClass sc = STCundefined;
301 if (TREE_CODE (argtype) == REFERENCE_TYPE)
302 {
303 argtype = TREE_TYPE (argtype);
304 sc |= STCref;
305 }
306
307 Type *targ = build_frontend_type (argtype);
308 if (!targ)
309 {
310 delete args;
311 return NULL;
312 }
313
dddea6d4 314 args->push (Parameter::create (sc, targ, NULL, NULL, NULL));
b4c522fa
IB
315 }
316
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. */
c3a2ba10 319 if (args->length != 0 || varargs_p == VARARGnone)
b4c522fa
IB
320 {
321 dtype = TypeFunction::create (args, dtype, varargs_p, LINKc);
322 return dtype->addMod (mod);
323 }
324 }
325 break;
326
327 default:
328 break;
329 }
330
331 return NULL;
332}
333
334/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
ac78516b 335 LOC is the location in the source file where this CST is being evaluated.
b4c522fa
IB
336 This is used for getting the CTFE value out of a const-folded builtin,
337 returns NULL if it cannot convert CST. */
338
339Expression *
ac78516b 340d_eval_constant_expression (const Loc &loc, tree cst)
b4c522fa
IB
341{
342 STRIP_TYPE_NOPS (cst);
343 Type *type = build_frontend_type (TREE_TYPE (cst));
344
345 if (type)
346 {
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)
353 {
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));
ac78516b 357 return ComplexExp::create (loc, value, type);
b4c522fa
IB
358 }
359 else if (code == INTEGER_CST)
360 {
361 dinteger_t value = TREE_INT_CST_LOW (cst);
ac78516b 362 return IntegerExp::create (loc, value, type);
b4c522fa
IB
363 }
364 else if (code == REAL_CST)
365 {
366 real_value value = TREE_REAL_CST (cst);
ac78516b 367 return RealExp::create (loc, ldouble (value), type);
b4c522fa
IB
368 }
369 else if (code == STRING_CST)
370 {
371 const void *string = TREE_STRING_POINTER (cst);
372 size_t len = TREE_STRING_LENGTH (cst);
ac78516b 373 return StringExp::create (loc, CONST_CAST (void *, string), len);
b4c522fa
IB
374 }
375 else if (code == VECTOR_CST)
376 {
377 dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant ();
378 Expressions *elements = new Expressions;
379 elements->setDim (nunits);
380
381 for (size_t i = 0; i < nunits; i++)
382 {
383 Expression *elem
ac78516b 384 = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
b4c522fa
IB
385 if (elem == NULL)
386 return NULL;
387
388 (*elements)[i] = elem;
389 }
390
ac78516b 391 Expression *e = ArrayLiteralExp::create (loc, elements);
89fdaf5a 392 e->type = type->isTypeVector ()->basetype;
b4c522fa 393
ac78516b 394 return VectorExp::create (loc, e, type);
b4c522fa 395 }
c5e94699
IB
396 else if (code == ADDR_EXPR)
397 {
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);
402
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;
407
408 return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
409 }
b4c522fa
IB
410 }
411
412 return NULL;
413}
414
415/* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.
416 Adds IDENT to the list of predefined version identifiers. */
417
418void
419d_add_builtin_version (const char* ident)
420{
b4c522fa
IB
421 VersionCondition::addPredefinedGlobalIdent (ident);
422}
423
424/* Initialize the list of all the predefined version identifiers. */
425
426void
427d_init_versions (void)
428{
429 VersionCondition::addPredefinedGlobalIdent ("GNU");
430 VersionCondition::addPredefinedGlobalIdent ("D_Version2");
431
432 if (BYTES_BIG_ENDIAN)
433 VersionCondition::addPredefinedGlobalIdent ("BigEndian");
434 else
435 VersionCondition::addPredefinedGlobalIdent ("LittleEndian");
436
437 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
438 VersionCondition::addPredefinedGlobalIdent ("GNU_SjLj_Exceptions");
439 else if (targetm_common.except_unwind_info (&global_options) == UI_SEH)
440 VersionCondition::addPredefinedGlobalIdent ("GNU_SEH_Exceptions");
441 else if (targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
442 VersionCondition::addPredefinedGlobalIdent ("GNU_DWARF2_Exceptions");
443
444 if (!targetm.have_tls)
445 VersionCondition::addPredefinedGlobalIdent ("GNU_EMUTLS");
446
49686677
IB
447 if (STACK_GROWS_DOWNWARD)
448 VersionCondition::addPredefinedGlobalIdent ("GNU_StackGrowsDown");
b4c522fa
IB
449
450 /* Should define this anyway to set us apart from the competition. */
451 VersionCondition::addPredefinedGlobalIdent ("GNU_InlineAsm");
452
453 /* LP64 only means 64bit pointers in D. */
454 if (global.params.isLP64)
455 VersionCondition::addPredefinedGlobalIdent ("D_LP64");
456
457 /* Setting `global.params.cov' forces module info generation which is
458 not needed for the GCC coverage implementation. Instead, just
459 test flag_test_coverage while leaving `global.params.cov' unset. */
460 if (flag_test_coverage)
461 VersionCondition::addPredefinedGlobalIdent ("D_Coverage");
462 if (flag_pic)
463 VersionCondition::addPredefinedGlobalIdent ("D_PIC");
5a5d2301
IB
464 if (flag_pie)
465 VersionCondition::addPredefinedGlobalIdent ("D_PIE");
b4c522fa
IB
466
467 if (global.params.doDocComments)
468 VersionCondition::addPredefinedGlobalIdent ("D_Ddoc");
469
470 if (global.params.useUnitTests)
471 VersionCondition::addPredefinedGlobalIdent ("unittest");
472
0cdc55f5 473 if (global.params.useAssert == CHECKENABLEon)
b4c522fa
IB
474 VersionCondition::addPredefinedGlobalIdent ("assert");
475
0cdc55f5 476 if (global.params.useArrayBounds == CHECKENABLEoff)
b4c522fa
IB
477 VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");
478
c0aebc60
IB
479 if (global.params.betterC)
480 VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
481 else
482 {
483 VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
484 VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
485 VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
486 }
487
b4c522fa
IB
488 VersionCondition::addPredefinedGlobalIdent ("all");
489
490 /* Emit all target-specific version identifiers. */
491 targetdm.d_cpu_versions ();
492 targetdm.d_os_versions ();
9503d7b1
IB
493
494 VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
b4c522fa
IB
495}
496
497/* A helper for d_build_builtins_module. Return a new ALIAS for TYPE.
498 Analogous to `alias ALIAS = TYPE' in D code. */
499
500static AliasDeclaration *
501build_alias_declaration (const char *alias, Type *type)
502{
503 return AliasDeclaration::create (Loc (), Identifier::idPool (alias), type);
504}
505
506/* A helper function for Target::loadModule. Generates all code for the
507 `gcc.builtins' module, whose frontend symbol should be M. */
508
509void
510d_build_builtins_module (Module *m)
511{
512 Dsymbols *members = new Dsymbols;
513 tree decl;
514
515 for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i)
516 {
517 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
89fdaf5a
IB
518 Type *t = build_frontend_type (TREE_TYPE (decl));
519 TypeFunction *tf = t ? t->isTypeFunction () : NULL;
b4c522fa
IB
520
521 /* Cannot create built-in function type for DECL. */
522 if (!tf)
523 continue;
524
525 /* A few notes on D2 attributes applied to builtin functions:
526 - It is assumed that built-ins solely provided by the compiler are
527 considered @safe and pure.
528 - Built-ins that correspond to `extern(C)' functions in the standard
529 library that have `__attribute__(nothrow)' are considered `@trusted'.
530 - The purity of a built-in can vary depending on compiler flags set
531 upon initialization, or by the `-foptions' passed, such as
532 flag_unsafe_math_optimizations.
533 - Built-ins never use the GC or raise a D exception, and so are always
534 marked as `nothrow' and `@nogc'. */
535 tf->purity = DECL_PURE_P (decl) ? PUREstrong
536 : TREE_READONLY (decl) ? PUREconst
537 : DECL_IS_NOVOPS (decl) ? PUREweak
538 : !DECL_ASSEMBLER_NAME_SET_P (decl) ? PUREweak
539 : PUREimpure;
540 tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUSTsafe
541 : TREE_NOTHROW (decl) ? TRUSTtrusted
542 : TRUSTsystem;
543 tf->isnothrow = true;
544 tf->isnogc = true;
545
546 FuncDeclaration *func
547 = FuncDeclaration::create (Loc (), Loc (),
548 Identifier::idPool (name),
549 STCextern, tf);
550 DECL_LANG_SPECIFIC (decl) = build_lang_decl (func);
551 func->csym = decl;
c1d56e6a 552 func->builtin = BUILTINgcc;
b4c522fa
IB
553
554 members->push (func);
555 }
556
557 for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i)
558 {
559 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
560 Type *t = build_frontend_type (TREE_TYPE (decl));
561
562 /* Cannot create built-in type for DECL. */
563 if (!t)
564 continue;
565
566 members->push (build_alias_declaration (name, t));
567 }
568
569 /* Iterate through the target-specific builtin types for va_list. */
570 if (targetm.enum_va_list_p)
571 {
572 const char *name;
573 tree type;
574
575 for (int i = 0; targetm.enum_va_list_p (i, &name, &type); ++i)
576 {
577 Type *t = build_frontend_type (type);
578 /* Cannot create built-in type. */
579 if (!t)
580 continue;
581
582 members->push (build_alias_declaration (name, t));
583 }
584 }
585
586 /* Push out declarations for any RECORD_TYPE types encountered when building
587 all builtin functions and types. */
588 for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
589 {
590 /* Currently, there is no need to run semantic, but we do want to output
591 initializers, typeinfo, and others on demand. */
592 Dsymbol *dsym = builtin_converted_decls[i].dsym;
2ee3ea4b 593 if (dsym != NULL && !dsym->isAnonymous ())
b4c522fa
IB
594 {
595 dsym->parent = m;
596 members->push (dsym);
597 }
598 }
599
5905cbdb
IB
600 /* Expose target-specific va_list type. */
601 Type *tvalist = target.va_listType (Loc (), NULL);
89fdaf5a
IB
602 TypeStruct *ts = tvalist->isTypeStruct ();
603 if (ts == NULL || !ts->sym->isAnonymous ())
5905cbdb 604 members->push (build_alias_declaration ("__builtin_va_list", tvalist));
2ee3ea4b
IB
605 else
606 {
89fdaf5a
IB
607 ts->sym->ident = Identifier::idPool ("__builtin_va_list");
608 members->push (ts->sym);
2ee3ea4b 609 }
b4c522fa
IB
610
611 /* Expose target-specific integer types to the builtins module. */
612 {
613 Type *t = build_frontend_type (long_integer_type_node);
614 members->push (build_alias_declaration ("__builtin_clong", t));
615
616 t = build_frontend_type (long_unsigned_type_node);
617 members->push (build_alias_declaration ("__builtin_culong", t));
618
619 t = build_frontend_type (long_long_integer_type_node);
620 members->push (build_alias_declaration ("__builtin_clonglong", t));
621
622 t = build_frontend_type (long_long_unsigned_type_node);
623 members->push (build_alias_declaration ("__builtin_culonglong", t));
624
625 t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 0));
626 members->push (build_alias_declaration ("__builtin_machine_byte", t));
627
628 t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 1));
629 members->push (build_alias_declaration ("__builtin_machine_ubyte", t));
630
631 t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 0));
632 members->push (build_alias_declaration ("__builtin_machine_int", t));
633
634 t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 1));
635 members->push (build_alias_declaration ("__builtin_machine_uint", t));
636
637 t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 0));
638 members->push (build_alias_declaration ("__builtin_pointer_int", t));
639
640 t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 1));
641 members->push (build_alias_declaration ("__builtin_pointer_uint", t));
642
643 /* _Unwind_Word has its own target specific mode. */
644 machine_mode mode = targetm.unwind_word_mode ();
645 t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 0));
646 members->push (build_alias_declaration ("__builtin_unwind_int", t));
647
648 t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 1));
649 members->push (build_alias_declaration ("__builtin_unwind_uint", t));
650 }
651
652 m->members->push (LinkDeclaration::create (LINKc, members));
653}
654
655/* Search for any `extern(C)' functions that match any known GCC library builtin
656 function in D and override its internal back-end symbol. */
657
658static void
659maybe_set_builtin_1 (Dsymbol *d)
660{
661 AttribDeclaration *ad = d->isAttribDeclaration ();
662 FuncDeclaration *fd = d->isFuncDeclaration ();
663
664 if (ad != NULL)
665 {
666 /* Recursively search through attribute decls. */
d3da83f6 667 Dsymbols *decls = ad->include (NULL);
2cbc99d1 668 if (decls && decls->length)
b4c522fa 669 {
2cbc99d1 670 for (size_t i = 0; i < decls->length; i++)
b4c522fa
IB
671 {
672 Dsymbol *sym = (*decls)[i];
673 maybe_set_builtin_1 (sym);
674 }
675 }
676 }
677 else if (fd && !fd->fbody)
678 {
679 tree t;
680
681 for (size_t i = 0; vec_safe_iterate (gcc_builtins_libfuncs, i, &t); ++i)
682 {
683 gcc_assert (DECL_ASSEMBLER_NAME_SET_P (t));
684
685 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
686 if (fd->ident != Identifier::idPool (name))
687 continue;
688
689 /* Found a match, tell the frontend this is a builtin. */
690 DECL_LANG_SPECIFIC (t) = build_lang_decl (fd);
691 fd->csym = t;
c1d56e6a 692 fd->builtin = BUILTINgcc;
b4c522fa
IB
693 return;
694 }
695 }
696}
697
698/* A helper function for Target::loadModule. Traverse all members in module M
699 to search for any functions that can be mapped to any GCC builtin. */
700
701void
702d_maybe_set_builtin (Module *m)
703{
704 if (!m || !m->members)
705 return;
706
2cbc99d1 707 for (size_t i = 0; i < m->members->length; i++)
b4c522fa
IB
708 {
709 Dsymbol *sym = (*m->members)[i];
710 maybe_set_builtin_1 (sym);
711 }
712}
713
714/* Used to help initialize the builtin-types.def table. When a type of
715 the correct size doesn't exist, use error_mark_node instead of NULL.
716 The latter results in segfaults even when a decl using the type doesn't
717 get invoked. */
718
719static tree
720builtin_type_for_size (int size, bool unsignedp)
721{
722 tree type = lang_hooks.types.type_for_size (size, unsignedp);
723 return type ? type : error_mark_node;
724}
725
726/* Support for DEF_BUILTIN. */
727
728static void
729do_build_builtin_fn (built_in_function fncode,
730 const char *name,
731 built_in_class fnclass,
732 tree fntype, bool both_p, bool fallback_p,
733 tree fnattrs, bool implicit_p)
734{
735 tree decl;
736 const char *libname;
737
738 if (fntype == error_mark_node)
739 return;
740
741 gcc_assert ((!both_p && !fallback_p)
6ba3079d 742 || startswith (name, "__builtin_"));
b4c522fa
IB
743
744 libname = name + strlen ("__builtin_");
745
746 decl = add_builtin_function (name, fntype, fncode, fnclass,
747 fallback_p ? libname : NULL, fnattrs);
748
749 set_builtin_decl (fncode, decl, implicit_p);
750}
751
752/* Standard data types to be used in builtin argument declarations. */
753
754static GTY(()) tree string_type_node;
755static GTY(()) tree const_string_type_node;
756static GTY(()) tree wint_type_node;
757static GTY(()) tree intmax_type_node;
758static GTY(()) tree uintmax_type_node;
759static GTY(()) tree signed_size_type_node;
760
761
762/* Build nodes that would have been created by the C front-end; necessary
763 for including builtin-types.def and ultimately builtins.def. */
764
765static void
766d_build_c_type_nodes (void)
767{
768 void_list_node = build_tree_list (NULL_TREE, void_type_node);
769 string_type_node = build_pointer_type (char_type_node);
770 const_string_type_node
771 = build_pointer_type (build_qualified_type (char_type_node,
772 TYPE_QUAL_CONST));
773
7610ae80 774 if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
b4c522fa
IB
775 {
776 intmax_type_node = integer_type_node;
777 uintmax_type_node = unsigned_type_node;
b4c522fa 778 }
7610ae80 779 else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
b4c522fa
IB
780 {
781 intmax_type_node = long_integer_type_node;
782 uintmax_type_node = long_unsigned_type_node;
b4c522fa 783 }
7610ae80 784 else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
b4c522fa
IB
785 {
786 intmax_type_node = long_long_integer_type_node;
787 uintmax_type_node = long_long_unsigned_type_node;
b4c522fa
IB
788 }
789 else
790 gcc_unreachable ();
791
7610ae80 792 signed_size_type_node = signed_type_for (size_type_node);
b4c522fa
IB
793 wint_type_node = unsigned_type_node;
794 pid_type_node = integer_type_node;
795}
796
797/* Build nodes that are used by the D front-end.
798 These are distinct from C types. */
799
800static void
801d_build_d_type_nodes (void)
802{
803 /* Integral types. */
804 d_byte_type = make_signed_type (8);
805 d_ubyte_type = make_unsigned_type (8);
806
807 d_short_type = make_signed_type (16);
808 d_ushort_type = make_unsigned_type (16);
809
810 d_int_type = make_signed_type (32);
811 d_uint_type = make_unsigned_type (32);
812
813 d_long_type = make_signed_type (64);
814 d_ulong_type = make_unsigned_type (64);
815
816 d_cent_type = make_signed_type (128);
817 d_ucent_type = make_unsigned_type (128);
818
819 {
820 /* Re-define size_t as a D type. */
821 machine_mode type_mode = TYPE_MODE (size_type_node);
822 size_type_node = lang_hooks.types.type_for_mode (type_mode, 1);
823 }
824
825 /* Bool and Character types. */
826 d_bool_type = make_unsigned_type (1);
827 TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);
828
829 char8_type_node = make_unsigned_type (8);
830 TYPE_STRING_FLAG (char8_type_node) = 1;
831
832 char16_type_node = make_unsigned_type (16);
833 TYPE_STRING_FLAG (char16_type_node) = 1;
834
835 char32_type_node = make_unsigned_type (32);
836 TYPE_STRING_FLAG (char32_type_node) = 1;
837
838 /* Imaginary types. */
839 ifloat_type_node = build_distinct_type_copy (float_type_node);
840 TYPE_IMAGINARY_FLOAT (ifloat_type_node) = 1;
841
842 idouble_type_node = build_distinct_type_copy (double_type_node);
843 TYPE_IMAGINARY_FLOAT (idouble_type_node) = 1;
844
845 ireal_type_node = build_distinct_type_copy (long_double_type_node);
846 TYPE_IMAGINARY_FLOAT (ireal_type_node) = 1;
847
e4011c13
IB
848 /* Calling build_ctype() links the front-end Type to the GCC node,
849 and sets the TYPE_NAME to the D language type. */
850 for (unsigned ty = 0; ty < TMAX; ty++)
851 {
852 if (Type::basic[ty] != NULL)
853 build_ctype (Type::basic[ty]);
854 }
855
b4c522fa
IB
856 /* Used for ModuleInfo, ClassInfo, and Interface decls. */
857 unknown_type_node = make_node (RECORD_TYPE);
858
859 /* Make sure we get a unique function type, so we can give
860 its pointer type a name. (This wins for gdb). */
861 {
862 tree vfunc_type = make_node (FUNCTION_TYPE);
863 TREE_TYPE (vfunc_type) = d_int_type;
864 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
865 layout_type (vfunc_type);
866
867 vtable_entry_type = build_pointer_type (vfunc_type);
868 }
869
870 vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
871 layout_type (vtbl_ptr_type_node);
872
873 /* When an object is accessed via an interface, this type appears
874 as the first entry in its vtable. */
875 {
876 tree domain = build_index_type (size_int (3));
877 vtbl_interface_type_node = build_array_type (ptr_type_node, domain);
878 }
879
880 /* Use `void[]' as a generic dynamic array type. */
881 array_type_node = make_struct_type ("__builtin_void[]", 2,
882 get_identifier ("length"), size_type_node,
883 get_identifier ("ptr"), ptr_type_node);
884 TYPE_DYNAMIC_ARRAY (array_type_node) = 1;
885
886 null_array_node = d_array_value (array_type_node, size_zero_node,
887 null_pointer_node);
888}
889
890/* Handle default attributes. */
891
892enum built_in_attribute
893{
894#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
895#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
896#define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
897#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
898#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
899#include "builtin-attrs.def"
900#undef DEF_ATTR_NULL_TREE
901#undef DEF_ATTR_INT
902#undef DEF_ATTR_STRING
903#undef DEF_ATTR_IDENT
904#undef DEF_ATTR_TREE_LIST
905 ATTR_LAST
906};
907
908static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
909
910/* Initialize the attribute table for all the supported builtins. */
911
912static void
913d_init_attributes (void)
914{
915 /* Fill in the built_in_attributes array. */
916#define DEF_ATTR_NULL_TREE(ENUM) \
917 built_in_attributes[(int) ENUM] = NULL_TREE;
918# define DEF_ATTR_INT(ENUM, VALUE) \
919 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
920#define DEF_ATTR_STRING(ENUM, VALUE) \
921 built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
922#define DEF_ATTR_IDENT(ENUM, STRING) \
923 built_in_attributes[(int) ENUM] = get_identifier (STRING);
924#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
925 built_in_attributes[(int) ENUM] \
926 = tree_cons (built_in_attributes[(int) PURPOSE], \
927 built_in_attributes[(int) VALUE], \
928 built_in_attributes[(int) CHAIN]);
929#include "builtin-attrs.def"
930#undef DEF_ATTR_NULL_TREE
931#undef DEF_ATTR_INT
932#undef DEF_ATTR_STRING
933#undef DEF_ATTR_IDENT
934#undef DEF_ATTR_TREE_LIST
935}
936
937/* Builtin types. */
938
939enum d_builtin_type
940{
941#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
942#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
943#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
944#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
945#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
946#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
947#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
948#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
949 ARG6) NAME,
950#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
951 ARG6, ARG7) NAME,
952#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
953 ARG6, ARG7, ARG8) NAME,
954#define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
955 ARG6, ARG7, ARG8, ARG9) NAME,
956#define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
957 ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
958#define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
959 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
960#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
961#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
962#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
963#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
964#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
965#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
966 NAME,
967#define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
968 ARG6) NAME,
969#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
970 ARG6, ARG7) NAME,
971#define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
972 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
973#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
974#include "builtin-types.def"
975#undef DEF_PRIMITIVE_TYPE
976#undef DEF_FUNCTION_TYPE_0
977#undef DEF_FUNCTION_TYPE_1
978#undef DEF_FUNCTION_TYPE_2
979#undef DEF_FUNCTION_TYPE_3
980#undef DEF_FUNCTION_TYPE_4
981#undef DEF_FUNCTION_TYPE_5
982#undef DEF_FUNCTION_TYPE_6
983#undef DEF_FUNCTION_TYPE_7
984#undef DEF_FUNCTION_TYPE_8
985#undef DEF_FUNCTION_TYPE_9
986#undef DEF_FUNCTION_TYPE_10
987#undef DEF_FUNCTION_TYPE_11
988#undef DEF_FUNCTION_TYPE_VAR_0
989#undef DEF_FUNCTION_TYPE_VAR_1
990#undef DEF_FUNCTION_TYPE_VAR_2
991#undef DEF_FUNCTION_TYPE_VAR_3
992#undef DEF_FUNCTION_TYPE_VAR_4
993#undef DEF_FUNCTION_TYPE_VAR_5
994#undef DEF_FUNCTION_TYPE_VAR_6
995#undef DEF_FUNCTION_TYPE_VAR_7
996#undef DEF_FUNCTION_TYPE_VAR_11
997#undef DEF_POINTER_TYPE
998 BT_LAST
999};
1000
1001typedef enum d_builtin_type builtin_type;
1002
1003/* A temporary array used in communication with def_fn_type. */
1004static GTY(()) tree builtin_types[(int) BT_LAST + 1];
1005
1006/* A helper function for d_init_builtins. Build function type for DEF with
1007 return type RET and N arguments. If VAR is true, then the function should
1008 be variadic after those N arguments.
1009
1010 Takes special care not to ICE if any of the types involved are
1011 error_mark_node, which indicates that said type is not in fact available
1012 (see builtin_type_for_size). In which case the function type as a whole
1013 should be error_mark_node. */
1014
1015static void
1016def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
1017{
1018 tree t;
1019 tree *args = XALLOCAVEC (tree, n);
1020 va_list list;
1021 int i;
1022
1023 va_start (list, n);
1024 for (i = 0; i < n; ++i)
1025 {
1026 builtin_type a = (builtin_type) va_arg (list, int);
1027 t = builtin_types[a];
1028 if (t == error_mark_node)
1029 goto egress;
1030 args[i] = t;
1031 }
1032
1033 t = builtin_types[ret];
1034 if (t == error_mark_node)
1035 goto egress;
1036 if (var)
1037 t = build_varargs_function_type_array (t, n, args);
1038 else
1039 t = build_function_type_array (t, n, args);
1040
1041 egress:
1042 builtin_types[def] = t;
1043 va_end (list);
1044}
1045
1046/* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
1047 VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
1048
1049static void
1050d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
1051 tree va_list_arg_type_node ATTRIBUTE_UNUSED)
1052{
1053#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
1054 builtin_types[(int) ENUM] = VALUE;
1055#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
1056 def_fn_type (ENUM, RETURN, 0, 0);
1057#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
1058 def_fn_type (ENUM, RETURN, 0, 1, ARG1);
1059#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
1060 def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
1061#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1062 def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
1063#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1064 def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
1065#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1066 def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1067#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1068 ARG6) \
1069 def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1070#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1071 ARG6, ARG7) \
1072 def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1073#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1074 ARG6, ARG7, ARG8) \
1075 def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1076 ARG7, ARG8);
1077#define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1078 ARG6, ARG7, ARG8, ARG9) \
1079 def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1080 ARG7, ARG8, ARG9);
1081#define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1082 ARG6, ARG7, ARG8, ARG9, ARG10) \
1083 def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1084 ARG7, ARG8, ARG9, ARG10);
1085#define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1086 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1087 def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1088 ARG7, ARG8, ARG9, ARG10, ARG11);
1089#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
1090 def_fn_type (ENUM, RETURN, 1, 0);
1091#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
1092 def_fn_type (ENUM, RETURN, 1, 1, ARG1);
1093#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
1094 def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
1095#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1096 def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
1097#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1098 def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
1099#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1100 def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1101#define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1102 ARG6) \
1103 def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1104#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1105 ARG6, ARG7) \
1106 def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1107#define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1108 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1109 def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1110 ARG7, ARG8, ARG9, ARG10, ARG11);
1111#define DEF_POINTER_TYPE(ENUM, TYPE) \
1112 builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
1113
1114#include "builtin-types.def"
1115
1116#undef DEF_PRIMITIVE_TYPE
1117#undef DEF_FUNCTION_TYPE_1
1118#undef DEF_FUNCTION_TYPE_2
1119#undef DEF_FUNCTION_TYPE_3
1120#undef DEF_FUNCTION_TYPE_4
1121#undef DEF_FUNCTION_TYPE_5
1122#undef DEF_FUNCTION_TYPE_6
1123#undef DEF_FUNCTION_TYPE_7
1124#undef DEF_FUNCTION_TYPE_8
1125#undef DEF_FUNCTION_TYPE_9
1126#undef DEF_FUNCTION_TYPE_10
1127#undef DEF_FUNCTION_TYPE_11
1128#undef DEF_FUNCTION_TYPE_VAR_0
1129#undef DEF_FUNCTION_TYPE_VAR_1
1130#undef DEF_FUNCTION_TYPE_VAR_2
1131#undef DEF_FUNCTION_TYPE_VAR_3
1132#undef DEF_FUNCTION_TYPE_VAR_4
1133#undef DEF_FUNCTION_TYPE_VAR_5
1134#undef DEF_FUNCTION_TYPE_VAR_6
1135#undef DEF_FUNCTION_TYPE_VAR_7
1136#undef DEF_FUNCTION_TYPE_VAR_11
1137#undef DEF_POINTER_TYPE
1138 builtin_types[(int) BT_LAST] = NULL_TREE;
1139
1140 d_init_attributes ();
1141
1142#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
1143 NONANSI_P, ATTRS, IMPLICIT, COND) \
1144 if (NAME && COND) \
1145 do_build_builtin_fn (ENUM, NAME, CLASS, \
1146 builtin_types[(int) TYPE], \
1147 BOTH_P, FALLBACK_P, \
1148 built_in_attributes[(int) ATTRS], IMPLICIT);
1149#include "builtins.def"
1150#undef DEF_BUILTIN
1151}
1152
1153/* Build builtin functions and types for the D language frontend. */
1154
1155void
1156d_init_builtins (void)
1157{
b4c522fa
IB
1158 d_build_c_type_nodes ();
1159 d_build_d_type_nodes ();
1160
1161 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
1162 {
1163 /* It might seem natural to make the argument type a pointer, but there
1164 is no implicit casting from arrays to pointers in D. */
1165 d_define_builtins (va_list_type_node, va_list_type_node);
1166 }
1167 else
1168 {
1169 d_define_builtins (build_reference_type (va_list_type_node),
1170 va_list_type_node);
1171 }
1172
1173 targetm.init_builtins ();
1174 build_common_builtin_nodes ();
1175}
1176
1177/* Registration of machine- or os-specific builtin types.
1178 Add to builtin types list for maybe processing later
1179 if `gcc.builtins' was imported into the current module. */
1180
1181void
1182d_register_builtin_type (tree type, const char *name)
1183{
1184 tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
1185 get_identifier (name), type);
1186 DECL_ARTIFICIAL (decl) = 1;
1187
1188 if (!TYPE_NAME (type))
1189 TYPE_NAME (type) = decl;
1190
1191 vec_safe_push (gcc_builtins_types, decl);
1192}
1193
1194/* Add DECL to builtin functions list for maybe processing later
1195 if `gcc.builtins' was imported into the current module. */
1196
1197tree
1198d_builtin_function (tree decl)
1199{
1200 if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))
1201 vec_safe_push (gcc_builtins_libfuncs, decl);
1202
1203 vec_safe_push (gcc_builtins_functions, decl);
1204 return decl;
1205}
1206
b2f6e1de
IB
1207/* Same as d_builtin_function, but used to delay putting in back-end builtin
1208 functions until the ISA that defines the builtin has been declared.
1209 However in D, there is no global namespace. All builtins get pushed into the
1210 `gcc.builtins' module, which is constructed during the semantic analysis
1211 pass, which has already finished by the time target attributes are evaluated.
1212 So builtins are not pushed because they would be ultimately ignored.
1213 The purpose of having this function then is to improve compile-time
1214 reflection support to allow user-code to determine whether a given back end
1215 function is enabled by the ISA. */
1216
1217tree
1218d_builtin_function_ext_scope (tree decl)
1219{
1220 return decl;
1221}
b4c522fa
IB
1222
1223#include "gt-d-d-builtins.h"