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