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