hppa: Always enable PIE on 64-bit target
[official-gcc.git] / gcc / d / typeinfo.cc
blobf671131413e4ed2753cc9d6b58d6e5e782b9d0bb
1 /* typeinfo.cc -- D runtime type identification.
2 Copyright (C) 2013-2024 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
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"
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"
41 #include "d-tree.h"
42 #include "d-frontend.h"
43 #include "d-target.h"
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.
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.
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.
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. */
68 enum tinfo_kind
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
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. */
95 static GTY(()) tree tinfo_types[TK_END];
97 /* Return the kind of TypeInfo used to describe TYPE. */
99 static tinfo_kind
100 get_typeinfo_kind (Type *type)
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;
112 switch (type->ty)
114 case TY::Tpointer:
115 return TK_POINTER_TYPE;
117 case TY::Tarray:
118 return TK_ARRAY_TYPE;
120 case TY::Tsarray:
121 return TK_STATICARRAY_TYPE;
123 case TY::Taarray:
124 return TK_ASSOCIATIVEARRAY_TYPE;
126 case TY::Tstruct:
127 return TK_STRUCT_TYPE;
129 case TY::Tvector:
130 return TK_VECTOR_TYPE;
132 case TY::Tenum:
133 return TK_ENUMERAL_TYPE;
135 case TY::Tfunction:
136 return TK_FUNCTION_TYPE;
138 case TY::Tdelegate:
139 return TK_DELEGATE_TYPE;
141 case TY::Ttuple:
142 return TK_TYPELIST_TYPE;
144 case TY::Tclass:
145 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
146 return TK_INTERFACE_TYPE;
147 else
148 return TK_CLASSINFO_TYPE;
150 default:
151 return TK_TYPEINFO_TYPE;
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. */
159 static void
160 make_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...)
162 va_list ap;
164 va_start (ap, ident);
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);
171 /* Now add the derived fields. */
172 tree field_type = va_arg (ap, tree);
173 while (field_type != NULL_TREE)
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);
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);
186 tinfo_types[tk] = type;
188 va_end (ap);
191 /* Reference to the `object` module, where all TypeInfo is defined. */
193 static Module *object_module;
195 /* Helper for create_frontend_tinfo_types. Creates a typeinfo class
196 declaration incase one wasn't supplied by reading `object.d'. */
198 static void
199 make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL)
201 if (!base)
202 base = Type::dtypeinfo;
204 gcc_assert (object_module);
206 /* Create object module in order to complete the semantic. */
207 if (!object_module->_scope)
208 object_module->importAll (NULL);
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)
215 if (!ClassDeclaration::object)
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;
225 base = ClassDeclaration::object;
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;
241 /* Make sure the required builtin types exist for generating the TypeInfo
242 variable definitions. */
244 void
245 create_tinfo_types (Module *mod)
247 /* Already generated internal types for the object module. */
248 if (object_module != NULL)
249 return;
251 /* Build the internal TypeInfo and ClassInfo types.
252 See TypeInfoVisitor for documentation of field layout. */
253 make_internal_typeinfo (TK_TYPEINFO_TYPE, Identifier::idPool ("TypeInfo"),
254 NULL);
256 make_internal_typeinfo (TK_CLASSINFO_TYPE,
257 Identifier::idPool ("TypeInfo_Class"),
258 array_type_node, array_type_node, array_type_node,
259 array_type_node, ptr_type_node, ptr_type_node,
260 ptr_type_node, d_uint_type, ptr_type_node,
261 array_type_node, ptr_type_node, ptr_type_node, NULL);
263 object_module = mod;
266 /* Same as create_tinfo_types, but builds all front-end TypeInfo variable
267 definitions. */
269 static void
270 create_frontend_tinfo_types (void)
272 /* If there's no object module, then neither can there be TypeInfo. */
273 if (object_module == NULL)
274 return;
276 /* Create all frontend TypeInfo classes declarations. We rely on all
277 existing, even if only just as stubs. */
278 if (!Type::dtypeinfo)
279 make_frontend_typeinfo (Identifier::idPool ("TypeInfo"),
280 ClassDeclaration::object);
282 if (!Type::typeinfoclass)
283 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class"));
285 if (!Type::typeinfointerface)
286 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface"));
288 if (!Type::typeinfostruct)
289 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct"));
291 if (!Type::typeinfopointer)
292 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer"));
294 if (!Type::typeinfoarray)
295 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array"));
297 if (!Type::typeinfostaticarray)
298 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray"));
300 if (!Type::typeinfoassociativearray)
301 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray"));
303 if (!Type::typeinfoenum)
304 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum"));
306 if (!Type::typeinfofunction)
307 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function"));
309 if (!Type::typeinfodelegate)
310 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate"));
312 if (!Type::typeinfotypelist)
313 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple"));
315 if (!Type::typeinfoconst)
316 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const"));
318 if (!Type::typeinfoinvariant)
319 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"),
320 Type::typeinfoconst);
322 if (!Type::typeinfoshared)
323 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"),
324 Type::typeinfoconst);
326 if (!Type::typeinfowild)
327 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"),
328 Type::typeinfoconst);
330 if (!Type::typeinfovector)
331 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector"));
333 if (!ClassDeclaration::cpp_type_info_ptr)
334 make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"),
335 ClassDeclaration::object);
338 /* Return true if TypeInfo class TINFO is available in the runtime library. */
340 bool
341 have_typeinfo_p (ClassDeclaration *tinfo)
343 /* Run-time typeinfo disabled on command line. */
344 if (!global.params.useTypeInfo)
345 return false;
347 /* Can't layout TypeInfo if type is not declared, or is an opaque
348 declaration in the object module. */
349 if (!tinfo || !tinfo->members)
350 return false;
352 /* Typeinfo is compiler-generated. */
353 if (tinfo->storage_class & STCtemp)
354 return false;
356 return true;
359 /* Implements the visitor interface to build the TypeInfo layout of all
360 TypeInfoDeclaration AST classes emitted from the D Front-end.
361 All visit methods accept one parameter D, which holds the frontend AST
362 of the TypeInfo class. They also don't return any value, instead the
363 generated symbol is cached internally and returned from the caller. */
365 class TypeInfoVisitor : public Visitor
367 using Visitor::visit;
369 tree decl_;
370 vec<constructor_elt, va_gc> *init_;
372 /* Build an internal comdat symbol for the manifest constant VALUE, so that
373 its address can be taken. */
375 tree internal_reference (tree value)
377 /* Use the typeinfo decl name as a prefix for the internal symbol. */
378 const char *prefix = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (this->decl_));
379 tree decl = build_artificial_decl (TREE_TYPE (value), value, prefix);
381 /* The internal pointer reference should be public, but not visible outside
382 the compilation unit. */
383 DECL_EXTERNAL (decl) = 0;
384 TREE_PUBLIC (decl) = 1;
385 DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
386 set_linkage_for_decl (decl);
387 d_pushdecl (decl);
389 return decl;
392 /* Add VALUE to the constructor values list. */
394 void layout_field (tree value)
396 CONSTRUCTOR_APPEND_ELT (this->init_, NULL_TREE, value);
399 /* Write out STR as a static D string literal. */
401 void layout_string (const char *str)
403 unsigned len = strlen (str);
404 tree value = build_string (len, str);
406 TREE_TYPE (value) = make_array_type (Type::tchar, len);
407 TREE_CONSTANT (value) = 1;
408 TREE_READONLY (value) = 1;
409 TREE_STATIC (value) = 1;
411 /* Taking the address, so assign the literal to a static var. */
412 tree decl = this->internal_reference (value);
413 TREE_READONLY (decl) = 1;
415 value = d_array_value (build_ctype (Type::tchar->arrayOf ()),
416 size_int (len), build_address (decl));
417 this->layout_field (value);
420 /* Write out the __vptr and optionally __monitor fields of class CD. */
422 void layout_base (ClassDeclaration *cd)
424 gcc_assert (cd != NULL);
426 if (have_typeinfo_p (cd))
427 this->layout_field (build_address (get_vtable_decl (cd)));
428 else
429 this->layout_field (null_pointer_node);
431 if (cd->hasMonitor ())
432 this->layout_field (null_pointer_node);
435 /* Write out the interfaces field of class CD.
436 Returns the array of interfaces that the field is pointing to. */
438 tree layout_interfaces (ClassDeclaration *cd)
440 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
441 tree csym = build_address (get_classinfo_decl (cd));
443 /* Put out the offset to where vtblInterfaces are written. */
444 tree value = d_array_value (array_type_node,
445 size_int (cd->vtblInterfaces->length),
446 build_offset (csym, size_int (offset)));
447 this->layout_field (value);
449 /* Internally, the compiler sees Interface as:
450 void*[4] interface;
452 The run-time layout of Interface is:
453 TypeInfo_Class classinfo;
454 void*[] vtbl;
455 size_t offset; */
456 vec<constructor_elt, va_gc> *elms = NULL;
458 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
460 BaseClass *b = (*cd->vtblInterfaces)[i];
461 ClassDeclaration *id = b->sym;
462 vec<constructor_elt, va_gc> *v = NULL;
464 /* Fill in the vtbl[]. */
465 if (!cd->isInterfaceDeclaration ())
466 b->fillVtbl (cd, &b->vtbl, 1);
468 /* ClassInfo for the interface. */
469 value = build_address (get_classinfo_decl (id));
470 CONSTRUCTOR_APPEND_ELT (v, size_int (0), value);
472 if (!cd->isInterfaceDeclaration ())
474 /* The vtable of the interface length and ptr. */
475 unsigned voffset = base_vtable_offset (cd, b);
476 gcc_assert (voffset != 0u);
477 value = build_offset (csym, size_int (voffset));
479 CONSTRUCTOR_APPEND_ELT (v, size_int (1),
480 size_int (id->vtbl.length));
481 CONSTRUCTOR_APPEND_ELT (v, size_int (2), value);
484 /* The `this' offset. */
485 CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));
487 /* Add to the array of interfaces. */
488 value = build_constructor (vtbl_interface_type_node, v);
489 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
492 tree domain = size_int (cd->vtblInterfaces->length - 1);
493 tree arrtype = build_array_type (vtbl_interface_type_node,
494 build_index_type (domain));
495 return build_constructor (arrtype, elms);
498 /* Write out the interfacing vtable[] of base class BCD that will be accessed
499 from the overriding class CD. If both are the same class, then this will
500 be its own vtable. INDEX is the offset in the interfaces array of the
501 base class where the Interface reference can be found.
502 This must be mirrored with base_vtable_offset(). */
504 void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd,
505 size_t index)
507 BaseClass *bs = (*bcd->vtblInterfaces)[index];
508 ClassDeclaration *id = bs->sym;
509 vec<constructor_elt, va_gc> *elms = NULL;
510 FuncDeclarations bvtbl;
512 if (id->vtbl.length == 0 || base_vtable_offset (cd, bs) == ~0u)
513 return;
515 /* Fill bvtbl with the functions we want to put out. */
516 if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0))
517 return;
519 /* First entry is struct Interface reference. */
520 if (id->vtblOffset ())
522 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
523 offset += (index * int_size_in_bytes (vtbl_interface_type_node));
524 tree value = build_offset (build_address (get_classinfo_decl (bcd)),
525 size_int (offset));
526 CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value);
529 for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.length; i++)
531 FuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i];
532 if (fd != NULL)
534 tree value = build_address (make_thunk (fd, bs->offset));
535 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
539 tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
540 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
541 tree value = build_constructor (vtbltype, elms);
542 this->layout_field (value);
546 public:
547 TypeInfoVisitor (tree decl)
549 this->decl_ = decl;
550 this->init_ = NULL;
553 /* Return the completed constructor for the TypeInfo record. */
555 tree result (void)
557 return build_struct_literal (TREE_TYPE (this->decl_), this->init_);
560 /* Layout of TypeInfo is:
561 void **__vptr;
562 void *__monitor; */
564 void visit (TypeInfoDeclaration *) final override
566 /* The vtable for TypeInfo. */
567 this->layout_base (Type::dtypeinfo);
570 /* Layout of TypeInfo_Const is:
571 void **__vptr;
572 void *__monitor;
573 TypeInfo base; */
575 void visit (TypeInfoConstDeclaration *d) final override
577 Type *tm = d->tinfo->mutableOf ();
578 tm = tm->merge2 ();
580 /* The vtable for TypeInfo_Const. */
581 this->layout_base (Type::typeinfoconst);
583 /* TypeInfo for the mutable type. */
584 this->layout_field (build_typeinfo (d->loc, tm));
587 /* Layout of TypeInfo_Immutable is:
588 void **__vptr;
589 void *__monitor;
590 TypeInfo base; */
592 void visit (TypeInfoInvariantDeclaration *d) final override
594 Type *tm = d->tinfo->mutableOf ();
595 tm = tm->merge2 ();
597 /* The vtable for TypeInfo_Invariant. */
598 this->layout_base (Type::typeinfoinvariant);
600 /* TypeInfo for the mutable type. */
601 this->layout_field (build_typeinfo (d->loc, tm));
604 /* Layout of TypeInfo_Shared is:
605 void **__vptr;
606 void *__monitor;
607 TypeInfo base; */
609 void visit (TypeInfoSharedDeclaration *d) final override
611 Type *tm = d->tinfo->unSharedOf ();
612 tm = tm->merge2 ();
614 /* The vtable for TypeInfo_Shared. */
615 this->layout_base (Type::typeinfoshared);
617 /* TypeInfo for the unshared type. */
618 this->layout_field (build_typeinfo (d->loc, tm));
621 /* Layout of TypeInfo_Inout is:
622 void **__vptr;
623 void *__monitor;
624 TypeInfo base; */
626 void visit (TypeInfoWildDeclaration *d) final override
628 Type *tm = d->tinfo->mutableOf ();
629 tm = tm->merge2 ();
631 /* The vtable for TypeInfo_Inout. */
632 this->layout_base (Type::typeinfowild);
634 /* TypeInfo for the mutable type. */
635 this->layout_field (build_typeinfo (d->loc, tm));
638 /* Layout of TypeInfo_Enum is:
639 void **__vptr;
640 void *__monitor;
641 TypeInfo base;
642 string name;
643 void[] m_init; */
645 void visit (TypeInfoEnumDeclaration *d) final override
647 TypeEnum *ti = d->tinfo->isTypeEnum ();
648 EnumDeclaration *ed = ti->sym;
650 /* The vtable for TypeInfo_Enum. */
651 this->layout_base (Type::typeinfoenum);
653 /* TypeInfo for enum members. */
654 tree memtype = (ed->memtype) ? build_typeinfo (d->loc, ed->memtype)
655 : null_pointer_node;
656 this->layout_field (memtype);
658 /* Name of the enum declaration. */
659 this->layout_string (ed->toPrettyChars ());
661 /* Default initializer for enum. */
662 if (ed->members && !d->tinfo->isZeroInit ())
664 tree length = size_int (ed->type->size ());
665 tree ptr = build_address (enum_initializer_decl (ed));
666 this->layout_field (d_array_value (array_type_node, length, ptr));
668 else
669 this->layout_field (null_array_node);
672 /* Layout of TypeInfo_Pointer is:
673 void **__vptr;
674 void *__monitor;
675 TypeInfo m_next; */
677 void visit (TypeInfoPointerDeclaration *d) final override
679 TypePointer *ti = d->tinfo->isTypePointer ();
681 /* The vtable for TypeInfo_Pointer. */
682 this->layout_base (Type::typeinfopointer);
684 /* TypeInfo for pointer-to type. */
685 this->layout_field (build_typeinfo (d->loc, ti->next));
688 /* Layout of TypeInfo_Array is:
689 void **__vptr;
690 void *__monitor;
691 TypeInfo value; */
693 void visit (TypeInfoArrayDeclaration *d) final override
695 TypeDArray *ti = d->tinfo->isTypeDArray ();
697 /* The vtable for TypeInfo_Array. */
698 this->layout_base (Type::typeinfoarray);
700 /* TypeInfo for array of type. */
701 this->layout_field (build_typeinfo (d->loc, ti->next));
704 /* Layout of TypeInfo_StaticArray is:
705 void **__vptr;
706 void *__monitor;
707 TypeInfo value;
708 size_t len; */
710 void visit (TypeInfoStaticArrayDeclaration *d) final override
712 TypeSArray *ti = d->tinfo->isTypeSArray ();
714 /* The vtable for TypeInfo_StaticArray. */
715 this->layout_base (Type::typeinfostaticarray);
717 /* TypeInfo for array of type. */
718 this->layout_field (build_typeinfo (d->loc, ti->next));
720 /* Static array length. */
721 this->layout_field (size_int (ti->dim->toInteger ()));
724 /* Layout of TypeInfo_AssociativeArray is:
725 void **__vptr;
726 void *__monitor;
727 TypeInfo value;
728 TypeInfo key; */
730 void visit (TypeInfoAssociativeArrayDeclaration *d) final override
732 TypeAArray *ti = d->tinfo->isTypeAArray ();
734 /* The vtable for TypeInfo_AssociativeArray. */
735 this->layout_base (Type::typeinfoassociativearray);
737 /* TypeInfo for value of type. */
738 this->layout_field (build_typeinfo (d->loc, ti->next));
740 /* TypeInfo for index of type. */
741 this->layout_field (build_typeinfo (d->loc, ti->index));
744 /* Layout of TypeInfo_Vector is:
745 void **__vptr;
746 void *__monitor;
747 TypeInfo base; */
749 void visit (TypeInfoVectorDeclaration *d) final override
751 TypeVector *ti = d->tinfo->isTypeVector ();
753 /* The vtable for TypeInfo_Vector. */
754 this->layout_base (Type::typeinfovector);
756 /* TypeInfo for equivalent static array. */
757 this->layout_field (build_typeinfo (d->loc, ti->basetype));
760 /* Layout of TypeInfo_Function is:
761 void **__vptr;
762 void *__monitor;
763 TypeInfo next;
764 string deco; */
766 void visit (TypeInfoFunctionDeclaration *d) final override
768 TypeFunction *ti = d->tinfo->isTypeFunction ();
769 gcc_assert (ti->deco != NULL);
771 /* The vtable for TypeInfo_Function. */
772 this->layout_base (Type::typeinfofunction);
774 /* TypeInfo for function return value. */
775 this->layout_field (build_typeinfo (d->loc, ti->next));
777 /* Mangled name of function declaration. */
778 this->layout_string (d->tinfo->deco);
781 /* Layout of TypeInfo_Delegate is:
782 void **__vptr;
783 void *__monitor;
784 TypeInfo next;
785 string deco; */
787 void visit (TypeInfoDelegateDeclaration *d) final override
789 TypeDelegate *ti = d->tinfo->isTypeDelegate ();
790 gcc_assert (ti->deco != NULL);
792 /* The vtable for TypeInfo_Delegate. */
793 this->layout_base (Type::typeinfodelegate);
795 /* TypeInfo for delegate return value. */
796 this->layout_field (build_typeinfo (d->loc, ti->next));
798 /* Mangled name of delegate declaration. */
799 this->layout_string (d->tinfo->deco);
802 /* Layout of ClassInfo/TypeInfo_Class is:
803 void **__vptr;
804 void *__monitor;
805 byte[] m_init;
806 string name;
807 void*[] vtbl;
808 Interface[] interfaces;
809 TypeInfo_Class base;
810 void *destructor;
811 void function(Object) classInvariant;
812 ClassFlags m_flags;
813 void *deallocator;
814 OffsetTypeInfo[] m_offTi;
815 void function(Object) defaultConstructor;
816 immutable(void)* m_RTInfo;
818 Information relating to interfaces, and their vtables are laid out
819 immediately after the named fields, if there is anything to write. */
821 void visit (TypeInfoClassDeclaration *d) final override
823 TypeClass *ti = d->tinfo->isTypeClass ();
824 ClassDeclaration *cd = ti->sym;
826 /* The vtable for ClassInfo. */
827 this->layout_base (Type::typeinfoclass);
829 if (!cd->members)
830 return;
832 tree interfaces = NULL_TREE;
834 if (!cd->isInterfaceDeclaration ())
836 /* Default initializer for class. */
837 tree init = aggregate_initializer_decl (cd);
838 tree value = d_array_value (array_type_node, size_int (cd->structsize),
839 build_address (init));
840 this->layout_field (value);
842 /* Name of the class declaration. */
843 const char *name = cd->ident->toChars ();
844 if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0))
845 name = cd->toPrettyChars (true);
846 this->layout_string (name);
848 /* The vtable of the class declaration. */
849 value = d_array_value (array_type_node, size_int (cd->vtbl.length),
850 build_address (get_vtable_decl (cd)));
851 this->layout_field (value);
853 /* Array of base interfaces that have their own vtable. */
854 if (cd->vtblInterfaces->length)
855 interfaces = this->layout_interfaces (cd);
856 else
857 this->layout_field (null_array_node);
859 /* TypeInfo_Class base; */
860 tree base = (cd->baseClass)
861 ? build_address (get_classinfo_decl (cd->baseClass))
862 : null_pointer_node;
863 this->layout_field (base);
865 /* void *destructor; */
866 tree dtor = (cd->tidtor) ? build_address (get_symbol_decl (cd->tidtor))
867 : null_pointer_node;
868 this->layout_field (dtor);
870 /* void function(Object) classInvariant; */
871 tree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv))
872 : null_pointer_node;
873 this->layout_field (inv);
875 /* ClassFlags m_flags; */
876 int flags = ClassFlags::hasOffTi;
877 if (cd->isCOMclass ())
878 flags |= ClassFlags::isCOMclass;
880 if (cd->isCPPclass ())
881 flags |= ClassFlags::isCPPclass;
883 flags |= ClassFlags::hasGetMembers;
884 flags |= ClassFlags::hasTypeInfo;
886 if (cd->ctor)
887 flags |= ClassFlags::hasCtor;
889 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
891 if (bcd->dtor)
893 flags |= ClassFlags::hasDtor;
894 break;
898 if (cd->isAbstract ())
899 flags |= ClassFlags::isAbstract;
901 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
903 if (!bcd->members)
904 continue;
906 for (size_t i = 0; i < bcd->members->length; i++)
908 Dsymbol *sm = (*bcd->members)[i];
909 if (sm->hasPointers ())
910 goto Lhaspointers;
914 flags |= ClassFlags::noPointers;
916 Lhaspointers:
917 this->layout_field (build_integer_cst (flags, d_uint_type));
919 /* void *deallocator; */
920 this->layout_field (null_pointer_node);
922 /* OffsetTypeInfo[] m_offTi; (not implemented) */
923 this->layout_field (null_array_node);
925 /* void function(Object) defaultConstructor; */
926 if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable))
928 tree dctor = get_symbol_decl (cd->defaultCtor);
929 this->layout_field (build_address (dctor));
931 else
932 this->layout_field (null_pointer_node);
934 /* immutable(void)* m_RTInfo; */
935 if (cd->getRTInfo)
936 this->layout_field (build_expr (cd->getRTInfo, true));
937 else if (!(flags & ClassFlags::noPointers))
938 this->layout_field (size_one_node);
939 else
940 this->layout_field (null_pointer_node);
942 else
944 /* No initializer for interface. */
945 this->layout_field (null_array_node);
947 /* Name of the interface declaration. */
948 this->layout_string (cd->toPrettyChars (true));
950 /* No vtable for interface declaration. */
951 this->layout_field (null_array_node);
953 /* Array of base interfaces that have their own vtable. */
954 if (cd->vtblInterfaces->length)
955 interfaces = this->layout_interfaces (cd);
956 else
957 this->layout_field (null_array_node);
959 /* TypeInfo_Class base;
960 void *destructor;
961 void function(Object) classInvariant; */
962 this->layout_field (null_pointer_node);
963 this->layout_field (null_pointer_node);
964 this->layout_field (null_pointer_node);
966 /* ClassFlags m_flags; */
967 int flags = ClassFlags::hasOffTi;
968 flags |= ClassFlags::hasTypeInfo;
969 if (cd->isCOMinterface ())
970 flags |= ClassFlags::isCOMclass;
972 this->layout_field (build_integer_cst (flags, d_uint_type));
974 /* void *deallocator;
975 OffsetTypeInfo[] m_offTi; (not implemented)
976 void function(Object) defaultConstructor; */
977 this->layout_field (null_pointer_node);
978 this->layout_field (null_array_node);
979 this->layout_field (null_pointer_node);
981 /* immutable(void)* m_RTInfo; */
982 if (cd->getRTInfo)
983 this->layout_field (build_expr (cd->getRTInfo, true));
984 else
985 this->layout_field (null_pointer_node);
988 /* Put out array of Interfaces. */
989 if (interfaces != NULL_TREE)
990 this->layout_field (interfaces);
992 if (!cd->isInterfaceDeclaration ())
994 /* Put out this class' interface vtables[]. */
995 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
996 this->layout_base_vtable (cd, cd, i);
998 /* Put out the overriding interface vtables[]. */
999 for (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass)
1001 for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
1002 this->layout_base_vtable (cd, bcd, i);
1007 /* Layout of TypeInfo_Interface is:
1008 void **__vptr;
1009 void *__monitor;
1010 TypeInfo_Class info; */
1012 void visit (TypeInfoInterfaceDeclaration *d) final override
1014 TypeClass *ti = d->tinfo->isTypeClass ();
1016 if (!ti->sym->vclassinfo)
1017 ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti);
1019 /* The vtable for TypeInfo_Interface. */
1020 this->layout_base (Type::typeinfointerface);
1022 /* TypeInfo for class inheriting the interface. */
1023 tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo);
1024 this->layout_field (build_address (tidecl));
1027 /* Layout of TypeInfo_Struct is:
1028 void **__vptr;
1029 void *__monitor;
1030 string mangledName;
1031 void[] m_init;
1032 hash_t function(in void*) xtoHash;
1033 bool function(in void*, in void*) xopEquals;
1034 int function(in void*, in void*) xopCmp;
1035 string function(const(void)*) xtoString;
1036 StructFlags m_flags;
1037 void function(void*) xdtor;
1038 void function(void*) xpostblit;
1039 uint m_align;
1040 immutable(void)* xgetRTInfo; */
1042 void visit (TypeInfoStructDeclaration *d) final override
1044 TypeStruct *ti = d->tinfo->isTypeStruct ();
1045 StructDeclaration *sd = ti->sym;
1047 /* The vtable for TypeInfo_Struct. */
1048 this->layout_base (Type::typeinfostruct);
1050 if (!sd->members)
1051 return;
1053 /* Mangled name of the struct declaration. */
1054 this->layout_string (ti->deco);
1056 /* Default initializer for struct. */
1057 tree ptr = (sd->zeroInit ()) ? null_pointer_node
1058 : build_address (aggregate_initializer_decl (sd));
1059 this->layout_field (d_array_value (array_type_node,
1060 size_int (sd->structsize), ptr));
1062 /* hash_t function (in void*) xtoHash; */
1063 tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash))
1064 : null_pointer_node;
1065 this->layout_field (xhash);
1067 /* bool function(in void*, in void*) xopEquals; */
1068 tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
1069 : null_pointer_node;
1070 this->layout_field (xeq);
1072 /* int function(in void*, in void*) xopCmp; */
1073 tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp))
1074 : null_pointer_node;
1075 this->layout_field (xcmp);
1077 /* string function(const(void)*) xtoString; */
1078 FuncDeclaration *fdx = search_toString (sd);
1079 if (fdx)
1080 this->layout_field (build_address (get_symbol_decl (fdx)));
1081 else
1082 this->layout_field (null_pointer_node);
1084 /* StructFlags m_flags; */
1085 int m_flags = StructFlags::none;
1086 if (ti->hasPointers ())
1087 m_flags |= StructFlags::hasPointers;
1088 this->layout_field (build_integer_cst (m_flags, d_uint_type));
1090 /* void function(void*) xdtor; */
1091 tree dtor = (sd->tidtor) ? build_address (get_symbol_decl (sd->tidtor))
1092 : null_pointer_node;
1093 this->layout_field (dtor);
1095 /* void function(void*) xpostblit; */
1096 if (sd->postblit && !(sd->postblit->storage_class & STCdisable))
1097 this->layout_field (build_address (get_symbol_decl (sd->postblit)));
1098 else
1099 this->layout_field (null_pointer_node);
1101 /* uint m_align; */
1102 this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type));
1104 /* immutable(void)* xgetRTInfo; */
1105 if (sd->getRTInfo)
1106 this->layout_field (build_expr (sd->getRTInfo, true));
1107 else if (m_flags & StructFlags::hasPointers)
1108 this->layout_field (size_one_node);
1111 /* Layout of TypeInfo_Tuple is:
1112 void **__vptr;
1113 void *__monitor;
1114 TypeInfo[] elements; */
1116 void visit (TypeInfoTupleDeclaration *d) final override
1118 TypeTuple *ti = d->tinfo->isTypeTuple ();
1120 /* The vtable for TypeInfo_Tuple. */
1121 this->layout_base (Type::typeinfotypelist);
1123 /* TypeInfo[] elements; */
1124 Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->length);
1125 vec<constructor_elt, va_gc> *elms = NULL;
1126 for (size_t i = 0; i < ti->arguments->length; i++)
1128 Parameter *arg = (*ti->arguments)[i];
1129 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1130 build_typeinfo (d->loc, arg->type));
1132 tree ctor = build_constructor (build_ctype (satype), elms);
1133 tree decl = this->internal_reference (ctor);
1135 tree length = size_int (ti->arguments->length);
1136 tree ptr = build_address (decl);
1137 this->layout_field (d_array_value (array_type_node, length, ptr));
1139 rest_of_decl_compilation (decl, 1, 0);
1144 /* Main entry point for TypeInfoVisitor interface to generate
1145 TypeInfo constructor for the TypeInfoDeclaration AST class D. */
1147 tree
1148 layout_typeinfo (TypeInfoDeclaration *d)
1150 if (!Type::dtypeinfo)
1151 create_frontend_tinfo_types ();
1153 TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d));
1154 d->accept (&v);
1155 return v.result ();
1158 /* Like layout_typeinfo, but generates the TypeInfo_Class for
1159 the class or interface declaration CD. */
1161 tree
1162 layout_classinfo (ClassDeclaration *cd)
1164 if (!Type::dtypeinfo)
1165 create_frontend_tinfo_types ();
1167 TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
1168 TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd));
1169 d->accept (&v);
1170 return v.result ();
1173 /* Get the offset to the BC's vtbl[] initializer from the start of CD.
1174 Returns "~0u" if the base class is not found in any vtable interfaces. */
1176 unsigned
1177 base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
1179 unsigned csymoffset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
1180 unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
1181 csymoffset += cd->vtblInterfaces->length * interfacesize;
1183 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
1185 BaseClass *b = (*cd->vtblInterfaces)[i];
1186 if (b == bc)
1187 return csymoffset;
1188 csymoffset += b->sym->vtbl.length * target.ptrsize;
1191 /* Check all overriding interface vtbl[]s. */
1192 for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)
1194 for (size_t k = 0; k < cd2->vtblInterfaces->length; k++)
1196 BaseClass *bs = (*cd2->vtblInterfaces)[k];
1197 if (bs->fillVtbl (cd, NULL, 0))
1199 if (bc == bs)
1200 return csymoffset;
1201 csymoffset += bs->sym->vtbl.length * target.ptrsize;
1206 return ~0u;
1209 /* Layout fields that immediately come after the classinfo type for DECL if
1210 there's any interfaces or interface vtables to be added.
1211 This must be mirrored with base_vtable_offset(). */
1213 static tree
1214 layout_classinfo_interfaces (ClassDeclaration *decl)
1216 tree type = tinfo_types[TK_CLASSINFO_TYPE];
1217 size_t structsize = int_size_in_bytes (type);
1219 if (decl->vtblInterfaces->length)
1221 size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node);
1222 tree field;
1224 type = copy_aggregate_type (type);
1226 /* First layout the static array of Interface, which provides information
1227 about the vtables that follow. */
1228 tree domain = size_int (decl->vtblInterfaces->length - 1);
1229 tree arrtype = build_array_type (vtbl_interface_type_node,
1230 build_index_type (domain));
1231 field = create_field_decl (arrtype, NULL, 1, 1);
1232 insert_aggregate_field (type, field, structsize);
1233 structsize += decl->vtblInterfaces->length * interfacesize;
1235 /* For each interface, layout each vtable. */
1236 for (size_t i = 0; i < decl->vtblInterfaces->length; i++)
1238 BaseClass *b = (*decl->vtblInterfaces)[i];
1239 ClassDeclaration *id = b->sym;
1240 unsigned offset = base_vtable_offset (decl, b);
1242 if (id->vtbl.length && offset != ~0u)
1244 tree vtbldomain
1245 = build_index_type (size_int (id->vtbl.length - 1));
1246 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1248 field = create_field_decl (vtbltype, NULL, 1, 1);
1249 insert_aggregate_field (type, field, offset);
1250 structsize += id->vtbl.length * target.ptrsize;
1255 /* Layout the arrays of overriding interface vtables. */
1256 for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass)
1258 for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
1260 BaseClass *b = (*bcd->vtblInterfaces)[i];
1261 ClassDeclaration *id = b->sym;
1262 unsigned offset = base_vtable_offset (decl, b);
1264 if (id->vtbl.length && offset != ~0u)
1266 if (type == tinfo_types[TK_CLASSINFO_TYPE])
1267 type = copy_aggregate_type (type);
1269 tree vtbldomain
1270 = build_index_type (size_int (id->vtbl.length - 1));
1271 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1273 tree field = create_field_decl (vtbltype, NULL, 1, 1);
1274 insert_aggregate_field (type, field, offset);
1275 structsize += id->vtbl.length * target.ptrsize;
1280 /* Update the type size and record mode for the classinfo type. */
1281 if (type != tinfo_types[TK_CLASSINFO_TYPE])
1282 finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type);
1284 return type;
1287 /* Returns true if the TypeInfo for TYPE should be placed in
1288 the runtime library. */
1290 static bool
1291 builtin_typeinfo_p (Type *type)
1293 if (type->isTypeBasic () || type->ty == TY::Tclass || type->ty == TY::Tnull)
1294 return !type->mod;
1296 if (type->ty == TY::Tarray)
1298 /* Strings are so common, make them builtin. */
1299 Type *next = type->nextOf ();
1300 return !type->mod
1301 && ((next->isTypeBasic () != NULL && !next->mod)
1302 || (next->ty == TY::Tchar && next->mod == MODimmutable)
1303 || (next->ty == TY::Tchar && next->mod == MODconst));
1306 return false;
1309 /* Implements a visitor interface to create the decl tree for TypeInfo decls.
1310 TypeInfo_Class objects differ in that they also have information about
1311 the class type packed immediately after the TypeInfo symbol.
1313 If the frontend had an interface to allow distinguishing being these two
1314 AST types, then that would be better for us. */
1316 class TypeInfoDeclVisitor : public Visitor
1318 using Visitor::visit;
1320 public:
1321 TypeInfoDeclVisitor (void)
1325 void visit (TypeInfoDeclaration *tid) final override
1327 tree ident = get_identifier (tid->ident->toChars ());
1328 tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)];
1329 gcc_assert (type != NULL_TREE);
1331 /* Built-in typeinfo will be referenced as one-only. */
1332 tid->csym = declare_extern_var (ident, type);
1333 DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid);
1335 DECL_CONTEXT (tid->csym) = d_decl_context (tid);
1336 TREE_READONLY (tid->csym) = 1;
1339 void visit (TypeInfoClassDeclaration *tid) final override
1341 TypeClass *tc = tid->tinfo->isTypeClass ();
1342 tid->csym = get_classinfo_decl (tc->sym);
1346 /* Get the VAR_DECL of the TypeInfo for DECL. If this does not yet exist,
1347 create it. The TypeInfo decl provides information about the type of a given
1348 expression or object. */
1350 tree
1351 get_typeinfo_decl (TypeInfoDeclaration *decl)
1353 if (decl->csym)
1354 return decl->csym;
1356 gcc_assert (decl->tinfo->ty != TY::Terror);
1358 TypeInfoDeclVisitor v = TypeInfoDeclVisitor ();
1359 decl->accept (&v);
1360 gcc_assert (decl->csym != NULL_TREE);
1362 return decl->csym;
1365 /* Get the VAR_DECL of the ClassInfo for DECL. If this does not yet exist,
1366 create it. The ClassInfo decl provides information about the dynamic type
1367 of a given class type or object. */
1369 tree
1370 get_classinfo_decl (ClassDeclaration *decl)
1372 if (decl->csym)
1373 return decl->csym;
1375 InterfaceDeclaration *id = decl->isInterfaceDeclaration ();
1376 tree ident = mangle_internal_decl (decl, id ? "__Interface" : "__Class", "Z");
1377 tree type = layout_classinfo_interfaces (decl);
1379 decl->csym = declare_extern_var (ident, type);
1380 DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);
1382 /* Class is a reference, want the record type. */
1383 DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type));
1384 /* ClassInfo cannot be const data, because we use the monitor on it. */
1385 TREE_READONLY (decl->csym) = 0;
1387 return decl->csym;
1390 /* Performs sanity checks on the `object.TypeInfo' type, raising an error if
1391 RTTI is disabled, or the type is missing. LOC is the location used for error
1392 messages. SC is the context, and EXPR is expression where TypeInfo is
1393 required from, if either are set. */
1395 void
1396 check_typeinfo_type (const Loc &loc, Scope *sc, Expression *expr)
1398 if (!global.params.useTypeInfo)
1400 /* Even when compiling without RTTI we should still be able to evaluate
1401 TypeInfo at compile-time, just not at run-time. */
1402 if (!sc || !(sc->flags & unsigned(SCOPE::ctfe)))
1404 static int warned = 0;
1406 if (expr != NULL)
1407 error_at (make_location_t (loc),
1408 "expression %qs requires %<object.TypeInfo%> and cannot "
1409 "be used with %<-fno-rtti%>", expr->toChars ());
1410 else if (!warned)
1411 error_at (make_location_t (loc),
1412 "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
1414 warned = 1;
1418 if (Type::dtypeinfo == NULL
1419 || (Type::dtypeinfo->storage_class & STCtemp))
1421 /* If TypeInfo has not been declared, warn about each location once. */
1422 static Loc warnloc;
1424 if (loc.filename () && !warnloc.equals (loc))
1426 error_at (make_location_t (loc),
1427 "%<object.TypeInfo%> could not be found, "
1428 "but is implicitly used");
1429 warnloc = loc;
1434 /* Returns typeinfo reference for TYPE. LOC is the location used for error
1435 messages. EXPR is the expression where TypeInfo is required, if set. */
1437 tree
1438 build_typeinfo (const Loc &loc, Type *type, Expression *expr)
1440 gcc_assert (type->ty != TY::Terror);
1441 check_typeinfo_type (loc, NULL, expr);
1442 create_typeinfo (type, NULL);
1443 return build_address (get_typeinfo_decl (type->vtinfo));
1446 tree build_typeinfo (Expression *expr, Type *type)
1448 return build_typeinfo (expr->loc, type, expr);
1451 /* Like layout_classinfo, but generates an Object that wraps around a
1452 pointer to C++ type_info so it can be distinguished from D TypeInfo. */
1454 void
1455 layout_cpp_typeinfo (ClassDeclaration *cd)
1457 if (!Type::dtypeinfo)
1458 create_frontend_tinfo_types ();
1460 gcc_assert (cd->isCPPclass ());
1462 tree decl = get_cpp_typeinfo_decl (cd);
1463 vec<constructor_elt, va_gc> *init = NULL;
1465 /* Use the vtable of __cpp_type_info_ptr, the EH personality routine
1466 expects this, as it uses .classinfo identity comparison to test for
1467 C++ catch handlers. */
1468 ClassDeclaration *cppti = ClassDeclaration::cpp_type_info_ptr;
1469 if (have_typeinfo_p (cppti))
1471 tree vptr = get_vtable_decl (cppti);
1472 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr));
1474 else
1475 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);
1477 if (cppti->hasMonitor ())
1478 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);
1480 /* Let C++ do the RTTI generation, and just reference the symbol as
1481 extern, knowing the underlying type is not required. */
1482 const char *ident = target.cpp.typeInfoMangle (cd);
1483 tree typeinfo = declare_extern_var (get_identifier (ident),
1484 unknown_type_node);
1485 TREE_READONLY (typeinfo) = 1;
1486 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo));
1488 /* Build the initializer and emit. */
1489 DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init);
1490 d_finish_decl (decl);
1493 /* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet
1494 exist, create it. The __cpp_type_info_ptr decl is then initialized with a
1495 pointer to the C++ type_info for the given class. */
1497 tree
1498 get_cpp_typeinfo_decl (ClassDeclaration *decl)
1500 gcc_assert (decl->isCPPclass ());
1502 if (decl->cpp_type_info_ptr_sym)
1503 return decl->cpp_type_info_ptr_sym;
1505 if (!tinfo_types[TK_CPPTI_TYPE])
1506 make_internal_typeinfo (TK_CPPTI_TYPE,
1507 Identifier::idPool ("__cpp_type_info_ptr"),
1508 ptr_type_node, NULL);
1510 tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", "");
1511 tree type = tinfo_types[TK_CPPTI_TYPE];
1513 decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type);
1514 DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL);
1516 /* Class is a reference, want the record type. */
1517 DECL_CONTEXT (decl->cpp_type_info_ptr_sym)
1518 = TREE_TYPE (build_ctype (decl->type));
1519 TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;
1521 /* Layout the initializer and emit the symbol. */
1522 layout_cpp_typeinfo (decl);
1524 return decl->cpp_type_info_ptr_sym;
1527 /* Get the exact TypeInfo for TYPE, if it doesn't exist, create it.
1528 When GENERATE is true, push the TypeInfo as a member of MOD so that it will
1529 get code generation. */
1531 void
1532 create_typeinfo (Type *type, Module *mod, bool generate)
1534 if (!Type::dtypeinfo)
1535 create_frontend_tinfo_types ();
1537 /* Do this since not all Type's are merged. */
1538 Type *t = type->merge2 ();
1539 Identifier *ident;
1541 if (!t->vtinfo)
1543 tinfo_kind tk = get_typeinfo_kind (t);
1544 switch (tk)
1546 case TK_SHARED_TYPE:
1547 case TK_CONST_TYPE:
1548 case TK_IMMUTABLE_TYPE:
1549 case TK_INOUT_TYPE:
1550 case TK_POINTER_TYPE:
1551 case TK_ARRAY_TYPE:
1552 case TK_VECTOR_TYPE:
1553 case TK_INTERFACE_TYPE:
1554 /* Kinds of TypeInfo that add one extra pointer field. */
1555 if (tk == TK_SHARED_TYPE)
1557 /* Does both `shared' and `shared const'. */
1558 t->vtinfo = TypeInfoSharedDeclaration::create (t);
1559 ident = Identifier::idPool ("TypeInfo_Shared");
1561 else if (tk == TK_CONST_TYPE)
1563 t->vtinfo = TypeInfoConstDeclaration::create (t);
1564 ident = Identifier::idPool ("TypeInfo_Const");
1566 else if (tk == TK_IMMUTABLE_TYPE)
1568 t->vtinfo = TypeInfoInvariantDeclaration::create (t);
1569 ident = Identifier::idPool ("TypeInfo_Invariant");
1571 else if (tk == TK_INOUT_TYPE)
1573 t->vtinfo = TypeInfoWildDeclaration::create (t);
1574 ident = Identifier::idPool ("TypeInfo_Wild");
1576 else if (tk == TK_POINTER_TYPE)
1578 t->vtinfo = TypeInfoPointerDeclaration::create (t);
1579 ident = Identifier::idPool ("TypeInfo_Pointer");
1581 else if (tk == TK_ARRAY_TYPE)
1583 t->vtinfo = TypeInfoArrayDeclaration::create (t);
1584 ident = Identifier::idPool ("TypeInfo_Array");
1586 else if (tk == TK_VECTOR_TYPE)
1588 t->vtinfo = TypeInfoVectorDeclaration::create (t);
1589 ident = Identifier::idPool ("TypeInfo_Vector");
1591 else if (tk == TK_INTERFACE_TYPE)
1593 t->vtinfo = TypeInfoInterfaceDeclaration::create (t);
1594 ident = Identifier::idPool ("TypeInfo_Interface");
1596 else
1597 gcc_unreachable ();
1599 if (!tinfo_types[tk])
1600 make_internal_typeinfo (tk, ident, ptr_type_node, NULL);
1601 break;
1603 case TK_STATICARRAY_TYPE:
1604 if (!tinfo_types[tk])
1606 ident = Identifier::idPool ("TypeInfo_StaticArray");
1607 make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node,
1608 NULL);
1610 t->vtinfo = TypeInfoStaticArrayDeclaration::create (t);
1611 break;
1613 case TK_ASSOCIATIVEARRAY_TYPE:
1614 if (!tinfo_types[tk])
1616 ident = Identifier::idPool ("TypeInfo_AssociativeArray");
1617 make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node,
1618 NULL);
1620 t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t);
1621 break;
1623 case TK_STRUCT_TYPE:
1624 if (!tinfo_types[tk])
1626 ident = Identifier::idPool ("TypeInfo_Struct");
1627 make_internal_typeinfo (tk, ident,
1628 array_type_node, array_type_node,
1629 ptr_type_node, ptr_type_node,
1630 ptr_type_node, ptr_type_node,
1631 d_uint_type, ptr_type_node,
1632 ptr_type_node, d_uint_type,
1633 ptr_type_node, NULL);
1635 t->vtinfo = TypeInfoStructDeclaration::create (t);
1636 break;
1638 case TK_ENUMERAL_TYPE:
1639 if (!tinfo_types[tk])
1641 ident = Identifier::idPool ("TypeInfo_Enum");
1642 make_internal_typeinfo (tk, ident,
1643 ptr_type_node, array_type_node,
1644 array_type_node, NULL);
1646 t->vtinfo = TypeInfoEnumDeclaration::create (t);
1647 break;
1649 case TK_FUNCTION_TYPE:
1650 case TK_DELEGATE_TYPE:
1651 /* Functions and delegates share a common TypeInfo layout. */
1652 if (tk == TK_FUNCTION_TYPE)
1654 t->vtinfo = TypeInfoFunctionDeclaration::create (t);
1655 ident = Identifier::idPool ("TypeInfo_Function");
1657 else if (tk == TK_DELEGATE_TYPE)
1659 t->vtinfo = TypeInfoDelegateDeclaration::create (t);
1660 ident = Identifier::idPool ("TypeInfo_Delegate");
1662 else
1663 gcc_unreachable ();
1665 if (!tinfo_types[tk])
1666 make_internal_typeinfo (tk, ident, ptr_type_node,
1667 array_type_node, NULL);
1668 break;
1670 case TK_TYPELIST_TYPE:
1671 if (!tinfo_types[tk])
1673 ident = Identifier::idPool ("TypeInfo_Tuple");
1674 make_internal_typeinfo (tk, ident, array_type_node, NULL);
1676 t->vtinfo = TypeInfoTupleDeclaration::create (t);
1677 break;
1679 case TK_CLASSINFO_TYPE:
1680 t->vtinfo = TypeInfoClassDeclaration::create (t);
1681 break;
1683 default:
1684 t->vtinfo = TypeInfoDeclaration::create (t);
1686 gcc_assert (t->vtinfo);
1688 /* If this has a custom implementation in rt/typeinfo, then
1689 do not generate a COMDAT for it. */
1690 if (generate && !builtin_typeinfo_p (t))
1692 /* Find module that will go all the way to an object file. */
1693 if (mod)
1694 mod->members->push (t->vtinfo);
1695 else
1696 build_decl_tree (t->vtinfo);
1699 /* Types aren't merged, but we can share the vtinfo's. */
1700 if (!type->vtinfo)
1701 type->vtinfo = t->vtinfo;
1703 gcc_assert (type->vtinfo != NULL);
1706 /* Implements a visitor interface to check whether a type is speculative.
1707 TypeInfo_Struct would reference the members of the struct it is representing
1708 (e.g: opEquals via xopEquals field), so if it's instantiated in speculative
1709 context, TypeInfo creation should also be stopped to avoid possible
1710 `unresolved symbol' linker errors. */
1712 class SpeculativeTypeVisitor : public Visitor
1714 using Visitor::visit;
1716 bool result_;
1718 public:
1719 SpeculativeTypeVisitor (void)
1721 this->result_ = false;
1724 bool result (void)
1726 return this->result_;
1729 void visit (Type *t) final override
1731 Type *tb = t->toBasetype ();
1732 if (tb != t)
1733 tb->accept (this);
1736 void visit (TypeNext *t) final override
1738 if (t->next)
1739 t->next->accept (this);
1742 void visit (TypeBasic *) final override
1746 void visit (TypeVector *t) final override
1748 t->basetype->accept (this);
1751 void visit (TypeAArray *t) final override
1753 t->index->accept (this);
1754 visit ((TypeNext *) t);
1757 void visit (TypeFunction *t) final override
1759 visit ((TypeNext *) t);
1762 void visit (TypeStruct *t) final override
1764 StructDeclaration *sd = t->sym;
1765 if (TemplateInstance *ti = sd->isInstantiated ())
1767 if (!ti->needsCodegen ())
1769 if (ti->minst || sd->requestTypeInfo ())
1770 return;
1772 this->result_ |= true;
1777 void visit (TypeClass *t) final override
1779 ClassDeclaration *cd = t->sym;
1780 if (TemplateInstance *ti = cd->isInstantiated ())
1782 if (!ti->needsCodegen () && !ti->minst)
1784 this->result_ |= true;
1789 void visit (TypeTuple *t) final override
1791 if (!t->arguments)
1792 return;
1794 for (size_t i = 0; i < t->arguments->length; i++)
1796 Type *tprm = (*t->arguments)[i]->type;
1797 if (tprm)
1798 tprm->accept (this);
1799 if (this->result_)
1800 return;
1805 /* Return true if type was instantiated in a speculative context. */
1807 bool
1808 speculative_type_p (Type *t)
1810 SpeculativeTypeVisitor v = SpeculativeTypeVisitor ();
1811 t->accept (&v);
1812 return v.result ();
1815 #include "gt-d-typeinfo.h"