1 /* d-builtins.cc -- GCC builtins support for D.
2 Copyright (C) 2006-2022 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 VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
504 VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
505 VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
509 VersionCondition::addPredefinedGlobalIdent ("D_Optimized");
511 VersionCondition::addPredefinedGlobalIdent ("all");
513 /* Emit all target-specific version identifiers. */
514 targetdm
.d_cpu_versions ();
515 targetdm
.d_os_versions ();
517 VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
520 /* A helper for d_build_builtins_module. Return a new ALIAS for TYPE.
521 Analogous to `alias ALIAS = TYPE' in D code. */
523 static AliasDeclaration
*
524 build_alias_declaration (const char *alias
, Type
*type
)
526 return AliasDeclaration::create (Loc (), Identifier::idPool (alias
), type
);
529 /* A helper function for Target::loadModule. Generates all code for the
530 `gcc.builtins' module, whose frontend symbol should be M. */
533 d_build_builtins_module (Module
*m
)
535 Dsymbols
*members
= d_gc_malloc
<Dsymbols
> ();
538 for (size_t i
= 0; vec_safe_iterate (gcc_builtins_functions
, i
, &decl
); ++i
)
540 const char *name
= IDENTIFIER_POINTER (DECL_NAME (decl
));
541 Type
*t
= build_frontend_type (TREE_TYPE (decl
));
542 TypeFunction
*tf
= t
? t
->isTypeFunction () : NULL
;
544 /* Cannot create built-in function type for DECL. */
548 /* A few notes on D2 attributes applied to builtin functions:
549 - It is assumed that built-ins solely provided by the compiler are
550 considered @safe and pure.
551 - Built-ins that correspond to `extern(C)' functions in the standard
552 library that have `__attribute__(nothrow)' are considered `@trusted'.
553 - The purity of a built-in can vary depending on compiler flags set
554 upon initialization, or by the `-foptions' passed, such as
555 flag_unsafe_math_optimizations.
556 - Built-ins never use the GC or raise a D exception, and so are always
557 marked as `nothrow' and `@nogc'. */
558 tf
->purity
= DECL_PURE_P (decl
) ? PURE::const_
559 : TREE_READONLY (decl
) ? PURE::const_
560 : DECL_IS_NOVOPS (decl
) ? PURE::weak
561 : !DECL_ASSEMBLER_NAME_SET_P (decl
) ? PURE::weak
563 tf
->trust
= !DECL_ASSEMBLER_NAME_SET_P (decl
) ? TRUST::safe
564 : TREE_NOTHROW (decl
) ? TRUST::trusted
566 tf
->isnothrow (true);
569 FuncDeclaration
*func
570 = FuncDeclaration::create (Loc (), Loc (),
571 Identifier::idPool (name
),
573 DECL_LANG_SPECIFIC (decl
) = build_lang_decl (func
);
575 func
->builtin
= BUILTIN::gcc
;
577 members
->push (func
);
580 for (size_t i
= 0; vec_safe_iterate (gcc_builtins_types
, i
, &decl
); ++i
)
582 const char *name
= IDENTIFIER_POINTER (DECL_NAME (decl
));
583 Type
*t
= build_frontend_type (TREE_TYPE (decl
));
585 /* Cannot create built-in type for DECL. */
589 members
->push (build_alias_declaration (name
, t
));
592 /* Iterate through the target-specific builtin types for va_list. */
593 if (targetm
.enum_va_list_p
)
598 for (int i
= 0; targetm
.enum_va_list_p (i
, &name
, &type
); ++i
)
600 Type
*t
= build_frontend_type (type
);
601 /* Cannot create built-in type. */
605 members
->push (build_alias_declaration (name
, t
));
609 /* Push out declarations for any RECORD_TYPE types encountered when building
610 all builtin functions and types. */
611 for (size_t i
= 0; i
< builtin_converted_decls
.length (); ++i
)
613 /* Currently, there is no need to run semantic, but we do want to output
614 initializers, typeinfo, and others on demand. */
615 Dsymbol
*dsym
= builtin_converted_decls
[i
].dsym
;
616 if (dsym
!= NULL
&& !dsym
->isAnonymous ())
619 members
->push (dsym
);
623 /* Expose target-specific va_list type. */
624 Type
*tvalist
= target
.va_listType (Loc (), NULL
);
625 TypeStruct
*ts
= tvalist
->isTypeStruct ();
626 if (ts
== NULL
|| !ts
->sym
->isAnonymous ())
627 members
->push (build_alias_declaration ("__builtin_va_list", tvalist
));
630 ts
->sym
->ident
= Identifier::idPool ("__builtin_va_list");
631 members
->push (ts
->sym
);
634 /* Expose target-specific integer types to the builtins module. */
636 Type
*t
= build_frontend_type (long_integer_type_node
);
637 members
->push (build_alias_declaration ("__builtin_clong", t
));
639 t
= build_frontend_type (long_unsigned_type_node
);
640 members
->push (build_alias_declaration ("__builtin_culong", t
));
642 t
= build_frontend_type (long_long_integer_type_node
);
643 members
->push (build_alias_declaration ("__builtin_clonglong", t
));
645 t
= build_frontend_type (long_long_unsigned_type_node
);
646 members
->push (build_alias_declaration ("__builtin_culonglong", t
));
648 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (byte_mode
, 0));
649 members
->push (build_alias_declaration ("__builtin_machine_byte", t
));
651 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (byte_mode
, 1));
652 members
->push (build_alias_declaration ("__builtin_machine_ubyte", t
));
654 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (word_mode
, 0));
655 members
->push (build_alias_declaration ("__builtin_machine_int", t
));
657 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (word_mode
, 1));
658 members
->push (build_alias_declaration ("__builtin_machine_uint", t
));
660 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (ptr_mode
, 0));
661 members
->push (build_alias_declaration ("__builtin_pointer_int", t
));
663 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (ptr_mode
, 1));
664 members
->push (build_alias_declaration ("__builtin_pointer_uint", t
));
666 /* _Unwind_Word has its own target specific mode. */
667 machine_mode mode
= targetm
.unwind_word_mode ();
668 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (mode
, 0));
669 members
->push (build_alias_declaration ("__builtin_unwind_int", t
));
671 t
= build_frontend_type (lang_hooks
.types
.type_for_mode (mode
, 1));
672 members
->push (build_alias_declaration ("__builtin_unwind_uint", t
));
675 m
->members
->push (LinkDeclaration::create (Loc (), LINK::c
, members
));
678 /* Remove all type modifiers from TYPE, returning the naked type. */
681 strip_type_modifiers (Type
*type
)
683 if (type
->ty
== TY::Tpointer
)
685 Type
*tnext
= strip_type_modifiers (type
->nextOf ());
686 return tnext
->pointerTo ();
689 return type
->castMod (0);
692 /* Returns true if types T1 and T2 representing return types or types of
693 function arguments are close enough to be considered interchangeable. */
696 matches_builtin_type (Type
*t1
, Type
*t2
)
698 Type
*tb1
= strip_type_modifiers (t1
);
699 Type
*tb2
= strip_type_modifiers (t2
);
701 if (same_type_p (t1
, t2
))
704 if (((tb1
->isTypePointer () && tb2
->isTypePointer ())
705 || (tb1
->isTypeVector () && tb2
->isTypeVector ()))
706 && tb1
->implicitConvTo (tb2
) != MATCH::nomatch
)
709 if (tb1
->isintegral () == tb2
->isintegral ()
710 && tb1
->size () == tb2
->size ())
716 /* Check whether the declared function type T1 is covariant with the built-in
717 function type T2. Returns true if they are covariant. */
720 covariant_with_builtin_type_p (Type
*t1
, Type
*t2
)
722 /* Check whether the declared function matches the built-in. */
723 if (same_type_p (t1
, t2
) || t1
->covariant (t2
) == Covariant::yes
)
726 /* May not be covariant because of D attributes applied on t1.
727 Strip them all off and compare again. */
728 TypeFunction
*tf1
= t1
->isTypeFunction ();
729 TypeFunction
*tf2
= t2
->isTypeFunction ();
731 /* Check for obvious reasons why types may be distinct. */
732 if (tf1
== NULL
|| tf2
== NULL
733 || tf1
->isref () != tf2
->isref ()
734 || tf1
->parameterList
.varargs
!= tf2
->parameterList
.varargs
735 || tf1
->parameterList
.length () != tf2
->parameterList
.length ())
738 /* Check return type and each parameter type for mismatch. */
739 if (!matches_builtin_type (tf1
->next
, tf2
->next
))
742 const size_t nparams
= tf1
->parameterList
.length ();
743 for (size_t i
= 0; i
< nparams
; i
++)
745 Parameter
*fparam1
= tf1
->parameterList
[i
];
746 Parameter
*fparam2
= tf2
->parameterList
[i
];
748 if (fparam1
->isReference () != fparam2
->isReference ()
749 || fparam1
->isLazy () != fparam2
->isLazy ())
752 if (!matches_builtin_type (fparam1
->type
, fparam2
->type
))
759 /* Search for any `extern(C)' functions that match any known GCC library builtin
760 function in D and override its internal back-end symbol. */
763 maybe_set_builtin_1 (Dsymbol
*d
)
765 AttribDeclaration
*ad
= d
->isAttribDeclaration ();
766 FuncDeclaration
*fd
= d
->isFuncDeclaration ();
770 /* Recursively search through attribute decls. */
771 Dsymbols
*decls
= ad
->include (NULL
);
772 if (decls
&& decls
->length
)
774 for (size_t i
= 0; i
< decls
->length
; i
++)
776 Dsymbol
*sym
= (*decls
)[i
];
777 maybe_set_builtin_1 (sym
);
781 else if (fd
&& !fd
->fbody
&& fd
->resolvedLinkage () == LINK::c
)
783 tree ident
= get_identifier (fd
->ident
->toChars ());
784 tree decl
= IDENTIFIER_DECL_TREE (ident
);
786 if (decl
&& TREE_CODE (decl
) == FUNCTION_DECL
787 && DECL_ASSEMBLER_NAME_SET_P (decl
)
788 && fndecl_built_in_p (decl
, BUILT_IN_NORMAL
))
790 /* Found a match, tell the frontend this is a builtin. */
791 DECL_LANG_SPECIFIC (decl
) = build_lang_decl (fd
);
793 fd
->builtin
= BUILTIN::gcc
;
795 /* Copy front-end attributes to the builtin. */
796 apply_user_attributes (fd
, fd
->csym
);
798 /* Function has `pragma(mangle)' specified, override its name. */
799 if (fd
->mangleOverride
.length
)
802 get_identifier_with_length (fd
->mangleOverride
.ptr
,
803 fd
->mangleOverride
.length
);
804 const char *asmname
= IDENTIFIER_POINTER (mangle
);
805 set_builtin_user_assembler_name (decl
, asmname
);
808 /* Warn when return and argument types of the user defined function is
809 not covariant with the built-in function type. */
810 if (Type
*type
= build_frontend_type (TREE_TYPE (decl
)))
812 if (!covariant_with_builtin_type_p (fd
->type
, type
))
814 warning_at (make_location_t (fd
->loc
),
815 OPT_Wbuiltin_declaration_mismatch
,
816 "conflicting types for built-in function %qs; "
818 fd
->toChars (), type
->toChars ());
825 /* A helper function for Target::loadModule. Traverse all members in module M
826 to search for any functions that can be mapped to any GCC builtin. */
829 d_maybe_set_builtin (Module
*m
)
831 if (!m
|| !m
->members
)
834 for (size_t i
= 0; i
< m
->members
->length
; i
++)
836 Dsymbol
*sym
= (*m
->members
)[i
];
837 maybe_set_builtin_1 (sym
);
841 /* Used to help initialize the builtin-types.def table. When a type of
842 the correct size doesn't exist, use error_mark_node instead of NULL.
843 The latter results in segfaults even when a decl using the type doesn't
847 builtin_type_for_size (int size
, bool unsignedp
)
849 tree type
= lang_hooks
.types
.type_for_size (size
, unsignedp
);
850 return type
? type
: error_mark_node
;
853 /* Support for DEF_BUILTIN. */
856 do_build_builtin_fn (built_in_function fncode
,
858 built_in_class fnclass
,
859 tree fntype
, bool both_p
, bool fallback_p
,
860 tree fnattrs
, bool implicit_p
)
865 if (fntype
== error_mark_node
)
868 gcc_assert ((!both_p
&& !fallback_p
)
869 || startswith (name
, "__builtin_"));
871 libname
= name
+ strlen ("__builtin_");
873 decl
= add_builtin_function (name
, fntype
, fncode
, fnclass
,
874 fallback_p
? libname
: NULL
, fnattrs
);
876 set_builtin_decl (fncode
, decl
, implicit_p
);
879 /* Standard data types to be used in builtin argument declarations. */
881 static GTY(()) tree string_type_node
;
882 static GTY(()) tree const_string_type_node
;
883 static GTY(()) tree wint_type_node
;
884 static GTY(()) tree intmax_type_node
;
885 static GTY(()) tree uintmax_type_node
;
886 static GTY(()) tree signed_size_type_node
;
889 /* Build nodes that would have been created by the C front-end; necessary
890 for including builtin-types.def and ultimately builtins.def. */
893 d_build_c_type_nodes (void)
895 string_type_node
= build_pointer_type (char_type_node
);
896 const_string_type_node
897 = build_pointer_type (build_qualified_type (char_type_node
,
900 if (strcmp (UINTMAX_TYPE
, "unsigned int") == 0)
902 intmax_type_node
= integer_type_node
;
903 uintmax_type_node
= unsigned_type_node
;
905 else if (strcmp (UINTMAX_TYPE
, "long unsigned int") == 0)
907 intmax_type_node
= long_integer_type_node
;
908 uintmax_type_node
= long_unsigned_type_node
;
910 else if (strcmp (UINTMAX_TYPE
, "long long unsigned int") == 0)
912 intmax_type_node
= long_long_integer_type_node
;
913 uintmax_type_node
= long_long_unsigned_type_node
;
918 signed_size_type_node
= signed_type_for (size_type_node
);
919 wint_type_node
= unsigned_type_node
;
920 pid_type_node
= integer_type_node
;
923 /* Build nodes that are used by the D front-end.
924 These are distinct from C types. */
927 d_build_d_type_nodes (void)
929 /* Integral types. */
930 d_byte_type
= make_signed_type (8);
931 d_ubyte_type
= make_unsigned_type (8);
933 d_short_type
= make_signed_type (16);
934 d_ushort_type
= make_unsigned_type (16);
936 d_int_type
= make_signed_type (32);
937 d_uint_type
= make_unsigned_type (32);
939 d_long_type
= make_signed_type (64);
940 d_ulong_type
= make_unsigned_type (64);
942 d_cent_type
= make_signed_type (128);
943 d_ucent_type
= make_unsigned_type (128);
946 /* Re-define size_t as a D type. */
947 machine_mode type_mode
= TYPE_MODE (size_type_node
);
948 size_type_node
= lang_hooks
.types
.type_for_mode (type_mode
, 1);
951 /* Bool and Character types. */
952 d_bool_type
= make_unsigned_type (1);
953 TREE_SET_CODE (d_bool_type
, BOOLEAN_TYPE
);
955 char8_type_node
= make_unsigned_type (8);
956 TYPE_STRING_FLAG (char8_type_node
) = 1;
958 char16_type_node
= make_unsigned_type (16);
959 TYPE_STRING_FLAG (char16_type_node
) = 1;
961 char32_type_node
= make_unsigned_type (32);
962 TYPE_STRING_FLAG (char32_type_node
) = 1;
964 /* Imaginary types. */
965 ifloat_type_node
= build_distinct_type_copy (float_type_node
);
966 TYPE_IMAGINARY_FLOAT (ifloat_type_node
) = 1;
968 idouble_type_node
= build_distinct_type_copy (double_type_node
);
969 TYPE_IMAGINARY_FLOAT (idouble_type_node
) = 1;
971 ireal_type_node
= build_distinct_type_copy (long_double_type_node
);
972 TYPE_IMAGINARY_FLOAT (ireal_type_node
) = 1;
975 noreturn_type_node
= build_distinct_type_copy (void_type_node
);
977 /* Calling build_ctype() links the front-end Type to the GCC node,
978 and sets the TYPE_NAME to the D language type. */
979 for (unsigned ty
= 0; ty
< (unsigned) TY::TMAX
; ty
++)
981 if (Type::basic
[ty
] != NULL
)
982 build_ctype (Type::basic
[ty
]);
985 /* Used for ModuleInfo, ClassInfo, and Interface decls. */
986 unknown_type_node
= make_node (RECORD_TYPE
);
988 /* Make sure we get a unique function type, so we can give
989 its pointer type a name. (This wins for gdb). */
991 tree vfunc_type
= make_node (FUNCTION_TYPE
);
992 TREE_TYPE (vfunc_type
) = d_int_type
;
993 TYPE_ARG_TYPES (vfunc_type
) = NULL_TREE
;
994 layout_type (vfunc_type
);
996 vtable_entry_type
= build_pointer_type (vfunc_type
);
999 vtbl_ptr_type_node
= build_pointer_type (vtable_entry_type
);
1000 layout_type (vtbl_ptr_type_node
);
1002 /* When an object is accessed via an interface, this type appears
1003 as the first entry in its vtable. */
1005 tree domain
= build_index_type (size_int (3));
1006 vtbl_interface_type_node
= build_array_type (ptr_type_node
, domain
);
1009 /* Use `void[]' as a generic dynamic array type. */
1010 array_type_node
= make_struct_type ("__builtin_void[]", 2,
1011 get_identifier ("length"), size_type_node
,
1012 get_identifier ("ptr"), ptr_type_node
);
1013 TYPE_DYNAMIC_ARRAY (array_type_node
) = 1;
1015 null_array_node
= d_array_value (array_type_node
, size_zero_node
,
1019 /* Handle default attributes. */
1021 enum built_in_attribute
1023 #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
1024 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
1025 #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
1026 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
1027 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
1028 #include "builtin-attrs.def"
1029 #undef DEF_ATTR_NULL_TREE
1031 #undef DEF_ATTR_STRING
1032 #undef DEF_ATTR_IDENT
1033 #undef DEF_ATTR_TREE_LIST
1037 static GTY(()) tree built_in_attributes
[(int) ATTR_LAST
];
1039 /* Initialize the attribute table for all the supported builtins. */
1042 d_init_attributes (void)
1044 /* Fill in the built_in_attributes array. */
1045 #define DEF_ATTR_NULL_TREE(ENUM) \
1046 built_in_attributes[(int) ENUM] = NULL_TREE;
1047 # define DEF_ATTR_INT(ENUM, VALUE) \
1048 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
1049 #define DEF_ATTR_STRING(ENUM, VALUE) \
1050 built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
1051 #define DEF_ATTR_IDENT(ENUM, STRING) \
1052 built_in_attributes[(int) ENUM] = get_identifier (STRING);
1053 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
1054 built_in_attributes[(int) ENUM] \
1055 = tree_cons (built_in_attributes[(int) PURPOSE], \
1056 built_in_attributes[(int) VALUE], \
1057 built_in_attributes[(int) CHAIN]);
1058 #include "builtin-attrs.def"
1059 #undef DEF_ATTR_NULL_TREE
1061 #undef DEF_ATTR_STRING
1062 #undef DEF_ATTR_IDENT
1063 #undef DEF_ATTR_TREE_LIST
1066 /* Builtin types. */
1070 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
1071 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
1072 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
1073 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
1074 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
1075 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
1076 #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
1077 #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1079 #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1081 #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1082 ARG6, ARG7, ARG8) NAME,
1083 #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1084 ARG6, ARG7, ARG8, ARG9) NAME,
1085 #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1086 ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
1087 #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1088 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
1089 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
1090 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
1091 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
1092 #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
1093 #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
1094 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1096 #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1098 #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1100 #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1101 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
1102 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
1103 #include "builtin-types.def"
1104 #undef DEF_PRIMITIVE_TYPE
1105 #undef DEF_FUNCTION_TYPE_0
1106 #undef DEF_FUNCTION_TYPE_1
1107 #undef DEF_FUNCTION_TYPE_2
1108 #undef DEF_FUNCTION_TYPE_3
1109 #undef DEF_FUNCTION_TYPE_4
1110 #undef DEF_FUNCTION_TYPE_5
1111 #undef DEF_FUNCTION_TYPE_6
1112 #undef DEF_FUNCTION_TYPE_7
1113 #undef DEF_FUNCTION_TYPE_8
1114 #undef DEF_FUNCTION_TYPE_9
1115 #undef DEF_FUNCTION_TYPE_10
1116 #undef DEF_FUNCTION_TYPE_11
1117 #undef DEF_FUNCTION_TYPE_VAR_0
1118 #undef DEF_FUNCTION_TYPE_VAR_1
1119 #undef DEF_FUNCTION_TYPE_VAR_2
1120 #undef DEF_FUNCTION_TYPE_VAR_3
1121 #undef DEF_FUNCTION_TYPE_VAR_4
1122 #undef DEF_FUNCTION_TYPE_VAR_5
1123 #undef DEF_FUNCTION_TYPE_VAR_6
1124 #undef DEF_FUNCTION_TYPE_VAR_7
1125 #undef DEF_FUNCTION_TYPE_VAR_11
1126 #undef DEF_POINTER_TYPE
1130 typedef enum d_builtin_type builtin_type
;
1132 /* A temporary array used in communication with def_fn_type. */
1133 static GTY(()) tree builtin_types
[(int) BT_LAST
+ 1];
1135 /* A helper function for d_init_builtins. Build function type for DEF with
1136 return type RET and N arguments. If VAR is true, then the function should
1137 be variadic after those N arguments.
1139 Takes special care not to ICE if any of the types involved are
1140 error_mark_node, which indicates that said type is not in fact available
1141 (see builtin_type_for_size). In which case the function type as a whole
1142 should be error_mark_node. */
1145 def_fn_type (builtin_type def
, builtin_type ret
, bool var
, int n
, ...)
1148 tree
*args
= XALLOCAVEC (tree
, n
);
1153 for (i
= 0; i
< n
; ++i
)
1155 builtin_type a
= (builtin_type
) va_arg (list
, int);
1156 t
= builtin_types
[a
];
1157 if (t
== error_mark_node
)
1162 t
= builtin_types
[ret
];
1163 if (t
== error_mark_node
)
1166 t
= build_varargs_function_type_array (t
, n
, args
);
1168 t
= build_function_type_array (t
, n
, args
);
1171 builtin_types
[def
] = t
;
1175 /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
1176 VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
1179 d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED
,
1180 tree va_list_arg_type_node ATTRIBUTE_UNUSED
)
1182 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
1183 builtin_types[(int) ENUM] = VALUE;
1184 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
1185 def_fn_type (ENUM, RETURN, 0, 0);
1186 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
1187 def_fn_type (ENUM, RETURN, 0, 1, ARG1);
1188 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
1189 def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
1190 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1191 def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
1192 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1193 def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
1194 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1195 def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1196 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1198 def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1199 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1201 def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1202 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1204 def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1206 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1207 ARG6, ARG7, ARG8, ARG9) \
1208 def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1210 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1211 ARG6, ARG7, ARG8, ARG9, ARG10) \
1212 def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1213 ARG7, ARG8, ARG9, ARG10);
1214 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1215 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1216 def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1217 ARG7, ARG8, ARG9, ARG10, ARG11);
1218 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
1219 def_fn_type (ENUM, RETURN, 1, 0);
1220 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
1221 def_fn_type (ENUM, RETURN, 1, 1, ARG1);
1222 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
1223 def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
1224 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1225 def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
1226 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1227 def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
1228 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1229 def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1230 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1232 def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1233 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1235 def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1236 #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1237 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1238 def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1239 ARG7, ARG8, ARG9, ARG10, ARG11);
1240 #define DEF_POINTER_TYPE(ENUM, TYPE) \
1241 builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
1243 #include "builtin-types.def"
1245 #undef DEF_PRIMITIVE_TYPE
1246 #undef DEF_FUNCTION_TYPE_1
1247 #undef DEF_FUNCTION_TYPE_2
1248 #undef DEF_FUNCTION_TYPE_3
1249 #undef DEF_FUNCTION_TYPE_4
1250 #undef DEF_FUNCTION_TYPE_5
1251 #undef DEF_FUNCTION_TYPE_6
1252 #undef DEF_FUNCTION_TYPE_7
1253 #undef DEF_FUNCTION_TYPE_8
1254 #undef DEF_FUNCTION_TYPE_9
1255 #undef DEF_FUNCTION_TYPE_10
1256 #undef DEF_FUNCTION_TYPE_11
1257 #undef DEF_FUNCTION_TYPE_VAR_0
1258 #undef DEF_FUNCTION_TYPE_VAR_1
1259 #undef DEF_FUNCTION_TYPE_VAR_2
1260 #undef DEF_FUNCTION_TYPE_VAR_3
1261 #undef DEF_FUNCTION_TYPE_VAR_4
1262 #undef DEF_FUNCTION_TYPE_VAR_5
1263 #undef DEF_FUNCTION_TYPE_VAR_6
1264 #undef DEF_FUNCTION_TYPE_VAR_7
1265 #undef DEF_FUNCTION_TYPE_VAR_11
1266 #undef DEF_POINTER_TYPE
1267 builtin_types
[(int) BT_LAST
] = NULL_TREE
;
1269 d_init_attributes ();
1271 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
1272 NONANSI_P, ATTRS, IMPLICIT, COND) \
1274 do_build_builtin_fn (ENUM, NAME, CLASS, \
1275 builtin_types[(int) TYPE], \
1276 BOTH_P, FALLBACK_P, \
1277 built_in_attributes[(int) ATTRS], IMPLICIT);
1278 #include "builtins.def"
1282 /* Build builtin functions and types for the D language frontend. */
1285 d_init_builtins (void)
1287 d_build_c_type_nodes ();
1288 d_build_d_type_nodes ();
1290 if (TREE_CODE (va_list_type_node
) == ARRAY_TYPE
)
1292 /* It might seem natural to make the argument type a pointer, but there
1293 is no implicit casting from arrays to pointers in D. */
1294 d_define_builtins (va_list_type_node
, va_list_type_node
);
1298 d_define_builtins (build_reference_type (va_list_type_node
),
1302 targetm
.init_builtins ();
1303 build_common_builtin_nodes ();
1306 /* Registration of machine- or os-specific builtin types.
1307 Add to builtin types list for maybe processing later
1308 if `gcc.builtins' was imported into the current module. */
1311 d_register_builtin_type (tree type
, const char *name
)
1313 tree decl
= build_decl (UNKNOWN_LOCATION
, TYPE_DECL
,
1314 get_identifier (name
), type
);
1315 DECL_ARTIFICIAL (decl
) = 1;
1317 if (!TYPE_NAME (type
))
1318 TYPE_NAME (type
) = decl
;
1320 vec_safe_push (gcc_builtins_types
, decl
);
1323 /* Add DECL to builtin functions list for maybe processing later
1324 if `gcc.builtins' was imported into the current module. */
1327 d_builtin_function (tree decl
)
1329 if (!flag_no_builtin
&& DECL_ASSEMBLER_NAME_SET_P (decl
))
1331 /* Associate the assembler identifier with the built-in. */
1332 tree ident
= DECL_ASSEMBLER_NAME (decl
);
1333 IDENTIFIER_DECL_TREE (ident
) = decl
;
1336 vec_safe_push (gcc_builtins_functions
, decl
);
1340 /* Same as d_builtin_function, but used to delay putting in back-end builtin
1341 functions until the ISA that defines the builtin has been declared.
1342 However in D, there is no global namespace. All builtins get pushed into the
1343 `gcc.builtins' module, which is constructed during the semantic analysis
1344 pass, which has already finished by the time target attributes are evaluated.
1345 So builtins are not pushed because they would be ultimately ignored.
1346 The purpose of having this function then is to improve compile-time
1347 reflection support to allow user-code to determine whether a given back end
1348 function is enabled by the ISA. */
1351 d_builtin_function_ext_scope (tree decl
)
1356 #include "gt-d-d-builtins.h"