1 /* d-builtins.cc -- GCC builtins support for D.
2 Copyright (C) 2006-2023 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
20 #include "coretypes.h"
22 #include "dmd/attrib.h"
23 #include "dmd/aggregate.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"
33 #include "fold-const.h"
34 #include "diagnostic.h"
35 #include "langhooks.h"
37 #include "common/common-target.h"
38 #include "stringpool.h"
39 #include "stor-layout.h"
43 #include "d-frontend.h"
47 static GTY(()) vec
<tree
, va_gc
> *gcc_builtins_functions
= NULL
;
48 static GTY(()) vec
<tree
, va_gc
> *gcc_builtins_types
= NULL
;
50 /* Record built-in types and their associated decls for re-use when
51 generating the `gcc.builtins' module. */
59 builtin_data (Type
*t
, tree c
, Dsymbol
*d
= NULL
)
60 : dtype(t
), ctype(c
), dsym(d
)
64 static vec
<builtin_data
> builtin_converted_decls
;
66 /* Build D frontend type from tree TYPE type given. This will set the
67 back-end type symbol directly for complex types to save build_ctype()
68 the work. For other types, it is not useful or will cause errors, such
69 as casting from `C char' to `D char', which also means that `char *`
70 needs to be specially handled. */
73 build_frontend_type (tree type
)
78 if (TYPE_READONLY (type
))
80 if (TYPE_VOLATILE (type
))
83 /* If we've seen the type before, re-use the converted decl. */
84 unsigned saved_builtin_decls_length
= builtin_converted_decls
.length ();
85 for (size_t i
= 0; i
< saved_builtin_decls_length
; ++i
)
87 tree t
= builtin_converted_decls
[i
].ctype
;
88 if (TYPE_MAIN_VARIANT (t
) == TYPE_MAIN_VARIANT (type
))
89 return builtin_converted_decls
[i
].dtype
;
92 switch (TREE_CODE (type
))
95 dtype
= build_frontend_type (TREE_TYPE (type
));
98 /* Check for char * first. Needs to be done for chars/string. */
99 if (TYPE_MAIN_VARIANT (TREE_TYPE (type
)) == char_type_node
)
100 return Type::tchar
->addMod (dtype
->mod
)->pointerTo ()->addMod (mod
);
102 if (dtype
->ty
== TY::Tfunction
)
103 return (TypePointer::create (dtype
))->addMod (mod
);
105 return dtype
->pointerTo ()->addMod (mod
);
110 dtype
= build_frontend_type (TREE_TYPE (type
));
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
);
118 builtin_converted_decls
.safe_push (builtin_data (dtype
, type
));
124 /* Should be no need for size checking. */
125 return Type::tbool
->addMod (mod
);
129 unsigned size
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
));
130 bool unsignedp
= TYPE_UNSIGNED (type
);
132 /* For now, skip support for cent/ucent until the frontend
133 has better support for handling it. */
134 for (size_t i
= (size_t) TY::Tint8
; i
<= (size_t) TY::Tuns64
; i
++)
136 dtype
= Type::basic
[i
];
138 /* Search for type matching size and signedness. */
139 if (unsignedp
!= dtype
->isunsigned ()
140 || size
!= dtype
->size ())
143 return dtype
->addMod (mod
);
150 unsigned size
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type
));
152 for (size_t i
= (size_t) TY::Tfloat32
; i
<= (size_t) TY::Tfloat80
; i
++)
154 dtype
= Type::basic
[i
];
156 /* Search for type matching size. */
157 if (dtype
->size () != size
)
160 return dtype
->addMod (mod
);
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
;
171 dtype
= Type::basic
[i
];
173 /* Search for type matching size. */
174 if (dtype
->size () != size
)
177 return dtype
->addMod (mod
);
183 return Type::tvoid
->addMod (mod
);
186 dtype
= build_frontend_type (TREE_TYPE (type
));
189 tree index
= TYPE_DOMAIN (type
);
190 tree ub
= TYPE_MAX_VALUE (index
);
191 tree lb
= TYPE_MIN_VALUE (index
);
193 tree length
= fold_build2 (MINUS_EXPR
, TREE_TYPE (lb
), ub
, lb
);
194 length
= size_binop (PLUS_EXPR
, size_one_node
,
195 convert (sizetype
, length
));
197 dtype
= dtype
->sarrayOf (TREE_INT_CST_LOW (length
))->addMod (mod
);
198 builtin_converted_decls
.safe_push (builtin_data (dtype
, type
));
205 unsigned HOST_WIDE_INT nunits
;
206 if (!TYPE_VECTOR_SUBPARTS (type
).is_constant (&nunits
))
209 dtype
= build_frontend_type (TREE_TYPE (type
));
213 dtype
= dtype
->sarrayOf (nunits
)->addMod (mod
);
214 if (target
.isVectorTypeSupported (dtype
->size (), dtype
->nextOf ()))
217 dtype
= (TypeVector::create (dtype
))->addMod (mod
);
218 builtin_converted_decls
.safe_push (builtin_data (dtype
, type
));
224 Identifier
*ident
= TYPE_IDENTIFIER (type
) ?
225 Identifier::idPool (IDENTIFIER_POINTER (TYPE_IDENTIFIER (type
))) : NULL
;
227 /* Neither the `object' and `gcc.builtins' modules will not exist when
228 this is called. Use a stub `object' module parent in the meantime.
229 If `gcc.builtins' is later imported, the parent will be overridden
230 with the correct module symbol. */
231 static Identifier
*object
= Identifier::idPool ("object");
232 static Module
*stubmod
= Module::create ("object.d", object
, 0, 0);
234 StructDeclaration
*sdecl
= StructDeclaration::create (Loc (), ident
,
236 sdecl
->parent
= stubmod
;
237 sdecl
->structsize
= int_size_in_bytes (type
);
238 sdecl
->alignsize
= TYPE_ALIGN_UNIT (type
);
239 sdecl
->alignment
.setDefault ();
240 sdecl
->sizeok
= Sizeok::done
;
241 sdecl
->type
= (TypeStruct::create (sdecl
))->addMod (mod
);
242 sdecl
->type
->ctype
= type
;
243 sdecl
->type
->merge2 ();
245 /* Add both named and anonymous fields as members of the struct.
246 Anonymous fields still need a name in D, so call them "__pad%u". */
247 unsigned anonfield_id
= 0;
248 sdecl
->members
= d_gc_malloc
<Dsymbols
> ();
250 for (tree field
= TYPE_FIELDS (type
); field
; field
= DECL_CHAIN (field
))
252 Type
*ftype
= build_frontend_type (TREE_TYPE (field
));
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
);
262 if (DECL_NAME (field
) == NULL_TREE
)
265 snprintf (name
, sizeof (name
), "__pad%u", anonfield_id
++);
266 fident
= Identifier::idPool (name
);
270 const char *name
= IDENTIFIER_POINTER (DECL_NAME (field
));
271 fident
= Identifier::idPool (name
);
274 VarDeclaration
*vd
= VarDeclaration::create (Loc (), ftype
, fident
,
277 vd
->offset
= tree_to_uhwi (byte_position (field
));
278 vd
->semanticRun
= PASS::semanticdone
;
280 sdecl
->members
->push (vd
);
281 sdecl
->fields
.push (vd
);
285 builtin_converted_decls
.safe_push (builtin_data (dtype
, type
, sdecl
));
290 dtype
= build_frontend_type (TREE_TYPE (type
));
293 tree parms
= TYPE_ARG_TYPES (type
);
294 VarArg varargs_p
= VARARGvariadic
;
296 Parameters
*args
= d_gc_malloc
<Parameters
> ();
297 args
->reserve (list_length (parms
));
299 /* Attempt to convert all parameter types. */
300 for (tree parm
= parms
; parm
!= NULL_TREE
; parm
= TREE_CHAIN (parm
))
302 tree argtype
= TREE_VALUE (parm
);
303 if (argtype
== void_type_node
)
305 varargs_p
= VARARGnone
;
309 StorageClass sc
= STCundefined
;
310 if (TREE_CODE (argtype
) == REFERENCE_TYPE
)
312 argtype
= TREE_TYPE (argtype
);
316 Type
*targ
= build_frontend_type (argtype
);
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
);
325 args
->push (Parameter::create (sc
, targ
, NULL
, NULL
, NULL
));
328 /* GCC generic and placeholder built-ins are marked as variadic, yet
329 have no named parameters, and so can't be represented in D. */
330 if (args
->length
!= 0 || varargs_p
== VARARGnone
)
332 dtype
= TypeFunction::create (args
, dtype
, varargs_p
, LINK::c
);
333 return dtype
->addMod (mod
);
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. */
351 d_eval_constant_expression (const Loc
&loc
, tree cst
)
353 STRIP_TYPE_NOPS (cst
);
354 Type
*type
= build_frontend_type (TREE_TYPE (cst
));
358 /* Convert our GCC CST tree into a D Expression. This seems like we are
359 trying too hard, as these will only be converted back to a tree again
360 later in the codegen pass, but satisfies the need to have GCC built-ins
361 CTFE-able in the frontend. */
362 tree_code code
= TREE_CODE (cst
);
363 if (code
== COMPLEX_CST
)
365 real_value re
= TREE_REAL_CST (TREE_REALPART (cst
));
366 real_value im
= TREE_REAL_CST (TREE_IMAGPART (cst
));
367 complex_t value
= complex_t (ldouble (re
), ldouble (im
));
368 return ComplexExp::create (loc
, value
, type
);
370 else if (code
== INTEGER_CST
)
372 dinteger_t value
= TREE_INT_CST_LOW (cst
);
373 return IntegerExp::create (loc
, value
, type
);
375 else if (code
== REAL_CST
)
377 real_value value
= TREE_REAL_CST (cst
);
378 return RealExp::create (loc
, ldouble (value
), type
);
380 else if (code
== STRING_CST
)
382 const void *string
= TREE_STRING_POINTER (cst
);
383 size_t len
= TREE_STRING_LENGTH (cst
) - 1;
384 return StringExp::create (loc
, CONST_CAST (void *, string
), len
);
386 else if (code
== VECTOR_CST
)
388 dinteger_t nunits
= VECTOR_CST_NELTS (cst
).to_constant ();
389 Expressions
*elements
= d_gc_malloc
<Expressions
> ();
390 elements
->setDim (nunits
);
392 for (size_t i
= 0; i
< nunits
; i
++)
395 = d_eval_constant_expression (loc
, VECTOR_CST_ELT (cst
, i
));
399 (*elements
)[i
] = elem
;
402 Expression
*e
= ArrayLiteralExp::create (loc
, elements
);
403 e
->type
= type
->isTypeVector ()->basetype
;
405 return VectorExp::create (loc
, e
, type
);
407 else if (code
== ADDR_EXPR
)
409 /* Special handling for trees constructed by build_string_literal.
410 What we receive is an `&"string"[0]' expression, strip off the
411 outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
412 tree pointee
= TREE_OPERAND (cst
, 0);
414 if (TREE_CODE (pointee
) != ARRAY_REF
415 || TREE_OPERAND (pointee
, 1) != integer_zero_node
416 || TREE_CODE (TREE_OPERAND (pointee
, 0)) != STRING_CST
)
419 return d_eval_constant_expression (loc
, TREE_OPERAND (pointee
, 0));
426 /* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.
427 Adds IDENT to the list of predefined version identifiers. */
430 d_add_builtin_version (const char* ident
)
432 VersionCondition::addPredefinedGlobalIdent (ident
);
435 /* Initialize the list of all the predefined version identifiers. */
438 d_init_versions (void)
440 VersionCondition::addPredefinedGlobalIdent ("GNU");
441 VersionCondition::addPredefinedGlobalIdent ("D_Version2");
443 if (BYTES_BIG_ENDIAN
)
444 VersionCondition::addPredefinedGlobalIdent ("BigEndian");
446 VersionCondition::addPredefinedGlobalIdent ("LittleEndian");
448 if (targetm_common
.except_unwind_info (&global_options
) == UI_SJLJ
)
449 VersionCondition::addPredefinedGlobalIdent ("GNU_SjLj_Exceptions");
450 else if (targetm_common
.except_unwind_info (&global_options
) == UI_SEH
)
451 VersionCondition::addPredefinedGlobalIdent ("GNU_SEH_Exceptions");
452 else if (targetm_common
.except_unwind_info (&global_options
) == UI_DWARF2
)
453 VersionCondition::addPredefinedGlobalIdent ("GNU_DWARF2_Exceptions");
455 if (!targetm
.have_tls
)
456 VersionCondition::addPredefinedGlobalIdent ("GNU_EMUTLS");
458 if (STACK_GROWS_DOWNWARD
)
459 VersionCondition::addPredefinedGlobalIdent ("GNU_StackGrowsDown");
461 /* Should define this anyway to set us apart from the competition. */
462 VersionCondition::addPredefinedGlobalIdent ("GNU_InlineAsm");
464 /* LP64 only means 64bit pointers in D. */
465 if (POINTER_SIZE
== 64)
466 VersionCondition::addPredefinedGlobalIdent ("D_LP64");
468 /* Setting `global.params.cov' forces module info generation which is
469 not needed for the GCC coverage implementation. Instead, just
470 test flag_test_coverage while leaving `global.params.cov' unset. */
471 if (flag_test_coverage
)
472 VersionCondition::addPredefinedGlobalIdent ("D_Coverage");
474 VersionCondition::addPredefinedGlobalIdent ("D_PIC");
476 VersionCondition::addPredefinedGlobalIdent ("D_PIE");
478 if (global
.params
.ddoc
.doOutput
)
479 VersionCondition::addPredefinedGlobalIdent ("D_Ddoc");
481 if (global
.params
.useUnitTests
)
482 VersionCondition::addPredefinedGlobalIdent ("unittest");
484 if (global
.params
.useAssert
== CHECKENABLEon
)
485 VersionCondition::addPredefinedGlobalIdent ("assert");
487 if (global
.params
.useIn
== CHECKENABLEon
)
488 VersionCondition::addPredefinedGlobalIdent("D_PreConditions");
490 if (global
.params
.useOut
== CHECKENABLEon
)
491 VersionCondition::addPredefinedGlobalIdent("D_PostConditions");
493 if (global
.params
.useInvariants
== CHECKENABLEon
)
494 VersionCondition::addPredefinedGlobalIdent("D_Invariants");
496 if (global
.params
.useArrayBounds
== CHECKENABLEoff
)
497 VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");
499 if (global
.params
.betterC
)
500 VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
503 if (global
.params
.useModuleInfo
)
504 VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
505 if (global
.params
.useExceptions
)
506 VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
507 if (global
.params
.useTypeInfo
)
508 VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
512 VersionCondition::addPredefinedGlobalIdent ("D_Optimized");
514 VersionCondition::addPredefinedGlobalIdent ("all");
516 /* Emit all target-specific version identifiers. */
517 targetdm
.d_cpu_versions ();
518 targetdm
.d_os_versions ();
520 VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
523 /* A helper for d_build_builtins_module. Return a new ALIAS for TYPE.
524 Analogous to `alias ALIAS = TYPE' in D code. */
526 static AliasDeclaration
*
527 build_alias_declaration (const char *alias
, Type
*type
)
529 return AliasDeclaration::create (Loc (), Identifier::idPool (alias
), type
);
532 /* A helper function for Target::loadModule. Generates all code for the
533 `gcc.builtins' module, whose frontend symbol should be M. */
536 d_build_builtins_module (Module
*m
)
538 Dsymbols
*members
= d_gc_malloc
<Dsymbols
> ();
541 for (size_t i
= 0; vec_safe_iterate (gcc_builtins_functions
, i
, &decl
); ++i
)
543 const char *name
= IDENTIFIER_POINTER (DECL_NAME (decl
));
544 Type
*t
= build_frontend_type (TREE_TYPE (decl
));
545 TypeFunction
*tf
= t
? t
->isTypeFunction () : NULL
;
547 /* Cannot create built-in function type for DECL. */
551 /* A few notes on D2 attributes applied to builtin functions:
552 - It is assumed that built-ins solely provided by the compiler are
553 considered @safe and pure.
554 - Built-ins that correspond to `extern(C)' functions in the standard
555 library that have `__attribute__(nothrow)' are considered `@trusted'.
556 - The purity of a built-in can vary depending on compiler flags set
557 upon initialization, or by the `-foptions' passed, such as
558 flag_unsafe_math_optimizations.
559 - Built-ins never use the GC or raise a D exception, and so are always
560 marked as `nothrow' and `@nogc'. */
561 tf
->purity
= DECL_PURE_P (decl
) ? PURE::const_
562 : TREE_READONLY (decl
) ? PURE::const_
563 : DECL_IS_NOVOPS (decl
) ? PURE::weak
564 : !DECL_ASSEMBLER_NAME_SET_P (decl
) ? PURE::weak
566 tf
->trust
= !DECL_ASSEMBLER_NAME_SET_P (decl
) ? TRUST::safe
567 : TREE_NOTHROW (decl
) ? TRUST::trusted
569 tf
->isnothrow (true);
572 FuncDeclaration
*func
573 = FuncDeclaration::create (Loc (), Loc (),
574 Identifier::idPool (name
),
576 DECL_LANG_SPECIFIC (decl
) = build_lang_decl (func
);
578 func
->builtin
= BUILTIN::gcc
;
580 members
->push (func
);
583 for (size_t i
= 0; vec_safe_iterate (gcc_builtins_types
, i
, &decl
); ++i
)
585 const char *name
= IDENTIFIER_POINTER (DECL_NAME (decl
));
586 Type
*t
= build_frontend_type (TREE_TYPE (decl
));
588 /* Cannot create built-in type for DECL. */
592 members
->push (build_alias_declaration (name
, t
));
595 /* Iterate through the target-specific builtin types for va_list. */
596 if (targetm
.enum_va_list_p
)
601 for (int i
= 0; targetm
.enum_va_list_p (i
, &name
, &type
); ++i
)
603 Type
*t
= build_frontend_type (type
);
604 /* Cannot create built-in type. */
608 members
->push (build_alias_declaration (name
, t
));
612 /* Push out declarations for any RECORD_TYPE types encountered when building
613 all builtin functions and types. */
614 for (size_t i
= 0; i
< builtin_converted_decls
.length (); ++i
)
616 /* Currently, there is no need to run semantic, but we do want to output
617 initializers, typeinfo, and others on demand. */
618 Dsymbol
*dsym
= builtin_converted_decls
[i
].dsym
;
619 if (dsym
!= NULL
&& !dsym
->isAnonymous ())
622 members
->push (dsym
);
626 /* Expose target-specific va_list type. */
627 Type
*tvalist
= target
.va_listType (Loc (), NULL
);
628 TypeStruct
*ts
= tvalist
->isTypeStruct ();
629 if (ts
== NULL
|| !ts
->sym
->isAnonymous ())
630 members
->push (build_alias_declaration ("__builtin_va_list", tvalist
));
633 ts
->sym
->ident
= Identifier::idPool ("__builtin_va_list");
634 members
->push (ts
->sym
);
637 /* Expose target-specific integer types to the builtins module. */
639 Type
*t
= build_frontend_type (long_integer_type_node
);
640 members
->push (build_alias_declaration ("__builtin_clong", t
));
642 t
= build_frontend_type (long_unsigned_type_node
);
643 members
->push (build_alias_declaration ("__builtin_culong", t
));
645 t
= build_frontend_type (long_long_integer_type_node
);
646 members
->push (build_alias_declaration ("__builtin_clonglong", t
));
648 t
= build_frontend_type (long_long_unsigned_type_node
);
649 members
->push (build_alias_declaration ("__builtin_culonglong", t
));
651 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (byte_mode
, 0));
652 members
->push (build_alias_declaration ("__builtin_machine_byte", t
));
654 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (byte_mode
, 1));
655 members
->push (build_alias_declaration ("__builtin_machine_ubyte", t
));
657 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (word_mode
, 0));
658 members
->push (build_alias_declaration ("__builtin_machine_int", t
));
660 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (word_mode
, 1));
661 members
->push (build_alias_declaration ("__builtin_machine_uint", t
));
663 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (ptr_mode
, 0));
664 members
->push (build_alias_declaration ("__builtin_pointer_int", t
));
666 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (ptr_mode
, 1));
667 members
->push (build_alias_declaration ("__builtin_pointer_uint", t
));
669 /* _Unwind_Word has its own target specific mode. */
670 machine_mode mode
= targetm
.unwind_word_mode ();
671 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (mode
, 0));
672 members
->push (build_alias_declaration ("__builtin_unwind_int", t
));
674 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (mode
, 1));
675 members
->push (build_alias_declaration ("__builtin_unwind_uint", t
));
678 m
->members
->push (LinkDeclaration::create (Loc (), LINK::c
, members
));
681 /* Remove all type modifiers from TYPE, returning the naked type. */
684 strip_type_modifiers (Type
*type
)
686 if (type
->ty
== TY::Tpointer
)
688 Type
*tnext
= strip_type_modifiers (type
->nextOf ());
689 return tnext
->pointerTo ();
692 return type
->castMod (0);
695 /* Returns true if types T1 and T2 representing return types or types of
696 function arguments are close enough to be considered interchangeable. */
699 matches_builtin_type (Type
*t1
, Type
*t2
)
701 Type
*tb1
= strip_type_modifiers (t1
);
702 Type
*tb2
= strip_type_modifiers (t2
);
704 if (same_type_p (t1
, t2
))
707 if (((tb1
->isTypePointer () && tb2
->isTypePointer ())
708 || (tb1
->isTypeVector () && tb2
->isTypeVector ()))
709 && tb1
->implicitConvTo (tb2
) != MATCH::nomatch
)
712 if (tb1
->isintegral () == tb2
->isintegral ()
713 && tb1
->size () == tb2
->size ())
719 /* Check whether the declared function type T1 is covariant with the built-in
720 function type T2. Returns true if they are covariant. */
723 covariant_with_builtin_type_p (Type
*t1
, Type
*t2
)
725 /* Check whether the declared function matches the built-in. */
726 if (same_type_p (t1
, t2
) || t1
->covariant (t2
) == Covariant::yes
)
729 /* May not be covariant because of D attributes applied on t1.
730 Strip them all off and compare again. */
731 TypeFunction
*tf1
= t1
->isTypeFunction ();
732 TypeFunction
*tf2
= t2
->isTypeFunction ();
734 /* Check for obvious reasons why types may be distinct. */
735 if (tf1
== NULL
|| tf2
== NULL
736 || tf1
->isref () != tf2
->isref ()
737 || tf1
->parameterList
.varargs
!= tf2
->parameterList
.varargs
738 || tf1
->parameterList
.length () != tf2
->parameterList
.length ())
741 /* Check return type and each parameter type for mismatch. */
742 if (!matches_builtin_type (tf1
->next
, tf2
->next
))
745 const size_t nparams
= tf1
->parameterList
.length ();
746 for (size_t i
= 0; i
< nparams
; i
++)
748 Parameter
*fparam1
= tf1
->parameterList
[i
];
749 Parameter
*fparam2
= tf2
->parameterList
[i
];
751 if (fparam1
->isReference () != fparam2
->isReference ()
752 || fparam1
->isLazy () != fparam2
->isLazy ())
755 if (!matches_builtin_type (fparam1
->type
, fparam2
->type
))
762 /* Search for any `extern(C)' functions that match any known GCC library builtin
763 function in D and override its internal back-end symbol. */
766 maybe_set_builtin_1 (Dsymbol
*d
)
768 AttribDeclaration
*ad
= d
->isAttribDeclaration ();
769 FuncDeclaration
*fd
= d
->isFuncDeclaration ();
773 /* Recursively search through attribute decls. */
774 Dsymbols
*decls
= ad
->include (NULL
);
775 if (decls
&& decls
->length
)
777 for (size_t i
= 0; i
< decls
->length
; i
++)
779 Dsymbol
*sym
= (*decls
)[i
];
780 maybe_set_builtin_1 (sym
);
784 else if (fd
&& !fd
->fbody
&& fd
->resolvedLinkage () == LINK::c
)
786 tree ident
= get_identifier (fd
->ident
->toChars ());
787 tree decl
= IDENTIFIER_DECL_TREE (ident
);
789 if (decl
&& TREE_CODE (decl
) == FUNCTION_DECL
790 && DECL_ASSEMBLER_NAME_SET_P (decl
)
791 && fndecl_built_in_p (decl
, BUILT_IN_NORMAL
))
793 /* Found a match, tell the frontend this is a builtin. */
794 DECL_LANG_SPECIFIC (decl
) = build_lang_decl (fd
);
796 fd
->builtin
= BUILTIN::gcc
;
798 /* Copy front-end attributes to the builtin. */
799 apply_user_attributes (fd
, fd
->csym
);
801 /* Function has `pragma(mangle)' specified, override its name. */
802 if (fd
->mangleOverride
.length
)
805 get_identifier_with_length (fd
->mangleOverride
.ptr
,
806 fd
->mangleOverride
.length
);
807 const char *asmname
= IDENTIFIER_POINTER (mangle
);
808 set_builtin_user_assembler_name (decl
, asmname
);
811 /* Warn when return and argument types of the user defined function is
812 not covariant with the built-in function type. */
813 if (Type
*type
= build_frontend_type (TREE_TYPE (decl
)))
815 if (!covariant_with_builtin_type_p (fd
->type
, type
))
817 warning_at (make_location_t (fd
->loc
),
818 OPT_Wbuiltin_declaration_mismatch
,
819 "conflicting types for built-in function %qs; "
821 fd
->toChars (), type
->toChars ());
828 /* A helper function for Target::loadModule. Traverse all members in module M
829 to search for any functions that can be mapped to any GCC builtin. */
832 d_maybe_set_builtin (Module
*m
)
834 if (!m
|| !m
->members
)
837 for (size_t i
= 0; i
< m
->members
->length
; i
++)
839 Dsymbol
*sym
= (*m
->members
)[i
];
840 maybe_set_builtin_1 (sym
);
844 /* Used to help initialize the builtin-types.def table. When a type of
845 the correct size doesn't exist, use error_mark_node instead of NULL.
846 The latter results in segfaults even when a decl using the type doesn't
850 builtin_type_for_size (int size
, bool unsignedp
)
852 tree type
= lang_hooks
.types
.type_for_size (size
, unsignedp
);
853 return type
? type
: error_mark_node
;
856 /* Support for DEF_BUILTIN. */
859 do_build_builtin_fn (built_in_function fncode
,
861 built_in_class fnclass
,
862 tree fntype
, bool both_p
, bool fallback_p
,
863 tree fnattrs
, bool implicit_p
)
868 if (fntype
== error_mark_node
)
871 gcc_assert ((!both_p
&& !fallback_p
)
872 || startswith (name
, "__builtin_"));
874 libname
= name
+ strlen ("__builtin_");
876 decl
= add_builtin_function (name
, fntype
, fncode
, fnclass
,
877 fallback_p
? libname
: NULL
, fnattrs
);
879 set_builtin_decl (fncode
, decl
, implicit_p
);
882 /* Standard data types to be used in builtin argument declarations. */
884 static GTY(()) tree string_type_node
;
885 static GTY(()) tree const_string_type_node
;
886 static GTY(()) tree wint_type_node
;
887 static GTY(()) tree intmax_type_node
;
888 static GTY(()) tree uintmax_type_node
;
889 static GTY(()) tree signed_size_type_node
;
892 /* Build nodes that would have been created by the C front-end; necessary
893 for including builtin-types.def and ultimately builtins.def. */
896 d_build_c_type_nodes (void)
898 string_type_node
= build_pointer_type (char_type_node
);
899 const_string_type_node
900 = build_pointer_type (build_qualified_type (char_type_node
,
903 if (strcmp (UINTMAX_TYPE
, "unsigned int") == 0)
905 intmax_type_node
= integer_type_node
;
906 uintmax_type_node
= unsigned_type_node
;
908 else if (strcmp (UINTMAX_TYPE
, "long unsigned int") == 0)
910 intmax_type_node
= long_integer_type_node
;
911 uintmax_type_node
= long_unsigned_type_node
;
913 else if (strcmp (UINTMAX_TYPE
, "long long unsigned int") == 0)
915 intmax_type_node
= long_long_integer_type_node
;
916 uintmax_type_node
= long_long_unsigned_type_node
;
921 signed_size_type_node
= signed_type_for (size_type_node
);
922 wint_type_node
= unsigned_type_node
;
923 pid_type_node
= integer_type_node
;
926 /* Build nodes that are used by the D front-end.
927 These are distinct from C types. */
930 d_build_d_type_nodes (void)
932 /* Integral types. */
933 d_byte_type
= make_signed_type (8);
934 d_ubyte_type
= make_unsigned_type (8);
936 d_short_type
= make_signed_type (16);
937 d_ushort_type
= make_unsigned_type (16);
939 d_int_type
= make_signed_type (32);
940 d_uint_type
= make_unsigned_type (32);
942 d_long_type
= make_signed_type (64);
943 d_ulong_type
= make_unsigned_type (64);
945 d_cent_type
= make_signed_type (128);
946 d_ucent_type
= make_unsigned_type (128);
949 /* Re-define size_t as a D type. */
950 machine_mode type_mode
= TYPE_MODE (size_type_node
);
951 size_type_node
= lang_hooks
.types
.type_for_mode (type_mode
, 1);
954 /* Bool and Character types. */
955 d_bool_type
= make_unsigned_type (1);
956 TREE_SET_CODE (d_bool_type
, BOOLEAN_TYPE
);
958 char8_type_node
= make_unsigned_type (8);
959 TYPE_STRING_FLAG (char8_type_node
) = 1;
961 char16_type_node
= make_unsigned_type (16);
962 TYPE_STRING_FLAG (char16_type_node
) = 1;
964 char32_type_node
= make_unsigned_type (32);
965 TYPE_STRING_FLAG (char32_type_node
) = 1;
967 /* Imaginary types. */
968 ifloat_type_node
= build_distinct_type_copy (float_type_node
);
969 TYPE_IMAGINARY_FLOAT (ifloat_type_node
) = 1;
971 idouble_type_node
= build_distinct_type_copy (double_type_node
);
972 TYPE_IMAGINARY_FLOAT (idouble_type_node
) = 1;
974 ireal_type_node
= build_distinct_type_copy (long_double_type_node
);
975 TYPE_IMAGINARY_FLOAT (ireal_type_node
) = 1;
978 noreturn_type_node
= build_distinct_type_copy (void_type_node
);
980 /* Calling build_ctype() links the front-end Type to the GCC node,
981 and sets the TYPE_NAME to the D language type. */
982 for (unsigned ty
= 0; ty
< (unsigned) TY::TMAX
; ty
++)
984 if (Type::basic
[ty
] != NULL
)
985 build_ctype (Type::basic
[ty
]);
988 /* Used for ModuleInfo, ClassInfo, and Interface decls. */
989 unknown_type_node
= make_node (RECORD_TYPE
);
991 /* Make sure we get a unique function type, so we can give
992 its pointer type a name. (This wins for gdb). */
994 tree vfunc_type
= make_node (FUNCTION_TYPE
);
995 TREE_TYPE (vfunc_type
) = d_int_type
;
996 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
997 layout_type (vfunc_type
);
999 vtable_entry_type
= build_pointer_type (vfunc_type
);
1002 vtbl_ptr_type_node
= build_pointer_type (vtable_entry_type
);
1003 layout_type (vtbl_ptr_type_node
);
1005 /* When an object is accessed via an interface, this type appears
1006 as the first entry in its vtable. */
1008 tree domain
= build_index_type (size_int (3));
1009 vtbl_interface_type_node
= build_array_type (ptr_type_node
, domain
);
1012 /* Use `void[]' as a generic dynamic array type. */
1013 array_type_node
= make_struct_type ("__builtin_void[]", 2,
1014 get_identifier ("length"), size_type_node
,
1015 get_identifier ("ptr"), ptr_type_node
);
1016 TYPE_DYNAMIC_ARRAY (array_type_node
) = 1;
1018 null_array_node
= d_array_value (array_type_node
, size_zero_node
,
1022 /* Handle default attributes. */
1024 enum built_in_attribute
1026 #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
1027 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
1028 #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
1029 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
1030 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
1031 #include "builtin-attrs.def"
1032 #undef DEF_ATTR_NULL_TREE
1034 #undef DEF_ATTR_STRING
1035 #undef DEF_ATTR_IDENT
1036 #undef DEF_ATTR_TREE_LIST
1040 static GTY(()) tree built_in_attributes
[(int) ATTR_LAST
];
1042 /* Initialize the attribute table for all the supported builtins. */
1045 d_init_attributes (void)
1047 /* Fill in the built_in_attributes array. */
1048 #define DEF_ATTR_NULL_TREE(ENUM) \
1049 built_in_attributes[(int) ENUM] = NULL_TREE;
1050 # define DEF_ATTR_INT(ENUM, VALUE) \
1051 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
1052 #define DEF_ATTR_STRING(ENUM, VALUE) \
1053 built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
1054 #define DEF_ATTR_IDENT(ENUM, STRING) \
1055 built_in_attributes[(int) ENUM] = get_identifier (STRING);
1056 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
1057 built_in_attributes[(int) ENUM] \
1058 = tree_cons (built_in_attributes[(int) PURPOSE], \
1059 built_in_attributes[(int) VALUE], \
1060 built_in_attributes[(int) CHAIN]);
1061 #include "builtin-attrs.def"
1062 #undef DEF_ATTR_NULL_TREE
1064 #undef DEF_ATTR_STRING
1065 #undef DEF_ATTR_IDENT
1066 #undef DEF_ATTR_TREE_LIST
1069 /* Builtin types. */
1073 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
1074 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
1075 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
1076 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
1077 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
1078 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
1079 #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
1080 #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1082 #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1084 #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1085 ARG6, ARG7, ARG8) NAME,
1086 #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1087 ARG6, ARG7, ARG8, ARG9) NAME,
1088 #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1089 ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
1090 #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1091 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
1092 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
1093 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
1094 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
1095 #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
1096 #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
1097 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1099 #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1101 #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1103 #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1104 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
1105 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
1106 #include "builtin-types.def"
1107 #undef DEF_PRIMITIVE_TYPE
1108 #undef DEF_FUNCTION_TYPE_0
1109 #undef DEF_FUNCTION_TYPE_1
1110 #undef DEF_FUNCTION_TYPE_2
1111 #undef DEF_FUNCTION_TYPE_3
1112 #undef DEF_FUNCTION_TYPE_4
1113 #undef DEF_FUNCTION_TYPE_5
1114 #undef DEF_FUNCTION_TYPE_6
1115 #undef DEF_FUNCTION_TYPE_7
1116 #undef DEF_FUNCTION_TYPE_8
1117 #undef DEF_FUNCTION_TYPE_9
1118 #undef DEF_FUNCTION_TYPE_10
1119 #undef DEF_FUNCTION_TYPE_11
1120 #undef DEF_FUNCTION_TYPE_VAR_0
1121 #undef DEF_FUNCTION_TYPE_VAR_1
1122 #undef DEF_FUNCTION_TYPE_VAR_2
1123 #undef DEF_FUNCTION_TYPE_VAR_3
1124 #undef DEF_FUNCTION_TYPE_VAR_4
1125 #undef DEF_FUNCTION_TYPE_VAR_5
1126 #undef DEF_FUNCTION_TYPE_VAR_6
1127 #undef DEF_FUNCTION_TYPE_VAR_7
1128 #undef DEF_FUNCTION_TYPE_VAR_11
1129 #undef DEF_POINTER_TYPE
1133 typedef enum d_builtin_type builtin_type
;
1135 /* A temporary array used in communication with def_fn_type. */
1136 static GTY(()) tree builtin_types
[(int) BT_LAST
+ 1];
1138 /* A helper function for d_init_builtins. Build function type for DEF with
1139 return type RET and N arguments. If VAR is true, then the function should
1140 be variadic after those N arguments.
1142 Takes special care not to ICE if any of the types involved are
1143 error_mark_node, which indicates that said type is not in fact available
1144 (see builtin_type_for_size). In which case the function type as a whole
1145 should be error_mark_node. */
1148 def_fn_type (builtin_type def
, builtin_type ret
, bool var
, int n
, ...)
1151 tree
*args
= XALLOCAVEC (tree
, n
);
1156 for (i
= 0; i
< n
; ++i
)
1158 builtin_type a
= (builtin_type
) va_arg (list
, int);
1159 t
= builtin_types
[a
];
1160 if (t
== error_mark_node
)
1165 t
= builtin_types
[ret
];
1166 if (t
== error_mark_node
)
1169 t
= build_varargs_function_type_array (t
, n
, args
);
1171 t
= build_function_type_array (t
, n
, args
);
1174 builtin_types
[def
] = t
;
1178 /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
1179 VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
1182 d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED
,
1183 tree va_list_arg_type_node ATTRIBUTE_UNUSED
)
1185 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
1186 builtin_types[(int) ENUM] = VALUE;
1187 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
1188 def_fn_type (ENUM, RETURN, 0, 0);
1189 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
1190 def_fn_type (ENUM, RETURN, 0, 1, ARG1);
1191 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
1192 def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
1193 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1194 def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
1195 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1196 def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
1197 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1198 def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1199 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1201 def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1202 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1204 def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1205 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1207 def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1209 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1210 ARG6, ARG7, ARG8, ARG9) \
1211 def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1213 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1214 ARG6, ARG7, ARG8, ARG9, ARG10) \
1215 def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1216 ARG7, ARG8, ARG9, ARG10);
1217 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1218 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1219 def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1220 ARG7, ARG8, ARG9, ARG10, ARG11);
1221 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
1222 def_fn_type (ENUM, RETURN, 1, 0);
1223 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
1224 def_fn_type (ENUM, RETURN, 1, 1, ARG1);
1225 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
1226 def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
1227 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1228 def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
1229 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1230 def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
1231 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1232 def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1233 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1235 def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1236 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1238 def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1239 #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1240 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1241 def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1242 ARG7, ARG8, ARG9, ARG10, ARG11);
1243 #define DEF_POINTER_TYPE(ENUM, TYPE) \
1244 builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
1246 #include "builtin-types.def"
1248 #undef DEF_PRIMITIVE_TYPE
1249 #undef DEF_FUNCTION_TYPE_1
1250 #undef DEF_FUNCTION_TYPE_2
1251 #undef DEF_FUNCTION_TYPE_3
1252 #undef DEF_FUNCTION_TYPE_4
1253 #undef DEF_FUNCTION_TYPE_5
1254 #undef DEF_FUNCTION_TYPE_6
1255 #undef DEF_FUNCTION_TYPE_7
1256 #undef DEF_FUNCTION_TYPE_8
1257 #undef DEF_FUNCTION_TYPE_9
1258 #undef DEF_FUNCTION_TYPE_10
1259 #undef DEF_FUNCTION_TYPE_11
1260 #undef DEF_FUNCTION_TYPE_VAR_0
1261 #undef DEF_FUNCTION_TYPE_VAR_1
1262 #undef DEF_FUNCTION_TYPE_VAR_2
1263 #undef DEF_FUNCTION_TYPE_VAR_3
1264 #undef DEF_FUNCTION_TYPE_VAR_4
1265 #undef DEF_FUNCTION_TYPE_VAR_5
1266 #undef DEF_FUNCTION_TYPE_VAR_6
1267 #undef DEF_FUNCTION_TYPE_VAR_7
1268 #undef DEF_FUNCTION_TYPE_VAR_11
1269 #undef DEF_POINTER_TYPE
1270 builtin_types
[(int) BT_LAST
] = NULL_TREE
;
1272 d_init_attributes ();
1274 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
1275 NONANSI_P, ATTRS, IMPLICIT, COND) \
1277 do_build_builtin_fn (ENUM, NAME, CLASS, \
1278 builtin_types[(int) TYPE], \
1279 BOTH_P, FALLBACK_P, \
1280 built_in_attributes[(int) ATTRS], IMPLICIT);
1281 #include "builtins.def"
1285 /* Build builtin functions and types for the D language frontend. */
1288 d_init_builtins (void)
1290 d_build_c_type_nodes ();
1291 d_build_d_type_nodes ();
1293 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
1295 /* It might seem natural to make the argument type a pointer, but there
1296 is no implicit casting from arrays to pointers in D. */
1297 d_define_builtins (va_list_type_node
, va_list_type_node
);
1301 d_define_builtins (build_reference_type (va_list_type_node
),
1305 targetm
.init_builtins ();
1306 build_common_builtin_nodes ();
1309 /* Registration of machine- or os-specific builtin types.
1310 Add to builtin types list for maybe processing later
1311 if `gcc.builtins' was imported into the current module. */
1314 d_register_builtin_type (tree type
, const char *name
)
1316 tree decl
= build_decl (UNKNOWN_LOCATION
, TYPE_DECL
,
1317 get_identifier (name
), type
);
1318 DECL_ARTIFICIAL (decl
) = 1;
1320 if (!TYPE_NAME (type
))
1321 TYPE_NAME (type
) = decl
;
1323 vec_safe_push (gcc_builtins_types
, decl
);
1326 /* Add DECL to builtin functions list for maybe processing later
1327 if `gcc.builtins' was imported into the current module. */
1330 d_builtin_function (tree decl
)
1332 if (!flag_no_builtin
&& DECL_ASSEMBLER_NAME_SET_P (decl
))
1334 /* Associate the assembler identifier with the built-in. */
1335 tree ident
= DECL_ASSEMBLER_NAME (decl
);
1336 IDENTIFIER_DECL_TREE (ident
) = decl
;
1339 vec_safe_push (gcc_builtins_functions
, decl
);
1343 /* Same as d_builtin_function, but used to delay putting in back-end builtin
1344 functions until the ISA that defines the builtin has been declared.
1345 However in D, there is no global namespace. All builtins get pushed into the
1346 `gcc.builtins' module, which is constructed during the semantic analysis
1347 pass, which has already finished by the time target attributes are evaluated.
1348 So builtins are not pushed because they would be ultimately ignored.
1349 The purpose of having this function then is to improve compile-time
1350 reflection support to allow user-code to determine whether a given back end
1351 function is enabled by the ISA. */
1354 d_builtin_function_ext_scope (tree decl
)
1359 #include "gt-d-d-builtins.h"