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