1/* typeinfo.cc -- D runtime type identification. 2 Copyright (C) 2013-2020 Free Software Foundation, Inc. 3 4GCC is free software; you can redistribute it and/or modify 5it under the terms of the GNU General Public License as published by 6the Free Software Foundation; either version 3, or (at your option) 7any later version. 8 9GCC is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12GNU General Public License for more details. 13 14You should have received a copy of the GNU General Public License 15along with GCC; see the file COPYING3. If not see 16<http://www.gnu.org/licenses/>. */ 17 18#include "config.h" 19#include "system.h" 20#include "coretypes.h" 21 22#include "dmd/aggregate.h" 23#include "dmd/enum.h" 24#include "dmd/errors.h" 25#include "dmd/expression.h" 26#include "dmd/globals.h" 27#include "dmd/identifier.h" 28#include "dmd/module.h" 29#include "dmd/mtype.h" 30#include "dmd/scope.h" 31#include "dmd/template.h" 32#include "dmd/target.h" 33 34#include "tree.h" 35#include "fold-const.h" 36#include "diagnostic.h" 37#include "stringpool.h" 38#include "toplev.h" 39#include "stor-layout.h" 40 41#include "d-tree.h" 42#include "d-target.h" 43 44 45/* D returns type information to the user as TypeInfo class objects, and can 46 be retrieved for any type using `typeid()'. We also use type information 47 to implement many runtime library helpers, including `new', `delete', most 48 dynamic array operations, and all associative array operations. 49 50 Type information for a particular type is indicated with an ABI defined 51 structure derived from TypeInfo. This would all be very straight forward, 52 but for the fact that the runtime library provides the definitions of the 53 TypeInfo structure and the ABI defined derived classes in `object.d', as 54 well as having specific implementations of TypeInfo for built-in types 55 in `rt/typeinfo`. We cannot build declarations of these directly in the 56 compiler, but we need to layout objects of their type. 57 58 To get around this, we define layout compatible POD-structs and generate the 59 appropriate initializations for them. When we have to provide a TypeInfo to 60 the user, we cast the internal compiler type to TypeInfo. 61 62 It is only required that TypeInfo has a definition in `object.d'. It could 63 happen that we are generating a type information for a TypeInfo object that 64 has no declaration. We however only need the addresses of such incomplete 65 TypeInfo objects for static initialization. */ 66 67enum tinfo_kind 68{ 69 TK_TYPEINFO_TYPE, /* object.TypeInfo */ 70 TK_CLASSINFO_TYPE, /* object.TypeInfo_Class */ 71 TK_INTERFACE_TYPE, /* object.TypeInfo_Interface */ 72 TK_STRUCT_TYPE, /* object.TypeInfo_Struct */ 73 TK_POINTER_TYPE, /* object.TypeInfo_Pointer */ 74 TK_ARRAY_TYPE, /* object.TypeInfo_Array */ 75 TK_STATICARRAY_TYPE, /* object.TypeInfo_StaticArray */ 76 TK_ASSOCIATIVEARRAY_TYPE, /* object.TypeInfo_AssociativeArray */ 77 TK_VECTOR_TYPE, /* object.TypeInfo_Vector */ 78 TK_ENUMERAL_TYPE, /* object.TypeInfo_Enum */ 79 TK_FUNCTION_TYPE, /* object.TypeInfo_Function */ 80 TK_DELEGATE_TYPE, /* object.TypeInfo_Delegate */ 81 TK_TYPELIST_TYPE, /* object.TypeInfo_Tuple */ 82 TK_CONST_TYPE, /* object.TypeInfo_Const */ 83 TK_IMMUTABLE_TYPE, /* object.TypeInfo_Invariant */ 84 TK_SHARED_TYPE, /* object.TypeInfo_Shared */ 85 TK_INOUT_TYPE, /* object.TypeInfo_Inout */ 86 TK_CPPTI_TYPE, /* object.__cpp_type_info_ptr */ 87 TK_END 88}; 89 90/* An array of all internal TypeInfo derived types we need. 91 The TypeInfo and ClassInfo types are created early, the 92 remainder are generated as needed. */ 93 94static GTY(()) tree tinfo_types[TK_END]; 95 96/* Return the kind of TypeInfo used to describe TYPE. */ 97 98static tinfo_kind 99get_typeinfo_kind (Type *type) 100{ 101 /* Check head shared/const modifiers first. */ 102 if (type->isShared ()) 103 return TK_SHARED_TYPE; 104 else if (type->isConst ()) 105 return TK_CONST_TYPE; 106 else if (type->isImmutable ()) 107 return TK_IMMUTABLE_TYPE; 108 else if (type->isWild ()) 109 return TK_INOUT_TYPE; 110 111 switch (type->ty) 112 { 113 case Tpointer: 114 return TK_POINTER_TYPE; 115 116 case Tarray: 117 return TK_ARRAY_TYPE; 118 119 case Tsarray: 120 return TK_STATICARRAY_TYPE; 121 122 case Taarray: 123 return TK_ASSOCIATIVEARRAY_TYPE; 124 125 case Tstruct: 126 return TK_STRUCT_TYPE; 127 128 case Tvector: 129 return TK_VECTOR_TYPE; 130 131 case Tenum: 132 return TK_ENUMERAL_TYPE; 133 134 case Tfunction: 135 return TK_FUNCTION_TYPE; 136 137 case Tdelegate: 138 return TK_DELEGATE_TYPE; 139 140 case Ttuple: 141 return TK_TYPELIST_TYPE; 142 143 case Tclass: 144 if (((TypeClass *) type)->sym->isInterfaceDeclaration ()) 145 return TK_INTERFACE_TYPE; 146 else 147 return TK_CLASSINFO_TYPE; 148 149 default: 150 return TK_TYPEINFO_TYPE; 151 } 152} 153 154/* Generate the RECORD_TYPE containing the data layout of a TypeInfo derivative 155 as used by the runtime. This layout must be consistent with that defined in 156 the `object.d' module. */ 157 158static void 159make_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...) 160{ 161 va_list ap; 162 163 va_start (ap, ident); 164 165 /* First two fields are from the TypeInfo base class. 166 Note, finish_builtin_struct() expects these fields in reverse order. */ 167 tree fields = create_field_decl (ptr_type_node, NULL, 1, 1); 168 DECL_CHAIN (fields) = create_field_decl (vtbl_ptr_type_node, NULL, 1, 1); 169 170 /* Now add the derived fields. */ 171 tree field_type = va_arg (ap, tree); 172 while (field_type != NULL_TREE) 173 { 174 tree field = create_field_decl (field_type, NULL, 1, 1); 175 DECL_CHAIN (field) = fields; 176 fields = field; 177 field_type = va_arg (ap, tree); 178 } 179 180 /* Create the TypeInfo type. */ 181 tree type = make_node (RECORD_TYPE); 182 TYPE_ARTIFICIAL (type) = 1; 183 finish_builtin_struct (type, ident->toChars (), fields, NULL_TREE); 184 185 tinfo_types[tk] = type; 186 187 va_end (ap); 188} 189 190/* Reference to the `object` module, where all TypeInfo is defined. */ 191 192static Module *object_module; 193 194/* Helper for create_frontend_tinfo_types. Creates a typeinfo class 195 declaration incase one wasn't supplied by reading `object.d'. */ 196 197static void 198make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL) 199{ 200 if (!base) 201 base = Type::dtypeinfo; 202 203 gcc_assert (object_module); 204 205 /* Create object module in order to complete the semantic. */ 206 if (!object_module->_scope) 207 object_module->importAll (NULL); 208 209 /* Assignment of global typeinfo variables is managed by the ClassDeclaration 210 constructor, so only need to new the declaration here. */ 211 Loc loc = (object_module->md) ? object_module->md->loc : object_module->loc; 212 ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL, 213 true); 214 tinfo->parent = object_module; 215 tinfo->semantic (object_module->_scope); 216 tinfo->baseClass = base; 217 /* This is a compiler generated class, and shouldn't be mistaken for being 218 the type declared in the runtime library. */ 219 tinfo->storage_class |= STCtemp; 220} 221 222/* Make sure the required builtin types exist for generating the TypeInfo 223 variable definitions. */ 224 225void 226create_tinfo_types (Module *mod) 227{ 228 /* Build the internal TypeInfo and ClassInfo types. 229 See TypeInfoVisitor for documentation of field layout. */ 230 make_internal_typeinfo (TK_TYPEINFO_TYPE, Identifier::idPool ("TypeInfo"), 231 NULL); 232 233 make_internal_typeinfo (TK_CLASSINFO_TYPE, 234 Identifier::idPool ("TypeInfo_Class"), 235 array_type_node, array_type_node, array_type_node, 236 array_type_node, ptr_type_node, ptr_type_node, 237 ptr_type_node, d_uint_type, ptr_type_node, 238 array_type_node, ptr_type_node, ptr_type_node, NULL); 239 240 object_module = mod; 241} 242 243/* Same as create_tinfo_types, but builds all front-end TypeInfo variable 244 definitions. */ 245 246static void 247create_frontend_tinfo_types (void) 248{ 249 /* If there's no object module, then neither can there be TypeInfo. */ 250 if (object_module == NULL) 251 return; 252 253 /* Create all frontend TypeInfo classes declarations. We rely on all 254 existing, even if only just as stubs. */ 255 if (!Type::dtypeinfo) 256 make_frontend_typeinfo (Identifier::idPool ("TypeInfo"), 257 ClassDeclaration::object); 258 259 if (!Type::typeinfoclass) 260 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class")); 261 262 if (!Type::typeinfointerface) 263 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface")); 264 265 if (!Type::typeinfostruct) 266 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct")); 267 268 if (!Type::typeinfopointer) 269 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer")); 270 271 if (!Type::typeinfoarray) 272 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array")); 273 274 if (!Type::typeinfostaticarray) 275 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray")); 276 277 if (!Type::typeinfoassociativearray) 278 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray")); 279 280 if (!Type::typeinfoenum) 281 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum")); 282 283 if (!Type::typeinfofunction) 284 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function")); 285 286 if (!Type::typeinfodelegate) 287 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate")); 288 289 if (!Type::typeinfotypelist) 290 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple")); 291 292 if (!Type::typeinfoconst) 293 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const")); 294 295 if (!Type::typeinfoinvariant) 296 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"), 297 Type::typeinfoconst); 298 299 if (!Type::typeinfoshared) 300 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"), 301 Type::typeinfoconst); 302 303 if (!Type::typeinfowild) 304 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"), 305 Type::typeinfoconst); 306 307 if (!Type::typeinfovector) 308 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector")); 309 310 if (!ClassDeclaration::cpp_type_info_ptr) 311 make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"), 312 ClassDeclaration::object); 313} 314 315/* Return true if TypeInfo class TINFO is available in the runtime library. */ 316 317bool 318have_typeinfo_p (ClassDeclaration *tinfo) 319{ 320 /* Run-time typeinfo disabled on command line. */ 321 if (!global.params.useTypeInfo) 322 return false; 323 324 /* Can't layout TypeInfo if type is not declared, or is an opaque 325 declaration in the object module. */ 326 if (!tinfo || !tinfo->members) 327 return false; 328 329 /* Typeinfo is compiler-generated. */ 330 if (tinfo->storage_class & STCtemp) 331 return false; 332 333 return true; 334} 335 336/* Implements the visitor interface to build the TypeInfo layout of all 337 TypeInfoDeclaration AST classes emitted from the D Front-end. 338 All visit methods accept one parameter D, which holds the frontend AST 339 of the TypeInfo class. They also don't return any value, instead the 340 generated symbol is cached internally and returned from the caller. */ 341 342class TypeInfoVisitor : public Visitor 343{ 344 using Visitor::visit; 345 346 tree decl_; 347 vec<constructor_elt, va_gc> *init_; 348 349 /* Build an internal comdat symbol for the manifest constant VALUE, so that 350 its address can be taken. */ 351 352 tree internal_reference (tree value) 353 { 354 /* Use the typeinfo decl name as a prefix for the internal symbol. */ 355 const char *prefix = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (this->decl_)); 356 tree decl = build_artificial_decl (TREE_TYPE (value), value, prefix); 357 358 /* The internal pointer reference should be public, but not visible outside 359 the compilation unit. */ 360 DECL_EXTERNAL (decl) = 0; 361 TREE_PUBLIC (decl) = 1; 362 DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL; 363 d_comdat_linkage (decl); 364 d_pushdecl (decl); 365 366 return decl; 367 } 368 369 /* Add VALUE to the constructor values list. */ 370 371 void layout_field (tree value) 372 { 373 CONSTRUCTOR_APPEND_ELT (this->init_, NULL_TREE, value); 374 } 375 376 /* Write out STR as a static D string literal. */ 377 378 void layout_string (const char *str) 379 { 380 unsigned len = strlen (str); 381 tree value = build_string (len, str); 382 383 TREE_TYPE (value) = make_array_type (Type::tchar, len); 384 TREE_CONSTANT (value) = 1; 385 TREE_READONLY (value) = 1; 386 TREE_STATIC (value) = 1; 387 388 /* Taking the address, so assign the literal to a static var. */ 389 tree decl = this->internal_reference (value); 390 TREE_READONLY (decl) = 1; 391 392 value = d_array_value (build_ctype (Type::tchar->arrayOf ()), 393 size_int (len), build_address (decl)); 394 this->layout_field (value); 395 } 396 397 398 /* Write out the __vptr and __monitor fields of class CD. */ 399 400 void layout_base (ClassDeclaration *cd) 401 { 402 gcc_assert (cd != NULL); 403 404 if (have_typeinfo_p (cd)) 405 this->layout_field (build_address (get_vtable_decl (cd))); 406 else 407 this->layout_field (null_pointer_node); 408 409 this->layout_field (null_pointer_node); 410 } 411 412 /* Write out the interfaces field of class CD. 413 Returns the array of interfaces that the field is pointing to. */ 414 415 tree layout_interfaces (ClassDeclaration *cd) 416 { 417 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]); 418 tree csym = build_address (get_classinfo_decl (cd)); 419 420 /* Put out the offset to where vtblInterfaces are written. */ 421 tree value = d_array_value (array_type_node, 422 size_int (cd->vtblInterfaces->dim), 423 build_offset (csym, size_int (offset))); 424 this->layout_field (value); 425 426 /* Internally, the compiler sees Interface as: 427 void*[4] interface; 428 429 The run-time layout of Interface is: 430 TypeInfo_Class classinfo; 431 void*[] vtbl; 432 size_t offset; */ 433 vec<constructor_elt, va_gc> *elms = NULL; 434 435 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) 436 { 437 BaseClass *b = (*cd->vtblInterfaces)[i]; 438 ClassDeclaration *id = b->sym; 439 vec<constructor_elt, va_gc> *v = NULL; 440 441 /* Fill in the vtbl[]. */ 442 if (!cd->isInterfaceDeclaration ()) 443 b->fillVtbl (cd, &b->vtbl, 1); 444 445 /* ClassInfo for the interface. */ 446 value = build_address (get_classinfo_decl (id)); 447 CONSTRUCTOR_APPEND_ELT (v, size_int (0), value); 448 449 if (!cd->isInterfaceDeclaration ()) 450 { 451 /* The vtable of the interface length and ptr. */ 452 unsigned voffset = base_vtable_offset (cd, b); 453 gcc_assert (voffset != 0u); 454 value = build_offset (csym, size_int (voffset)); 455 456 CONSTRUCTOR_APPEND_ELT (v, size_int (1), size_int (id->vtbl.dim)); 457 CONSTRUCTOR_APPEND_ELT (v, size_int (2), value); 458 } 459 460 /* The 'this' offset. */ 461 CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset)); 462 463 /* Add to the array of interfaces. */ 464 value = build_constructor (vtbl_interface_type_node, v); 465 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); 466 } 467 468 tree domain = size_int (cd->vtblInterfaces->dim - 1); 469 tree arrtype = build_array_type (vtbl_interface_type_node, 470 build_index_type (domain)); 471 return build_constructor (arrtype, elms); 472 } 473 474 /* Write out the interfacing vtable[] of base class BCD that will be accessed 475 from the overriding class CD. If both are the same class, then this will 476 be its own vtable. INDEX is the offset in the interfaces array of the 477 base class where the Interface reference can be found. 478 This must be mirrored with base_vtable_offset(). */ 479 480 void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd, 481 size_t index) 482 { 483 BaseClass *bs = (*bcd->vtblInterfaces)[index]; 484 ClassDeclaration *id = bs->sym; 485 vec<constructor_elt, va_gc> *elms = NULL; 486 FuncDeclarations bvtbl; 487 488 if (id->vtbl.dim == 0 || base_vtable_offset (cd, bs) == ~0u) 489 return; 490 491 /* Fill bvtbl with the functions we want to put out. */ 492 if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0)) 493 return; 494 495 /* First entry is struct Interface reference. */ 496 if (id->vtblOffset ()) 497 { 498 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]); 499 offset += (index * int_size_in_bytes (vtbl_interface_type_node)); 500 tree value = build_offset (build_address (get_classinfo_decl (bcd)), 501 size_int (offset)); 502 CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value); 503 } 504 505 for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.dim; i++) 506 { 507 FuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i]; 508 if (fd != NULL) 509 { 510 tree value = build_address (make_thunk (fd, bs->offset)); 511 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value); 512 } 513 } 514 515 tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1)); 516 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain); 517 tree value = build_constructor (vtbltype, elms); 518 this->layout_field (value); 519 } 520 521 522public: 523 TypeInfoVisitor (tree decl) 524 { 525 this->decl_ = decl; 526 this->init_ = NULL; 527 } 528 529 /* Return the completed constructor for the TypeInfo record. */ 530 531 tree result (void) 532 { 533 return build_struct_literal (TREE_TYPE (this->decl_), this->init_); 534 } 535 536 /* Layout of TypeInfo is: 537 void **__vptr; 538 void *__monitor; */ 539 540 void visit (TypeInfoDeclaration *) 541 { 542 /* The vtable for TypeInfo. */ 543 this->layout_base (Type::dtypeinfo); 544 } 545 546 /* Layout of TypeInfo_Const is: 547 void **__vptr; 548 void *__monitor; 549 TypeInfo base; */ 550 551 void visit (TypeInfoConstDeclaration *d) 552 { 553 Type *tm = d->tinfo->mutableOf (); 554 tm = tm->merge2 (); 555 556 /* The vtable for TypeInfo_Const. */ 557 this->layout_base (Type::typeinfoconst); 558 559 /* TypeInfo for the mutable type. */ 560 this->layout_field (build_typeinfo (d->loc, tm)); 561 } 562 563 /* Layout of TypeInfo_Immutable is: 564 void **__vptr; 565 void *__monitor; 566 TypeInfo base; */ 567 568 void visit (TypeInfoInvariantDeclaration *d) 569 { 570 Type *tm = d->tinfo->mutableOf (); 571 tm = tm->merge2 (); 572 573 /* The vtable for TypeInfo_Invariant. */ 574 this->layout_base (Type::typeinfoinvariant); 575 576 /* TypeInfo for the mutable type. */ 577 this->layout_field (build_typeinfo (d->loc, tm)); 578 } 579 580 /* Layout of TypeInfo_Shared is: 581 void **__vptr; 582 void *__monitor; 583 TypeInfo base; */ 584 585 void visit (TypeInfoSharedDeclaration *d) 586 { 587 Type *tm = d->tinfo->unSharedOf (); 588 tm = tm->merge2 (); 589 590 /* The vtable for TypeInfo_Shared. */ 591 this->layout_base (Type::typeinfoshared); 592 593 /* TypeInfo for the unshared type. */ 594 this->layout_field (build_typeinfo (d->loc, tm)); 595 } 596 597 /* Layout of TypeInfo_Inout is: 598 void **__vptr; 599 void *__monitor; 600 TypeInfo base; */ 601 602 void visit (TypeInfoWildDeclaration *d) 603 { 604 Type *tm = d->tinfo->mutableOf (); 605 tm = tm->merge2 (); 606 607 /* The vtable for TypeInfo_Inout. */ 608 this->layout_base (Type::typeinfowild); 609 610 /* TypeInfo for the mutable type. */ 611 this->layout_field (build_typeinfo (d->loc, tm)); 612 } 613 614 /* Layout of TypeInfo_Enum is: 615 void **__vptr; 616 void *__monitor; 617 TypeInfo base; 618 string name; 619 void[] m_init; */ 620 621 void visit (TypeInfoEnumDeclaration *d) 622 { 623 gcc_assert (d->tinfo->ty == Tenum); 624 TypeEnum *ti = (TypeEnum *) d->tinfo; 625 EnumDeclaration *ed = ti->sym; 626 627 /* The vtable for TypeInfo_Enum. */ 628 this->layout_base (Type::typeinfoenum); 629 630 /* TypeInfo for enum members. */ 631 tree memtype = (ed->memtype) ? build_typeinfo (d->loc, ed->memtype) 632 : null_pointer_node; 633 this->layout_field (memtype); 634 635 /* Name of the enum declaration. */ 636 this->layout_string (ed->toPrettyChars ()); 637 638 /* Default initializer for enum. */ 639 if (ed->members && !d->tinfo->isZeroInit ()) 640 { 641 tree length = size_int (ed->type->size ()); 642 tree ptr = build_address (enum_initializer_decl (ed)); 643 this->layout_field (d_array_value (array_type_node, length, ptr)); 644 } 645 else 646 this->layout_field (null_array_node); 647 } 648 649 /* Layout of TypeInfo_Pointer is: 650 void **__vptr; 651 void *__monitor; 652 TypeInfo m_next; */ 653 654 void visit (TypeInfoPointerDeclaration *d) 655 { 656 gcc_assert (d->tinfo->ty == Tpointer); 657 TypePointer *ti = (TypePointer *) d->tinfo; 658 659 /* The vtable for TypeInfo_Pointer. */ 660 this->layout_base (Type::typeinfopointer); 661 662 /* TypeInfo for pointer-to type. */ 663 this->layout_field (build_typeinfo (d->loc, ti->next)); 664 } 665 666 /* Layout of TypeInfo_Array is: 667 void **__vptr; 668 void *__monitor; 669 TypeInfo value; */ 670 671 void visit (TypeInfoArrayDeclaration *d) 672 { 673 gcc_assert (d->tinfo->ty == Tarray); 674 TypeDArray *ti = (TypeDArray *) d->tinfo; 675 676 /* The vtable for TypeInfo_Array. */ 677 this->layout_base (Type::typeinfoarray); 678 679 /* TypeInfo for array of type. */ 680 this->layout_field (build_typeinfo (d->loc, ti->next)); 681 } 682 683 /* Layout of TypeInfo_StaticArray is: 684 void **__vptr; 685 void *__monitor; 686 TypeInfo value; 687 size_t len; */ 688 689 void visit (TypeInfoStaticArrayDeclaration *d) 690 { 691 gcc_assert (d->tinfo->ty == Tsarray); 692 TypeSArray *ti = (TypeSArray *) d->tinfo; 693 694 /* The vtable for TypeInfo_StaticArray. */ 695 this->layout_base (Type::typeinfostaticarray); 696 697 /* TypeInfo for array of type. */ 698 this->layout_field (build_typeinfo (d->loc, ti->next)); 699 700 /* Static array length. */ 701 this->layout_field (size_int (ti->dim->toInteger ())); 702 } 703 704 /* Layout of TypeInfo_AssociativeArray is: 705 void **__vptr; 706 void *__monitor; 707 TypeInfo value; 708 TypeInfo key; */ 709 710 void visit (TypeInfoAssociativeArrayDeclaration *d) 711 { 712 gcc_assert (d->tinfo->ty == Taarray); 713 TypeAArray *ti = (TypeAArray *) d->tinfo; 714 715 /* The vtable for TypeInfo_AssociativeArray. */ 716 this->layout_base (Type::typeinfoassociativearray); 717 718 /* TypeInfo for value of type. */ 719 this->layout_field (build_typeinfo (d->loc, ti->next)); 720 721 /* TypeInfo for index of type. */ 722 this->layout_field (build_typeinfo (d->loc, ti->index)); 723 } 724 725 /* Layout of TypeInfo_Vector is: 726 void **__vptr; 727 void *__monitor; 728 TypeInfo base; */ 729 730 void visit (TypeInfoVectorDeclaration *d) 731 { 732 gcc_assert (d->tinfo->ty == Tvector); 733 TypeVector *ti = (TypeVector *) d->tinfo; 734 735 /* The vtable for TypeInfo_Vector. */ 736 this->layout_base (Type::typeinfovector); 737 738 /* TypeInfo for equivalent static array. */ 739 this->layout_field (build_typeinfo (d->loc, ti->basetype)); 740 } 741 742 /* Layout of TypeInfo_Function is: 743 void **__vptr; 744 void *__monitor; 745 TypeInfo next; 746 string deco; */ 747 748 void visit (TypeInfoFunctionDeclaration *d) 749 { 750 gcc_assert (d->tinfo->ty == Tfunction && d->tinfo->deco != NULL); 751 TypeFunction *ti = (TypeFunction *) d->tinfo; 752 753 /* The vtable for TypeInfo_Function. */ 754 this->layout_base (Type::typeinfofunction); 755 756 /* TypeInfo for function return value. */ 757 this->layout_field (build_typeinfo (d->loc, ti->next)); 758 759 /* Mangled name of function declaration. */ 760 this->layout_string (d->tinfo->deco); 761 } 762 763 /* Layout of TypeInfo_Delegate is: 764 void **__vptr; 765 void *__monitor; 766 TypeInfo next; 767 string deco; */ 768 769 void visit (TypeInfoDelegateDeclaration *d) 770 { 771 gcc_assert (d->tinfo->ty == Tdelegate && d->tinfo->deco != NULL); 772 TypeDelegate *ti = (TypeDelegate *) d->tinfo; 773 774 /* The vtable for TypeInfo_Delegate. */ 775 this->layout_base (Type::typeinfodelegate); 776 777 /* TypeInfo for delegate return value. */ 778 this->layout_field (build_typeinfo (d->loc, ti->next)); 779 780 /* Mangled name of delegate declaration. */ 781 this->layout_string (d->tinfo->deco); 782 } 783 784 /* Layout of ClassInfo/TypeInfo_Class is: 785 void **__vptr; 786 void *__monitor; 787 byte[] m_init; 788 string name; 789 void*[] vtbl; 790 Interface[] interfaces; 791 TypeInfo_Class base; 792 void *destructor; 793 void function(Object) classInvariant; 794 ClassFlags m_flags; 795 void *deallocator; 796 OffsetTypeInfo[] m_offTi; 797 void function(Object) defaultConstructor; 798 immutable(void)* m_RTInfo; 799 800 Information relating to interfaces, and their vtables are laid out 801 immediately after the named fields, if there is anything to write. */ 802 803 void visit (TypeInfoClassDeclaration *d) 804 { 805 gcc_assert (d->tinfo->ty == Tclass); 806 TypeClass *ti = (TypeClass *) d->tinfo; 807 ClassDeclaration *cd = ti->sym; 808 809 /* The vtable for ClassInfo. */ 810 this->layout_base (Type::typeinfoclass); 811 812 if (!cd->members) 813 return; 814 815 tree interfaces = NULL_TREE; 816 817 if (!cd->isInterfaceDeclaration ()) 818 { 819 /* Default initializer for class. */ 820 tree init = aggregate_initializer_decl (cd); 821 tree value = d_array_value (array_type_node, size_int (cd->structsize), 822 build_address (init)); 823 this->layout_field (value); 824 825 /* Name of the class declaration. */ 826 const char *name = cd->ident->toChars (); 827 if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0)) 828 name = cd->toPrettyChars (); 829 this->layout_string (name); 830 831 /* The vtable of the class declaration. */ 832 value = d_array_value (array_type_node, size_int (cd->vtbl.dim), 833 build_address (get_vtable_decl (cd))); 834 this->layout_field (value); 835 836 /* Array of base interfaces that have their own vtable. */ 837 if (cd->vtblInterfaces->dim) 838 interfaces = this->layout_interfaces (cd); 839 else 840 this->layout_field (null_array_node); 841 842 /* TypeInfo_Class base; */ 843 tree base = (cd->baseClass) 844 ? build_address (get_classinfo_decl (cd->baseClass)) 845 : null_pointer_node; 846 this->layout_field (base); 847 848 /* void *destructor; */ 849 tree dtor = (cd->dtor) ? build_address (get_symbol_decl (cd->dtor)) 850 : null_pointer_node; 851 this->layout_field (dtor); 852 853 /* void function(Object) classInvariant; */ 854 tree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv)) 855 : null_pointer_node; 856 this->layout_field (inv); 857 858 /* ClassFlags m_flags; */ 859 ClassFlags::Type flags = ClassFlags::hasOffTi; 860 if (cd->isCOMclass ()) 861 flags |= ClassFlags::isCOMclass; 862 863 if (cd->isCPPclass ()) 864 flags |= ClassFlags::isCPPclass; 865 866 flags |= ClassFlags::hasGetMembers; 867 flags |= ClassFlags::hasTypeInfo; 868 869 if (cd->ctor) 870 flags |= ClassFlags::hasCtor; 871 872 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass) 873 { 874 if (bcd->dtor) 875 { 876 flags |= ClassFlags::hasDtor; 877 break; 878 } 879 } 880 881 if (cd->isAbstract ()) 882 flags |= ClassFlags::isAbstract; 883 884 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass) 885 { 886 if (!bcd->members) 887 continue; 888 889 for (size_t i = 0; i < bcd->members->dim; i++) 890 { 891 Dsymbol *sm = (*bcd->members)[i]; 892 if (sm->hasPointers ()) 893 goto Lhaspointers; 894 } 895 } 896 897 flags |= ClassFlags::noPointers; 898 899 Lhaspointers: 900 this->layout_field (build_integer_cst (flags, d_uint_type)); 901 902 /* void *deallocator; */ 903 tree ddtor = (cd->aggDelete) 904 ? build_address (get_symbol_decl (cd->aggDelete)) 905 : null_pointer_node; 906 this->layout_field (ddtor); 907 908 /* OffsetTypeInfo[] m_offTi; (not implemented) */ 909 this->layout_field (null_array_node); 910 911 /* void function(Object) defaultConstructor; */ 912 if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable)) 913 { 914 tree dctor = get_symbol_decl (cd->defaultCtor); 915 this->layout_field (build_address (dctor)); 916 } 917 else 918 this->layout_field (null_pointer_node); 919 920 /* immutable(void)* m_RTInfo; */ 921 if (cd->getRTInfo) 922 this->layout_field (build_expr (cd->getRTInfo, true)); 923 else if (!(flags & ClassFlags::noPointers)) 924 this->layout_field (size_one_node); 925 } 926 else 927 { 928 /* No initializer for interface. */ 929 this->layout_field (null_array_node); 930 931 /* Name of the interface declaration. */ 932 this->layout_string (cd->toPrettyChars ()); 933 934 /* No vtable for interface declaration. */ 935 this->layout_field (null_array_node); 936 937 /* Array of base interfaces that have their own vtable. */ 938 if (cd->vtblInterfaces->dim) 939 interfaces = this->layout_interfaces (cd); 940 else 941 this->layout_field (null_array_node); 942 943 /* TypeInfo_Class base; 944 void *destructor; 945 void function(Object) classInvariant; */ 946 this->layout_field (null_pointer_node); 947 this->layout_field (null_pointer_node); 948 this->layout_field (null_pointer_node); 949 950 /* ClassFlags m_flags; */ 951 ClassFlags::Type flags = ClassFlags::hasOffTi; 952 flags |= ClassFlags::hasTypeInfo; 953 if (cd->isCOMinterface ()) 954 flags |= ClassFlags::isCOMclass; 955 956 this->layout_field (build_integer_cst (flags, d_uint_type)); 957 958 /* void *deallocator; 959 OffsetTypeInfo[] m_offTi; (not implemented) 960 void function(Object) defaultConstructor; */ 961 this->layout_field (null_pointer_node); 962 this->layout_field (null_array_node); 963 this->layout_field (null_pointer_node); 964 965 /* immutable(void)* m_RTInfo; */ 966 if (cd->getRTInfo) 967 this->layout_field (build_expr (cd->getRTInfo, true)); 968 else 969 this->layout_field (null_pointer_node); 970 } 971 972 /* Put out array of Interfaces. */ 973 if (interfaces != NULL_TREE) 974 this->layout_field (interfaces); 975 976 if (!cd->isInterfaceDeclaration ()) 977 { 978 /* Put out this class' interface vtables[]. */ 979 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) 980 this->layout_base_vtable (cd, cd, i); 981 982 /* Put out the overriding interface vtables[]. */ 983 for (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass) 984 { 985 for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++) 986 this->layout_base_vtable (cd, bcd, i); 987 } 988 } 989 } 990 991 /* Layout of TypeInfo_Interface is: 992 void **__vptr; 993 void *__monitor; 994 TypeInfo_Class info; */ 995 996 void visit (TypeInfoInterfaceDeclaration *d) 997 { 998 gcc_assert (d->tinfo->ty == Tclass); 999 TypeClass *ti = (TypeClass *) d->tinfo; 1000 1001 if (!ti->sym->vclassinfo) 1002 ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti); 1003 1004 /* The vtable for TypeInfo_Interface. */ 1005 this->layout_base (Type::typeinfointerface); 1006 1007 /* TypeInfo for class inheriting the interface. */ 1008 tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo); 1009 this->layout_field (build_address (tidecl)); 1010 } 1011 1012 /* Layout of TypeInfo_Struct is: 1013 void **__vptr; 1014 void *__monitor; 1015 string name; 1016 void[] m_init; 1017 hash_t function(in void*) xtoHash; 1018 bool function(in void*, in void*) xopEquals; 1019 int function(in void*, in void*) xopCmp; 1020 string function(const(void)*) xtoString; 1021 StructFlags m_flags; 1022 void function(void*) xdtor; 1023 void function(void*) xpostblit; 1024 uint m_align; 1025 version (X86_64) 1026 TypeInfo m_arg1; 1027 TypeInfo m_arg2; 1028 immutable(void)* xgetRTInfo; */ 1029 1030 void visit (TypeInfoStructDeclaration *d) 1031 { 1032 gcc_assert (d->tinfo->ty == Tstruct); 1033 TypeStruct *ti = (TypeStruct *) d->tinfo; 1034 StructDeclaration *sd = ti->sym; 1035 1036 /* The vtable for TypeInfo_Struct. */ 1037 this->layout_base (Type::typeinfostruct); 1038 1039 if (!sd->members) 1040 return; 1041 1042 /* Name of the struct declaration. */ 1043 this->layout_string (sd->toPrettyChars ()); 1044 1045 /* Default initializer for struct. */ 1046 tree ptr = (sd->zeroInit) ? null_pointer_node 1047 : build_address (aggregate_initializer_decl (sd)); 1048 this->layout_field (d_array_value (array_type_node, 1049 size_int (sd->structsize), ptr)); 1050 1051 /* hash_t function (in void*) xtoHash; */ 1052 tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash)) 1053 : null_pointer_node; 1054 this->layout_field (xhash); 1055 1056 if (sd->xhash) 1057 { 1058 TypeFunction *tf = (TypeFunction *) sd->xhash->type; 1059 gcc_assert (tf->ty == Tfunction); 1060 if (!tf->isnothrow || tf->trust == TRUSTsystem) 1061 { 1062 warning (sd->xhash->loc, "toHash() must be declared as " 1063 "extern (D) size_t toHash() const nothrow @safe, " 1064 "not %s", tf->toChars ()); 1065 } 1066 } 1067 1068 /* bool function(in void*, in void*) xopEquals; */ 1069 tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq)) 1070 : null_pointer_node; 1071 this->layout_field (xeq); 1072 1073 /* int function(in void*, in void*) xopCmp; */ 1074 tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp)) 1075 : null_pointer_node; 1076 this->layout_field (xcmp); 1077 1078 /* string function(const(void)*) xtoString; */ 1079 FuncDeclaration *fdx = search_toString (sd); 1080 if (fdx) 1081 this->layout_field (build_address (get_symbol_decl (fdx))); 1082 else 1083 this->layout_field (null_pointer_node); 1084 1085 /* StructFlags m_flags; */ 1086 StructFlags::Type m_flags = 0; 1087 if (ti->hasPointers ()) 1088 m_flags |= StructFlags::hasPointers; 1089 this->layout_field (build_integer_cst (m_flags, d_uint_type)); 1090 1091 /* void function(void*) xdtor; */ 1092 tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor)) 1093 : null_pointer_node; 1094 this->layout_field (dtor); 1095 1096 /* void function(void*) xpostblit; */ 1097 if (sd->postblit && !(sd->postblit->storage_class & STCdisable)) 1098 this->layout_field (build_address (get_symbol_decl (sd->postblit))); 1099 else 1100 this->layout_field (null_pointer_node); 1101 1102 /* uint m_align; */ 1103 this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type)); 1104 1105 if (global.params.is64bit) 1106 { 1107 /* TypeInfo m_arg1; */ 1108 tree arg1type = (sd->arg1type) ? build_typeinfo (d->loc, sd->arg1type) 1109 : null_pointer_node; 1110 this->layout_field (arg1type); 1111 1112 /* TypeInfo m_arg2; */ 1113 tree arg2type = (sd->arg2type) ? build_typeinfo (d->loc, sd->arg2type) 1114 : null_pointer_node; 1115 this->layout_field (arg2type); 1116 } 1117 1118 /* immutable(void)* xgetRTInfo; */ 1119 if (sd->getRTInfo) 1120 this->layout_field (build_expr (sd->getRTInfo, true)); 1121 else if (m_flags & StructFlags::hasPointers) 1122 this->layout_field (size_one_node); 1123 } 1124 1125 /* Layout of TypeInfo_Tuple is: 1126 void **__vptr; 1127 void *__monitor; 1128 TypeInfo[] elements; */ 1129 1130 void visit (TypeInfoTupleDeclaration *d) 1131 { 1132 gcc_assert (d->tinfo->ty == Ttuple); 1133 TypeTuple *ti = (TypeTuple *) d->tinfo; 1134 1135 /* The vtable for TypeInfo_Tuple. */ 1136 this->layout_base (Type::typeinfotypelist); 1137 1138 /* TypeInfo[] elements; */ 1139 Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->dim); 1140 vec<constructor_elt, va_gc> *elms = NULL; 1141 for (size_t i = 0; i < ti->arguments->dim; i++) 1142 { 1143 Parameter *arg = (*ti->arguments)[i]; 1144 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), 1145 build_typeinfo (d->loc, arg->type)); 1146 } 1147 tree ctor = build_constructor (build_ctype (satype), elms); 1148 tree decl = this->internal_reference (ctor); 1149 1150 tree length = size_int (ti->arguments->dim); 1151 tree ptr = build_address (decl); 1152 this->layout_field (d_array_value (array_type_node, length, ptr)); 1153 1154 rest_of_decl_compilation (decl, 1, 0); 1155 } 1156}; 1157 1158 1159/* Main entry point for TypeInfoVisitor interface to generate 1160 TypeInfo constructor for the TypeInfoDeclaration AST class D. */ 1161 1162tree 1163layout_typeinfo (TypeInfoDeclaration *d) 1164{ 1165 if (!Type::dtypeinfo) 1166 create_frontend_tinfo_types (); 1167 1168 TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d)); 1169 d->accept (&v); 1170 return v.result (); 1171} 1172 1173/* Like layout_typeinfo, but generates the TypeInfo_Class for 1174 the class or interface declaration CD. */ 1175 1176tree 1177layout_classinfo (ClassDeclaration *cd) 1178{ 1179 if (!Type::dtypeinfo) 1180 create_frontend_tinfo_types (); 1181 1182 TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type); 1183 TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd)); 1184 d->accept (&v); 1185 return v.result (); 1186} 1187 1188/* Layout fields that immediately come after the classinfo type for DECL if 1189 there's any interfaces or interface vtables to be added. 1190 This must be mirrored with base_vtable_offset(). */ 1191 1192static tree 1193layout_classinfo_interfaces (ClassDeclaration *decl) 1194{ 1195 tree type = tinfo_types[TK_CLASSINFO_TYPE]; 1196 size_t structsize = int_size_in_bytes (type); 1197 1198 if (decl->vtblInterfaces->dim) 1199 { 1200 size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node); 1201 tree field; 1202 1203 type = copy_aggregate_type (type); 1204 1205 /* First layout the static array of Interface, which provides information 1206 about the vtables that follow. */ 1207 tree domain = size_int (decl->vtblInterfaces->dim - 1); 1208 tree arrtype = build_array_type (vtbl_interface_type_node, 1209 build_index_type (domain)); 1210 field = create_field_decl (arrtype, NULL, 1, 1); 1211 insert_aggregate_field (type, field, structsize); 1212 structsize += decl->vtblInterfaces->dim * interfacesize; 1213 1214 /* For each interface, layout each vtable. */ 1215 for (size_t i = 0; i < decl->vtblInterfaces->dim; i++) 1216 { 1217 BaseClass *b = (*decl->vtblInterfaces)[i]; 1218 ClassDeclaration *id = b->sym; 1219 unsigned offset = base_vtable_offset (decl, b); 1220 1221 if (id->vtbl.dim && offset != ~0u) 1222 { 1223 tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1)); 1224 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain); 1225 1226 field = create_field_decl (vtbltype, NULL, 1, 1); 1227 insert_aggregate_field (type, field, offset); 1228 structsize += id->vtbl.dim * Target::ptrsize; 1229 } 1230 } 1231 } 1232 1233 /* Layout the arrays of overriding interface vtables. */ 1234 for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass) 1235 { 1236 for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++) 1237 { 1238 BaseClass *b = (*bcd->vtblInterfaces)[i]; 1239 ClassDeclaration *id = b->sym; 1240 unsigned offset = base_vtable_offset (decl, b); 1241 1242 if (id->vtbl.dim && offset != ~0u) 1243 { 1244 if (type == tinfo_types[TK_CLASSINFO_TYPE]) 1245 type = copy_aggregate_type (type); 1246 1247 tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1)); 1248 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain); 1249 1250 tree field = create_field_decl (vtbltype, NULL, 1, 1); 1251 insert_aggregate_field (type, field, offset); 1252 structsize += id->vtbl.dim * Target::ptrsize; 1253 } 1254 } 1255 } 1256 1257 /* Update the type size and record mode for the classinfo type. */ 1258 if (type != tinfo_types[TK_CLASSINFO_TYPE]) 1259 finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type); 1260 1261 return type; 1262} 1263 1264/* Returns true if the TypeInfo for TYPE should be placed in 1265 the runtime library. */ 1266 1267static bool 1268builtin_typeinfo_p (Type *type) 1269{ 1270 if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull) 1271 return !type->mod; 1272 1273 if (type->ty == Tarray) 1274 { 1275 /* Strings are so common, make them builtin. */ 1276 Type *next = type->nextOf (); 1277 return !type->mod 1278 && ((next->isTypeBasic () != NULL && !next->mod) 1279 || (next->ty == Tchar && next->mod == MODimmutable) 1280 || (next->ty == Tchar && next->mod == MODconst)); 1281 } 1282 1283 return false; 1284} 1285 1286/* Implements a visitor interface to create the decl tree for TypeInfo decls. 1287 TypeInfo_Class objects differ in that they also have information about 1288 the class type packed immediately after the TypeInfo symbol. 1289 1290 If the frontend had an interface to allow distinguishing being these two 1291 AST types, then that would be better for us. */ 1292 1293class TypeInfoDeclVisitor : public Visitor 1294{ 1295 using Visitor::visit; 1296 1297public: 1298 TypeInfoDeclVisitor (void) 1299 { 1300 } 1301 1302 void visit (TypeInfoDeclaration *tid) 1303 { 1304 tree ident = get_identifier (tid->ident->toChars ()); 1305 tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)]; 1306 gcc_assert (type != NULL_TREE); 1307 1308 tid->csym = declare_extern_var (ident, type); 1309 DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid); 1310 1311 DECL_CONTEXT (tid->csym) = d_decl_context (tid); 1312 TREE_READONLY (tid->csym) = 1; 1313 1314 /* Built-in typeinfo will be referenced as one-only. */ 1315 gcc_assert (!tid->isInstantiated ()); 1316 1317 if (builtin_typeinfo_p (tid->tinfo)) 1318 d_linkonce_linkage (tid->csym); 1319 else 1320 d_comdat_linkage (tid->csym); 1321 } 1322 1323 void visit (TypeInfoClassDeclaration *tid) 1324 { 1325 gcc_assert (tid->tinfo->ty == Tclass); 1326 TypeClass *tc = (TypeClass *) tid->tinfo; 1327 tid->csym = get_classinfo_decl (tc->sym); 1328 } 1329}; 1330 1331/* Get the VAR_DECL of the TypeInfo for DECL. If this does not yet exist, 1332 create it. The TypeInfo decl provides information about the type of a given 1333 expression or object. */ 1334 1335tree 1336get_typeinfo_decl (TypeInfoDeclaration *decl) 1337{ 1338 if (decl->csym) 1339 return decl->csym; 1340 1341 gcc_assert (decl->tinfo->ty != Terror); 1342 1343 TypeInfoDeclVisitor v = TypeInfoDeclVisitor (); 1344 decl->accept (&v); 1345 gcc_assert (decl->csym != NULL_TREE); 1346 1347 return decl->csym; 1348} 1349 1350/* Get the VAR_DECL of the ClassInfo for DECL. If this does not yet exist, 1351 create it. The ClassInfo decl provides information about the dynamic type 1352 of a given class type or object. */ 1353 1354tree 1355get_classinfo_decl (ClassDeclaration *decl) 1356{ 1357 if (decl->csym) 1358 return decl->csym; 1359 1360 InterfaceDeclaration *id = decl->isInterfaceDeclaration (); 1361 tree ident = mangle_internal_decl (decl, id ? "__Interface" : "__Class", "Z"); 1362 tree type = layout_classinfo_interfaces (decl); 1363 1364 decl->csym = declare_extern_var (ident, type); 1365 DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL); 1366 1367 /* Class is a reference, want the record type. */ 1368 DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type)); 1369 /* ClassInfo cannot be const data, because we use the monitor on it. */ 1370 TREE_READONLY (decl->csym) = 0; 1371 1372 return decl->csym; 1373} 1374 1375/* Performs sanity checks on the `object.TypeInfo' type, raising an error if 1376 RTTI is disabled, or the type is missing. */ 1377 1378void 1379check_typeinfo_type (const Loc &loc, Scope *sc) 1380{ 1381 if (!global.params.useTypeInfo) 1382 { 1383 static int warned = 0; 1384 1385 /* Even when compiling without RTTI we should still be able to evaluate 1386 TypeInfo at compile-time, just not at run-time. */ 1387 if (!warned && (!sc || !(sc->flags & SCOPEctfe))) 1388 { 1389 error_at (make_location_t (loc), 1390 "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>"); 1391 warned = 1; 1392 } 1393 } 1394 1395 if (Type::dtypeinfo == NULL 1396 || (Type::dtypeinfo->storage_class & STCtemp)) 1397 { 1398 /* If TypeInfo has not been declared, warn about each location once. */ 1399 static Loc warnloc; 1400 1401 if (!warnloc.equals (loc)) 1402 { 1403 error_at (make_location_t (loc), 1404 "%<object.TypeInfo%> could not be found, " 1405 "but is implicitly used"); 1406 warnloc = loc; 1407 } 1408 } 1409} 1410 1411/* Returns typeinfo reference for TYPE. */ 1412 1413tree 1414build_typeinfo (const Loc &loc, Type *type) 1415{ 1416 gcc_assert (type->ty != Terror); 1417 check_typeinfo_type (loc, NULL); 1418 create_typeinfo (type, NULL); 1419 return build_address (get_typeinfo_decl (type->vtinfo)); 1420} 1421 1422/* Like layout_classinfo, but generates an Object that wraps around a 1423 pointer to C++ type_info so it can be distinguished from D TypeInfo. */ 1424 1425void 1426layout_cpp_typeinfo (ClassDeclaration *cd) 1427{ 1428 if (!Type::dtypeinfo) 1429 create_frontend_tinfo_types (); 1430 1431 gcc_assert (cd->isCPPclass ()); 1432 1433 tree decl = get_cpp_typeinfo_decl (cd); 1434 vec<constructor_elt, va_gc> *init = NULL; 1435 1436 /* Use the vtable of __cpp_type_info_ptr, the EH personality routine 1437 expects this, as it uses .classinfo identity comparison to test for 1438 C++ catch handlers. */ 1439 tree vptr = get_vtable_decl (ClassDeclaration::cpp_type_info_ptr); 1440 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr)); 1441 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node); 1442 1443 /* Let C++ do the RTTI generation, and just reference the symbol as 1444 extern, knowing the underlying type is not required. */ 1445 const char *ident = Target::cppTypeInfoMangle (cd); 1446 tree typeinfo = declare_extern_var (get_identifier (ident), 1447 unknown_type_node); 1448 TREE_READONLY (typeinfo) = 1; 1449 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo)); 1450 1451 /* Build the initializer and emit. */ 1452 DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init); 1453 DECL_EXTERNAL (decl) = 0; 1454 d_pushdecl (decl); 1455 rest_of_decl_compilation (decl, 1, 0); 1456} 1457 1458/* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet 1459 exist, create it. The __cpp_type_info_ptr decl is then initialized with a 1460 pointer to the C++ type_info for the given class. */ 1461 1462tree 1463get_cpp_typeinfo_decl (ClassDeclaration *decl) 1464{ 1465 gcc_assert (decl->isCPPclass ()); 1466 1467 if (decl->cpp_type_info_ptr_sym) 1468 return decl->cpp_type_info_ptr_sym; 1469 1470 if (!tinfo_types[TK_CPPTI_TYPE]) 1471 make_internal_typeinfo (TK_CPPTI_TYPE, 1472 Identifier::idPool ("__cpp_type_info_ptr"), 1473 ptr_type_node, NULL); 1474 1475 tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", ""); 1476 tree type = tinfo_types[TK_CPPTI_TYPE]; 1477 1478 decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type); 1479 DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL); 1480 1481 /* Class is a reference, want the record type. */ 1482 DECL_CONTEXT (decl->cpp_type_info_ptr_sym) 1483 = TREE_TYPE (build_ctype (decl->type)); 1484 TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1; 1485 1486 d_comdat_linkage (decl->cpp_type_info_ptr_sym); 1487 1488 /* Layout the initializer and emit the symbol. */ 1489 layout_cpp_typeinfo (decl); 1490 1491 return decl->cpp_type_info_ptr_sym; 1492} 1493 1494/* Get the exact TypeInfo for TYPE, if it doesn't exist, create it. */ 1495 1496void 1497create_typeinfo (Type *type, Module *mod) 1498{ 1499 if (!Type::dtypeinfo) 1500 create_frontend_tinfo_types (); 1501 1502 /* Do this since not all Type's are merged. */ 1503 Type *t = type->merge2 (); 1504 Identifier *ident; 1505 1506 if (!t->vtinfo) 1507 { 1508 tinfo_kind tk = get_typeinfo_kind (t); 1509 switch (tk) 1510 { 1511 case TK_SHARED_TYPE: 1512 case TK_CONST_TYPE: 1513 case TK_IMMUTABLE_TYPE: 1514 case TK_INOUT_TYPE: 1515 case TK_POINTER_TYPE: 1516 case TK_ARRAY_TYPE: 1517 case TK_VECTOR_TYPE: 1518 case TK_INTERFACE_TYPE: 1519 /* Kinds of TypeInfo that add one extra pointer field. */ 1520 if (tk == TK_SHARED_TYPE) 1521 { 1522 /* Does both 'shared' and 'shared const'. */ 1523 t->vtinfo = TypeInfoSharedDeclaration::create (t); 1524 ident = Identifier::idPool ("TypeInfo_Shared"); 1525 } 1526 else if (tk == TK_CONST_TYPE) 1527 { 1528 t->vtinfo = TypeInfoConstDeclaration::create (t); 1529 ident = Identifier::idPool ("TypeInfo_Const"); 1530 } 1531 else if (tk == TK_IMMUTABLE_TYPE) 1532 { 1533 t->vtinfo = TypeInfoInvariantDeclaration::create (t); 1534 ident = Identifier::idPool ("TypeInfo_Invariant"); 1535 } 1536 else if (tk == TK_INOUT_TYPE) 1537 { 1538 t->vtinfo = TypeInfoWildDeclaration::create (t); 1539 ident = Identifier::idPool ("TypeInfo_Wild"); 1540 } 1541 else if (tk == TK_POINTER_TYPE) 1542 { 1543 t->vtinfo = TypeInfoPointerDeclaration::create (t); 1544 ident = Identifier::idPool ("TypeInfo_Pointer"); 1545 } 1546 else if (tk == TK_ARRAY_TYPE) 1547 { 1548 t->vtinfo = TypeInfoArrayDeclaration::create (t); 1549 ident = Identifier::idPool ("TypeInfo_Array"); 1550 } 1551 else if (tk == TK_VECTOR_TYPE) 1552 { 1553 t->vtinfo = TypeInfoVectorDeclaration::create (t); 1554 ident = Identifier::idPool ("TypeInfo_Vector"); 1555 } 1556 else if (tk == TK_INTERFACE_TYPE) 1557 { 1558 t->vtinfo = TypeInfoInterfaceDeclaration::create (t); 1559 ident = Identifier::idPool ("TypeInfo_Interface"); 1560 } 1561 else 1562 gcc_unreachable (); 1563 1564 if (!tinfo_types[tk]) 1565 make_internal_typeinfo (tk, ident, ptr_type_node, NULL); 1566 break; 1567 1568 case TK_STATICARRAY_TYPE: 1569 if (!tinfo_types[tk]) 1570 { 1571 ident = Identifier::idPool ("TypeInfo_StaticArray"); 1572 make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node, 1573 NULL); 1574 } 1575 t->vtinfo = TypeInfoStaticArrayDeclaration::create (t); 1576 break; 1577 1578 case TK_ASSOCIATIVEARRAY_TYPE: 1579 if (!tinfo_types[tk]) 1580 { 1581 ident = Identifier::idPool ("TypeInfo_AssociativeArray"); 1582 make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node, 1583 NULL); 1584 } 1585 t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t); 1586 break; 1587 1588 case TK_STRUCT_TYPE: 1589 if (!tinfo_types[tk]) 1590 { 1591 /* Some ABIs add extra TypeInfo fields on the end. */ 1592 tree argtype = global.params.is64bit ? ptr_type_node : NULL_TREE; 1593 1594 ident = Identifier::idPool ("TypeInfo_Struct"); 1595 make_internal_typeinfo (tk, ident, 1596 array_type_node, array_type_node, 1597 ptr_type_node, ptr_type_node, 1598 ptr_type_node, ptr_type_node, 1599 d_uint_type, ptr_type_node, 1600 ptr_type_node, d_uint_type, 1601 ptr_type_node, argtype, argtype, NULL); 1602 } 1603 t->vtinfo = TypeInfoStructDeclaration::create (t); 1604 break; 1605 1606 case TK_ENUMERAL_TYPE: 1607 if (!tinfo_types[tk]) 1608 { 1609 ident = Identifier::idPool ("TypeInfo_Enum"); 1610 make_internal_typeinfo (tk, ident, 1611 ptr_type_node, array_type_node, 1612 array_type_node, NULL); 1613 } 1614 t->vtinfo = TypeInfoEnumDeclaration::create (t); 1615 break; 1616 1617 case TK_FUNCTION_TYPE: 1618 case TK_DELEGATE_TYPE: 1619 /* Functions and delegates share a common TypeInfo layout. */ 1620 if (tk == TK_FUNCTION_TYPE) 1621 { 1622 t->vtinfo = TypeInfoFunctionDeclaration::create (t); 1623 ident = Identifier::idPool ("TypeInfo_Function"); 1624 } 1625 else if (tk == TK_DELEGATE_TYPE) 1626 { 1627 t->vtinfo = TypeInfoDelegateDeclaration::create (t); 1628 ident = Identifier::idPool ("TypeInfo_Delegate"); 1629 } 1630 else 1631 gcc_unreachable (); 1632 1633 if (!tinfo_types[tk]) 1634 make_internal_typeinfo (tk, ident, ptr_type_node, 1635 array_type_node, NULL); 1636 break; 1637 1638 case TK_TYPELIST_TYPE: 1639 if (!tinfo_types[tk]) 1640 { 1641 ident = Identifier::idPool ("TypeInfo_Tuple"); 1642 make_internal_typeinfo (tk, ident, array_type_node, NULL); 1643 } 1644 t->vtinfo = TypeInfoTupleDeclaration::create (t); 1645 break; 1646 1647 case TK_CLASSINFO_TYPE: 1648 t->vtinfo = TypeInfoClassDeclaration::create (t); 1649 break; 1650 1651 default: 1652 t->vtinfo = TypeInfoDeclaration::create (t); 1653 } 1654 gcc_assert (t->vtinfo); 1655 1656 /* If this has a custom implementation in rt/typeinfo, then 1657 do not generate a COMDAT for it. */ 1658 if (!builtin_typeinfo_p (t)) 1659 { 1660 /* Find module that will go all the way to an object file. */ 1661 if (mod) 1662 mod->members->push (t->vtinfo); 1663 else 1664 build_decl_tree (t->vtinfo); 1665 } 1666 } 1667 /* Types aren't merged, but we can share the vtinfo's. */ 1668 if (!type->vtinfo) 1669 type->vtinfo = t->vtinfo; 1670 1671 gcc_assert (type->vtinfo != NULL); 1672} 1673 1674/* Implements a visitor interface to check whether a type is speculative. 1675 TypeInfo_Struct would reference the members of the struct it is representing 1676 (e.g: opEquals via xopEquals field), so if it's instantiated in speculative 1677 context, TypeInfo creation should also be stopped to avoid possible 1678 `unresolved symbol' linker errors. */ 1679 1680class SpeculativeTypeVisitor : public Visitor 1681{ 1682 using Visitor::visit; 1683 1684 bool result_; 1685 1686public: 1687 SpeculativeTypeVisitor (void) 1688 { 1689 this->result_ = false; 1690 } 1691 1692 bool result (void) 1693 { 1694 return this->result_; 1695 } 1696 1697 void visit (Type *t) 1698 { 1699 Type *tb = t->toBasetype (); 1700 if (tb != t) 1701 tb->accept (this); 1702 } 1703 1704 void visit (TypeNext *t) 1705 { 1706 if (t->next) 1707 t->next->accept (this); 1708 } 1709 1710 void visit (TypeBasic *) 1711 { 1712 } 1713 1714 void visit (TypeVector *t) 1715 { 1716 t->basetype->accept (this); 1717 } 1718 1719 void visit (TypeAArray *t) 1720 { 1721 t->index->accept (this); 1722 visit ((TypeNext *)t); 1723 } 1724 1725 void visit (TypeFunction *t) 1726 { 1727 visit ((TypeNext *)t); 1728 } 1729 1730 void visit (TypeStruct *t) 1731 { 1732 StructDeclaration *sd = t->sym; 1733 if (TemplateInstance *ti = sd->isInstantiated ()) 1734 { 1735 if (!ti->needsCodegen ()) 1736 { 1737 if (ti->minst || sd->requestTypeInfo) 1738 return; 1739 1740 this->result_ |= true; 1741 } 1742 } 1743 } 1744 1745 void visit (TypeClass *t) 1746 { 1747 ClassDeclaration *cd = t->sym; 1748 if (TemplateInstance *ti = cd->isInstantiated ()) 1749 { 1750 if (!ti->needsCodegen () && !ti->minst) 1751 { 1752 this->result_ |= true; 1753 } 1754 } 1755 } 1756 1757 void visit (TypeTuple *t) 1758 { 1759 if (!t->arguments) 1760 return; 1761 1762 for (size_t i = 0; i < t->arguments->dim; i++) 1763 { 1764 Type *tprm = (*t->arguments)[i]->type; 1765 if (tprm) 1766 tprm->accept (this); 1767 if (this->result_) 1768 return; 1769 } 1770 } 1771}; 1772 1773/* Return true if type was instantiated in a speculative context. */ 1774 1775bool 1776speculative_type_p (Type *t) 1777{ 1778 SpeculativeTypeVisitor v = SpeculativeTypeVisitor (); 1779 t->accept (&v); 1780 return v.result (); 1781} 1782 1783#include "gt-d-typeinfo.h" 1784