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