Move PREFERRED_DEBUGGING_TYPE define in pa64-hpux.h to pa.h
[official-gcc.git] / gcc / d / typeinfo.cc
blobfd8c746a307d51a40711739ecd85e4f336a4e8c1
1 /* typeinfo.cc -- D runtime type identification.
2 Copyright (C) 2013-2021 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-target.h"
45 /* D returns type information to the user as TypeInfo class objects, and can
46 be retrieved for any type using `typeid()'. We also use type information
47 to implement many runtime library helpers, including `new', `delete', most
48 dynamic array operations, and all associative array operations.
50 Type information for a particular type is indicated with an ABI defined
51 structure derived from TypeInfo. This would all be very straight forward,
52 but for the fact that the runtime library provides the definitions of the
53 TypeInfo structure and the ABI defined derived classes in `object.d', as
54 well as having specific implementations of TypeInfo for built-in types
55 in `rt/typeinfo`. We cannot build declarations of these directly in the
56 compiler, but we need to layout objects of their type.
58 To get around this, we define layout compatible POD-structs and generate the
59 appropriate initializations for them. When we have to provide a TypeInfo to
60 the user, we cast the internal compiler type to TypeInfo.
62 It is only required that TypeInfo has a definition in `object.d'. It could
63 happen that we are generating a type information for a TypeInfo object that
64 has no declaration. We however only need the addresses of such incomplete
65 TypeInfo objects for static initialization. */
67 enum tinfo_kind
69 TK_TYPEINFO_TYPE, /* object.TypeInfo */
70 TK_CLASSINFO_TYPE, /* object.TypeInfo_Class */
71 TK_INTERFACE_TYPE, /* object.TypeInfo_Interface */
72 TK_STRUCT_TYPE, /* object.TypeInfo_Struct */
73 TK_POINTER_TYPE, /* object.TypeInfo_Pointer */
74 TK_ARRAY_TYPE, /* object.TypeInfo_Array */
75 TK_STATICARRAY_TYPE, /* object.TypeInfo_StaticArray */
76 TK_ASSOCIATIVEARRAY_TYPE, /* object.TypeInfo_AssociativeArray */
77 TK_VECTOR_TYPE, /* object.TypeInfo_Vector */
78 TK_ENUMERAL_TYPE, /* object.TypeInfo_Enum */
79 TK_FUNCTION_TYPE, /* object.TypeInfo_Function */
80 TK_DELEGATE_TYPE, /* object.TypeInfo_Delegate */
81 TK_TYPELIST_TYPE, /* object.TypeInfo_Tuple */
82 TK_CONST_TYPE, /* object.TypeInfo_Const */
83 TK_IMMUTABLE_TYPE, /* object.TypeInfo_Invariant */
84 TK_SHARED_TYPE, /* object.TypeInfo_Shared */
85 TK_INOUT_TYPE, /* object.TypeInfo_Inout */
86 TK_CPPTI_TYPE, /* object.__cpp_type_info_ptr */
87 TK_END
90 /* An array of all internal TypeInfo derived types we need.
91 The TypeInfo and ClassInfo types are created early, the
92 remainder are generated as needed. */
94 static GTY(()) tree tinfo_types[TK_END];
96 /* Return the kind of TypeInfo used to describe TYPE. */
98 static tinfo_kind
99 get_typeinfo_kind (Type *type)
101 /* Check head shared/const modifiers first. */
102 if (type->isShared ())
103 return TK_SHARED_TYPE;
104 else if (type->isConst ())
105 return TK_CONST_TYPE;
106 else if (type->isImmutable ())
107 return TK_IMMUTABLE_TYPE;
108 else if (type->isWild ())
109 return TK_INOUT_TYPE;
111 switch (type->ty)
113 case Tpointer:
114 return TK_POINTER_TYPE;
116 case Tarray:
117 return TK_ARRAY_TYPE;
119 case Tsarray:
120 return TK_STATICARRAY_TYPE;
122 case Taarray:
123 return TK_ASSOCIATIVEARRAY_TYPE;
125 case Tstruct:
126 return TK_STRUCT_TYPE;
128 case Tvector:
129 return TK_VECTOR_TYPE;
131 case Tenum:
132 return TK_ENUMERAL_TYPE;
134 case Tfunction:
135 return TK_FUNCTION_TYPE;
137 case Tdelegate:
138 return TK_DELEGATE_TYPE;
140 case Ttuple:
141 return TK_TYPELIST_TYPE;
143 case Tclass:
144 if (type->isTypeClass ()->sym->isInterfaceDeclaration ())
145 return TK_INTERFACE_TYPE;
146 else
147 return TK_CLASSINFO_TYPE;
149 default:
150 return TK_TYPEINFO_TYPE;
154 /* Generate the RECORD_TYPE containing the data layout of a TypeInfo derivative
155 as used by the runtime. This layout must be consistent with that defined in
156 the `object.d' module. */
158 static void
159 make_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...)
161 va_list ap;
163 va_start (ap, ident);
165 /* First two fields are from the TypeInfo base class.
166 Note, finish_builtin_struct() expects these fields in reverse order. */
167 tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);
168 DECL_CHAIN (fields) = create_field_decl (vtbl_ptr_type_node, NULL, 1, 1);
170 /* Now add the derived fields. */
171 tree field_type = va_arg (ap, tree);
172 while (field_type != NULL_TREE)
174 tree field = create_field_decl (field_type, NULL, 1, 1);
175 DECL_CHAIN (field) = fields;
176 fields = field;
177 field_type = va_arg (ap, tree);
180 /* Create the TypeInfo type. */
181 tree type = make_node (RECORD_TYPE);
182 finish_builtin_struct (type, ident->toChars (), fields, NULL_TREE);
184 tinfo_types[tk] = type;
186 va_end (ap);
189 /* Reference to the `object` module, where all TypeInfo is defined. */
191 static Module *object_module;
193 /* Helper for create_frontend_tinfo_types. Creates a typeinfo class
194 declaration incase one wasn't supplied by reading `object.d'. */
196 static void
197 make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL)
199 if (!base)
200 base = Type::dtypeinfo;
202 gcc_assert (object_module);
204 /* Create object module in order to complete the semantic. */
205 if (!object_module->_scope)
206 object_module->importAll (NULL);
208 /* Object class doesn't exist, create a stub one that will cause an error if
209 used. */
210 Loc loc = (object_module->md) ? object_module->md->loc : object_module->loc;
211 if (!base)
213 if (!ClassDeclaration::object)
215 ClassDeclaration *object
216 = ClassDeclaration::create (loc, Identifier::idPool ("Object"),
217 NULL, NULL, true);
218 object->parent = object_module;
219 object->members = new Dsymbols;
220 object->storage_class |= STCtemp;
223 base = ClassDeclaration::object;
226 /* Assignment of global typeinfo variables is managed by the ClassDeclaration
227 constructor, so only need to new the declaration here. */
228 ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL,
229 true);
230 tinfo->parent = object_module;
231 tinfo->members = new Dsymbols;
232 dsymbolSemantic (tinfo, object_module->_scope);
233 tinfo->baseClass = base;
234 /* This is a compiler generated class, and shouldn't be mistaken for being
235 the type declared in the runtime library. */
236 tinfo->storage_class |= STCtemp;
239 /* Make sure the required builtin types exist for generating the TypeInfo
240 variable definitions. */
242 void
243 create_tinfo_types (Module *mod)
245 /* Build the internal TypeInfo and ClassInfo types.
246 See TypeInfoVisitor for documentation of field layout. */
247 make_internal_typeinfo (TK_TYPEINFO_TYPE, Identifier::idPool ("TypeInfo"),
248 NULL);
250 make_internal_typeinfo (TK_CLASSINFO_TYPE,
251 Identifier::idPool ("TypeInfo_Class"),
252 array_type_node, array_type_node, array_type_node,
253 array_type_node, ptr_type_node, ptr_type_node,
254 ptr_type_node, d_uint_type, ptr_type_node,
255 array_type_node, ptr_type_node, ptr_type_node, NULL);
257 object_module = mod;
260 /* Same as create_tinfo_types, but builds all front-end TypeInfo variable
261 definitions. */
263 static void
264 create_frontend_tinfo_types (void)
266 /* If there's no object module, then neither can there be TypeInfo. */
267 if (object_module == NULL)
268 return;
270 /* Create all frontend TypeInfo classes declarations. We rely on all
271 existing, even if only just as stubs. */
272 if (!Type::dtypeinfo)
273 make_frontend_typeinfo (Identifier::idPool ("TypeInfo"),
274 ClassDeclaration::object);
276 if (!Type::typeinfoclass)
277 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class"));
279 if (!Type::typeinfointerface)
280 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface"));
282 if (!Type::typeinfostruct)
283 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct"));
285 if (!Type::typeinfopointer)
286 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer"));
288 if (!Type::typeinfoarray)
289 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array"));
291 if (!Type::typeinfostaticarray)
292 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray"));
294 if (!Type::typeinfoassociativearray)
295 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray"));
297 if (!Type::typeinfoenum)
298 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum"));
300 if (!Type::typeinfofunction)
301 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function"));
303 if (!Type::typeinfodelegate)
304 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate"));
306 if (!Type::typeinfotypelist)
307 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple"));
309 if (!Type::typeinfoconst)
310 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const"));
312 if (!Type::typeinfoinvariant)
313 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"),
314 Type::typeinfoconst);
316 if (!Type::typeinfoshared)
317 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"),
318 Type::typeinfoconst);
320 if (!Type::typeinfowild)
321 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"),
322 Type::typeinfoconst);
324 if (!Type::typeinfovector)
325 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector"));
327 if (!ClassDeclaration::cpp_type_info_ptr)
328 make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"),
329 ClassDeclaration::object);
332 /* Return true if TypeInfo class TINFO is available in the runtime library. */
334 bool
335 have_typeinfo_p (ClassDeclaration *tinfo)
337 /* Run-time typeinfo disabled on command line. */
338 if (!global.params.useTypeInfo)
339 return false;
341 /* Can't layout TypeInfo if type is not declared, or is an opaque
342 declaration in the object module. */
343 if (!tinfo || !tinfo->members)
344 return false;
346 /* Typeinfo is compiler-generated. */
347 if (tinfo->storage_class & STCtemp)
348 return false;
350 return true;
353 /* Implements the visitor interface to build the TypeInfo layout of all
354 TypeInfoDeclaration AST classes emitted from the D Front-end.
355 All visit methods accept one parameter D, which holds the frontend AST
356 of the TypeInfo class. They also don't return any value, instead the
357 generated symbol is cached internally and returned from the caller. */
359 class TypeInfoVisitor : public Visitor
361 using Visitor::visit;
363 tree decl_;
364 vec<constructor_elt, va_gc> *init_;
366 /* Build an internal comdat symbol for the manifest constant VALUE, so that
367 its address can be taken. */
369 tree internal_reference (tree value)
371 /* Use the typeinfo decl name as a prefix for the internal symbol. */
372 const char *prefix = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (this->decl_));
373 tree decl = build_artificial_decl (TREE_TYPE (value), value, prefix);
375 /* The internal pointer reference should be public, but not visible outside
376 the compilation unit. */
377 DECL_EXTERNAL (decl) = 0;
378 TREE_PUBLIC (decl) = 1;
379 DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
380 set_linkage_for_decl (decl);
381 d_pushdecl (decl);
383 return decl;
386 /* Add VALUE to the constructor values list. */
388 void layout_field (tree value)
390 CONSTRUCTOR_APPEND_ELT (this->init_, NULL_TREE, value);
393 /* Write out STR as a static D string literal. */
395 void layout_string (const char *str)
397 unsigned len = strlen (str);
398 tree value = build_string (len, str);
400 TREE_TYPE (value) = make_array_type (Type::tchar, len);
401 TREE_CONSTANT (value) = 1;
402 TREE_READONLY (value) = 1;
403 TREE_STATIC (value) = 1;
405 /* Taking the address, so assign the literal to a static var. */
406 tree decl = this->internal_reference (value);
407 TREE_READONLY (decl) = 1;
409 value = d_array_value (build_ctype (Type::tchar->arrayOf ()),
410 size_int (len), build_address (decl));
411 this->layout_field (value);
414 /* Write out the __vptr and optionally __monitor fields of class CD. */
416 void layout_base (ClassDeclaration *cd)
418 gcc_assert (cd != NULL);
420 if (have_typeinfo_p (cd))
421 this->layout_field (build_address (get_vtable_decl (cd)));
422 else
423 this->layout_field (null_pointer_node);
425 if (cd->hasMonitor ())
426 this->layout_field (null_pointer_node);
429 /* Write out the interfaces field of class CD.
430 Returns the array of interfaces that the field is pointing to. */
432 tree layout_interfaces (ClassDeclaration *cd)
434 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
435 tree csym = build_address (get_classinfo_decl (cd));
437 /* Put out the offset to where vtblInterfaces are written. */
438 tree value = d_array_value (array_type_node,
439 size_int (cd->vtblInterfaces->length),
440 build_offset (csym, size_int (offset)));
441 this->layout_field (value);
443 /* Internally, the compiler sees Interface as:
444 void*[4] interface;
446 The run-time layout of Interface is:
447 TypeInfo_Class classinfo;
448 void*[] vtbl;
449 size_t offset; */
450 vec<constructor_elt, va_gc> *elms = NULL;
452 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
454 BaseClass *b = (*cd->vtblInterfaces)[i];
455 ClassDeclaration *id = b->sym;
456 vec<constructor_elt, va_gc> *v = NULL;
458 /* Fill in the vtbl[]. */
459 if (!cd->isInterfaceDeclaration ())
460 b->fillVtbl (cd, &b->vtbl, 1);
462 /* ClassInfo for the interface. */
463 value = build_address (get_classinfo_decl (id));
464 CONSTRUCTOR_APPEND_ELT (v, size_int (0), value);
466 if (!cd->isInterfaceDeclaration ())
468 /* The vtable of the interface length and ptr. */
469 unsigned voffset = base_vtable_offset (cd, b);
470 gcc_assert (voffset != 0u);
471 value = build_offset (csym, size_int (voffset));
473 CONSTRUCTOR_APPEND_ELT (v, size_int (1),
474 size_int (id->vtbl.length));
475 CONSTRUCTOR_APPEND_ELT (v, size_int (2), value);
478 /* The `this' offset. */
479 CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));
481 /* Add to the array of interfaces. */
482 value = build_constructor (vtbl_interface_type_node, v);
483 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
486 tree domain = size_int (cd->vtblInterfaces->length - 1);
487 tree arrtype = build_array_type (vtbl_interface_type_node,
488 build_index_type (domain));
489 return build_constructor (arrtype, elms);
492 /* Write out the interfacing vtable[] of base class BCD that will be accessed
493 from the overriding class CD. If both are the same class, then this will
494 be its own vtable. INDEX is the offset in the interfaces array of the
495 base class where the Interface reference can be found.
496 This must be mirrored with base_vtable_offset(). */
498 void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd,
499 size_t index)
501 BaseClass *bs = (*bcd->vtblInterfaces)[index];
502 ClassDeclaration *id = bs->sym;
503 vec<constructor_elt, va_gc> *elms = NULL;
504 FuncDeclarations bvtbl;
506 if (id->vtbl.length == 0 || base_vtable_offset (cd, bs) == ~0u)
507 return;
509 /* Fill bvtbl with the functions we want to put out. */
510 if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0))
511 return;
513 /* First entry is struct Interface reference. */
514 if (id->vtblOffset ())
516 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
517 offset += (index * int_size_in_bytes (vtbl_interface_type_node));
518 tree value = build_offset (build_address (get_classinfo_decl (bcd)),
519 size_int (offset));
520 CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value);
523 for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.length; i++)
525 FuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i];
526 if (fd != NULL)
528 tree value = build_address (make_thunk (fd, bs->offset));
529 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
533 tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
534 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
535 tree value = build_constructor (vtbltype, elms);
536 this->layout_field (value);
540 public:
541 TypeInfoVisitor (tree decl)
543 this->decl_ = decl;
544 this->init_ = NULL;
547 /* Return the completed constructor for the TypeInfo record. */
549 tree result (void)
551 return build_struct_literal (TREE_TYPE (this->decl_), this->init_);
554 /* Layout of TypeInfo is:
555 void **__vptr;
556 void *__monitor; */
558 void visit (TypeInfoDeclaration *)
560 /* The vtable for TypeInfo. */
561 this->layout_base (Type::dtypeinfo);
564 /* Layout of TypeInfo_Const is:
565 void **__vptr;
566 void *__monitor;
567 TypeInfo base; */
569 void visit (TypeInfoConstDeclaration *d)
571 Type *tm = d->tinfo->mutableOf ();
572 tm = tm->merge2 ();
574 /* The vtable for TypeInfo_Const. */
575 this->layout_base (Type::typeinfoconst);
577 /* TypeInfo for the mutable type. */
578 this->layout_field (build_typeinfo (d->loc, tm));
581 /* Layout of TypeInfo_Immutable is:
582 void **__vptr;
583 void *__monitor;
584 TypeInfo base; */
586 void visit (TypeInfoInvariantDeclaration *d)
588 Type *tm = d->tinfo->mutableOf ();
589 tm = tm->merge2 ();
591 /* The vtable for TypeInfo_Invariant. */
592 this->layout_base (Type::typeinfoinvariant);
594 /* TypeInfo for the mutable type. */
595 this->layout_field (build_typeinfo (d->loc, tm));
598 /* Layout of TypeInfo_Shared is:
599 void **__vptr;
600 void *__monitor;
601 TypeInfo base; */
603 void visit (TypeInfoSharedDeclaration *d)
605 Type *tm = d->tinfo->unSharedOf ();
606 tm = tm->merge2 ();
608 /* The vtable for TypeInfo_Shared. */
609 this->layout_base (Type::typeinfoshared);
611 /* TypeInfo for the unshared type. */
612 this->layout_field (build_typeinfo (d->loc, tm));
615 /* Layout of TypeInfo_Inout is:
616 void **__vptr;
617 void *__monitor;
618 TypeInfo base; */
620 void visit (TypeInfoWildDeclaration *d)
622 Type *tm = d->tinfo->mutableOf ();
623 tm = tm->merge2 ();
625 /* The vtable for TypeInfo_Inout. */
626 this->layout_base (Type::typeinfowild);
628 /* TypeInfo for the mutable type. */
629 this->layout_field (build_typeinfo (d->loc, tm));
632 /* Layout of TypeInfo_Enum is:
633 void **__vptr;
634 void *__monitor;
635 TypeInfo base;
636 string name;
637 void[] m_init; */
639 void visit (TypeInfoEnumDeclaration *d)
641 TypeEnum *ti = d->tinfo->isTypeEnum ();
642 EnumDeclaration *ed = ti->sym;
644 /* The vtable for TypeInfo_Enum. */
645 this->layout_base (Type::typeinfoenum);
647 /* TypeInfo for enum members. */
648 tree memtype = (ed->memtype) ? build_typeinfo (d->loc, ed->memtype)
649 : null_pointer_node;
650 this->layout_field (memtype);
652 /* Name of the enum declaration. */
653 this->layout_string (ed->toPrettyChars ());
655 /* Default initializer for enum. */
656 if (ed->members && !d->tinfo->isZeroInit ())
658 tree length = size_int (ed->type->size ());
659 tree ptr = build_address (enum_initializer_decl (ed));
660 this->layout_field (d_array_value (array_type_node, length, ptr));
662 else
663 this->layout_field (null_array_node);
666 /* Layout of TypeInfo_Pointer is:
667 void **__vptr;
668 void *__monitor;
669 TypeInfo m_next; */
671 void visit (TypeInfoPointerDeclaration *d)
673 TypePointer *ti = d->tinfo->isTypePointer ();
675 /* The vtable for TypeInfo_Pointer. */
676 this->layout_base (Type::typeinfopointer);
678 /* TypeInfo for pointer-to type. */
679 this->layout_field (build_typeinfo (d->loc, ti->next));
682 /* Layout of TypeInfo_Array is:
683 void **__vptr;
684 void *__monitor;
685 TypeInfo value; */
687 void visit (TypeInfoArrayDeclaration *d)
689 TypeDArray *ti = d->tinfo->isTypeDArray ();
691 /* The vtable for TypeInfo_Array. */
692 this->layout_base (Type::typeinfoarray);
694 /* TypeInfo for array of type. */
695 this->layout_field (build_typeinfo (d->loc, ti->next));
698 /* Layout of TypeInfo_StaticArray is:
699 void **__vptr;
700 void *__monitor;
701 TypeInfo value;
702 size_t len; */
704 void visit (TypeInfoStaticArrayDeclaration *d)
706 TypeSArray *ti = d->tinfo->isTypeSArray ();
708 /* The vtable for TypeInfo_StaticArray. */
709 this->layout_base (Type::typeinfostaticarray);
711 /* TypeInfo for array of type. */
712 this->layout_field (build_typeinfo (d->loc, ti->next));
714 /* Static array length. */
715 this->layout_field (size_int (ti->dim->toInteger ()));
718 /* Layout of TypeInfo_AssociativeArray is:
719 void **__vptr;
720 void *__monitor;
721 TypeInfo value;
722 TypeInfo key; */
724 void visit (TypeInfoAssociativeArrayDeclaration *d)
726 TypeAArray *ti = d->tinfo->isTypeAArray ();
728 /* The vtable for TypeInfo_AssociativeArray. */
729 this->layout_base (Type::typeinfoassociativearray);
731 /* TypeInfo for value of type. */
732 this->layout_field (build_typeinfo (d->loc, ti->next));
734 /* TypeInfo for index of type. */
735 this->layout_field (build_typeinfo (d->loc, ti->index));
738 /* Layout of TypeInfo_Vector is:
739 void **__vptr;
740 void *__monitor;
741 TypeInfo base; */
743 void visit (TypeInfoVectorDeclaration *d)
745 TypeVector *ti = d->tinfo->isTypeVector ();
747 /* The vtable for TypeInfo_Vector. */
748 this->layout_base (Type::typeinfovector);
750 /* TypeInfo for equivalent static array. */
751 this->layout_field (build_typeinfo (d->loc, ti->basetype));
754 /* Layout of TypeInfo_Function is:
755 void **__vptr;
756 void *__monitor;
757 TypeInfo next;
758 string deco; */
760 void visit (TypeInfoFunctionDeclaration *d)
762 TypeFunction *ti = d->tinfo->isTypeFunction ();
763 gcc_assert (ti->deco != NULL);
765 /* The vtable for TypeInfo_Function. */
766 this->layout_base (Type::typeinfofunction);
768 /* TypeInfo for function return value. */
769 this->layout_field (build_typeinfo (d->loc, ti->next));
771 /* Mangled name of function declaration. */
772 this->layout_string (d->tinfo->deco);
775 /* Layout of TypeInfo_Delegate is:
776 void **__vptr;
777 void *__monitor;
778 TypeInfo next;
779 string deco; */
781 void visit (TypeInfoDelegateDeclaration *d)
783 TypeDelegate *ti = d->tinfo->isTypeDelegate ();
784 gcc_assert (ti->deco != NULL);
786 /* The vtable for TypeInfo_Delegate. */
787 this->layout_base (Type::typeinfodelegate);
789 /* TypeInfo for delegate return value. */
790 this->layout_field (build_typeinfo (d->loc, ti->next));
792 /* Mangled name of delegate declaration. */
793 this->layout_string (d->tinfo->deco);
796 /* Layout of ClassInfo/TypeInfo_Class is:
797 void **__vptr;
798 void *__monitor;
799 byte[] m_init;
800 string name;
801 void*[] vtbl;
802 Interface[] interfaces;
803 TypeInfo_Class base;
804 void *destructor;
805 void function(Object) classInvariant;
806 ClassFlags m_flags;
807 void *deallocator;
808 OffsetTypeInfo[] m_offTi;
809 void function(Object) defaultConstructor;
810 immutable(void)* m_RTInfo;
812 Information relating to interfaces, and their vtables are laid out
813 immediately after the named fields, if there is anything to write. */
815 void visit (TypeInfoClassDeclaration *d)
817 TypeClass *ti = d->tinfo->isTypeClass ();
818 ClassDeclaration *cd = ti->sym;
820 /* The vtable for ClassInfo. */
821 this->layout_base (Type::typeinfoclass);
823 if (!cd->members)
824 return;
826 tree interfaces = NULL_TREE;
828 if (!cd->isInterfaceDeclaration ())
830 /* Default initializer for class. */
831 tree init = aggregate_initializer_decl (cd);
832 tree value = d_array_value (array_type_node, size_int (cd->structsize),
833 build_address (init));
834 this->layout_field (value);
836 /* Name of the class declaration. */
837 const char *name = cd->ident->toChars ();
838 if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0))
839 name = cd->toPrettyChars ();
840 this->layout_string (name);
842 /* The vtable of the class declaration. */
843 value = d_array_value (array_type_node, size_int (cd->vtbl.length),
844 build_address (get_vtable_decl (cd)));
845 this->layout_field (value);
847 /* Array of base interfaces that have their own vtable. */
848 if (cd->vtblInterfaces->length)
849 interfaces = this->layout_interfaces (cd);
850 else
851 this->layout_field (null_array_node);
853 /* TypeInfo_Class base; */
854 tree base = (cd->baseClass)
855 ? build_address (get_classinfo_decl (cd->baseClass))
856 : null_pointer_node;
857 this->layout_field (base);
859 /* void *destructor; */
860 tree dtor = (cd->dtor) ? build_address (get_symbol_decl (cd->dtor))
861 : null_pointer_node;
862 this->layout_field (dtor);
864 /* void function(Object) classInvariant; */
865 tree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv))
866 : null_pointer_node;
867 this->layout_field (inv);
869 /* ClassFlags m_flags; */
870 int flags = ClassFlags::hasOffTi;
871 if (cd->isCOMclass ())
872 flags |= ClassFlags::isCOMclass;
874 if (cd->isCPPclass ())
875 flags |= ClassFlags::isCPPclass;
877 flags |= ClassFlags::hasGetMembers;
878 flags |= ClassFlags::hasTypeInfo;
880 if (cd->ctor)
881 flags |= ClassFlags::hasCtor;
883 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
885 if (bcd->dtor)
887 flags |= ClassFlags::hasDtor;
888 break;
892 if (cd->isAbstract ())
893 flags |= ClassFlags::isAbstract;
895 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
897 if (!bcd->members)
898 continue;
900 for (size_t i = 0; i < bcd->members->length; i++)
902 Dsymbol *sm = (*bcd->members)[i];
903 if (sm->hasPointers ())
904 goto Lhaspointers;
908 flags |= ClassFlags::noPointers;
910 Lhaspointers:
911 this->layout_field (build_integer_cst (flags, d_uint_type));
913 /* void *deallocator; */
914 tree ddtor = (cd->aggDelete)
915 ? build_address (get_symbol_decl (cd->aggDelete))
916 : null_pointer_node;
917 this->layout_field (ddtor);
919 /* OffsetTypeInfo[] m_offTi; (not implemented) */
920 this->layout_field (null_array_node);
922 /* void function(Object) defaultConstructor; */
923 if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable))
925 tree dctor = get_symbol_decl (cd->defaultCtor);
926 this->layout_field (build_address (dctor));
928 else
929 this->layout_field (null_pointer_node);
931 /* immutable(void)* m_RTInfo; */
932 if (cd->getRTInfo)
933 this->layout_field (build_expr (cd->getRTInfo, true));
934 else if (!(flags & ClassFlags::noPointers))
935 this->layout_field (size_one_node);
936 else
937 this->layout_field (null_pointer_node);
939 else
941 /* No initializer for interface. */
942 this->layout_field (null_array_node);
944 /* Name of the interface declaration. */
945 this->layout_string (cd->toPrettyChars ());
947 /* No vtable for interface declaration. */
948 this->layout_field (null_array_node);
950 /* Array of base interfaces that have their own vtable. */
951 if (cd->vtblInterfaces->length)
952 interfaces = this->layout_interfaces (cd);
953 else
954 this->layout_field (null_array_node);
956 /* TypeInfo_Class base;
957 void *destructor;
958 void function(Object) classInvariant; */
959 this->layout_field (null_pointer_node);
960 this->layout_field (null_pointer_node);
961 this->layout_field (null_pointer_node);
963 /* ClassFlags m_flags; */
964 int flags = ClassFlags::hasOffTi;
965 flags |= ClassFlags::hasTypeInfo;
966 if (cd->isCOMinterface ())
967 flags |= ClassFlags::isCOMclass;
969 this->layout_field (build_integer_cst (flags, d_uint_type));
971 /* void *deallocator;
972 OffsetTypeInfo[] m_offTi; (not implemented)
973 void function(Object) defaultConstructor; */
974 this->layout_field (null_pointer_node);
975 this->layout_field (null_array_node);
976 this->layout_field (null_pointer_node);
978 /* immutable(void)* m_RTInfo; */
979 if (cd->getRTInfo)
980 this->layout_field (build_expr (cd->getRTInfo, true));
981 else
982 this->layout_field (null_pointer_node);
985 /* Put out array of Interfaces. */
986 if (interfaces != NULL_TREE)
987 this->layout_field (interfaces);
989 if (!cd->isInterfaceDeclaration ())
991 /* Put out this class' interface vtables[]. */
992 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
993 this->layout_base_vtable (cd, cd, i);
995 /* Put out the overriding interface vtables[]. */
996 for (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass)
998 for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
999 this->layout_base_vtable (cd, bcd, i);
1004 /* Layout of TypeInfo_Interface is:
1005 void **__vptr;
1006 void *__monitor;
1007 TypeInfo_Class info; */
1009 void visit (TypeInfoInterfaceDeclaration *d)
1011 TypeClass *ti = d->tinfo->isTypeClass ();
1013 if (!ti->sym->vclassinfo)
1014 ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti);
1016 /* The vtable for TypeInfo_Interface. */
1017 this->layout_base (Type::typeinfointerface);
1019 /* TypeInfo for class inheriting the interface. */
1020 tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo);
1021 this->layout_field (build_address (tidecl));
1024 /* Layout of TypeInfo_Struct is:
1025 void **__vptr;
1026 void *__monitor;
1027 string name;
1028 void[] m_init;
1029 hash_t function(in void*) xtoHash;
1030 bool function(in void*, in void*) xopEquals;
1031 int function(in void*, in void*) xopCmp;
1032 string function(const(void)*) xtoString;
1033 StructFlags m_flags;
1034 void function(void*) xdtor;
1035 void function(void*) xpostblit;
1036 uint m_align;
1037 immutable(void)* xgetRTInfo; */
1039 void visit (TypeInfoStructDeclaration *d)
1041 TypeStruct *ti = d->tinfo->isTypeStruct ();
1042 StructDeclaration *sd = ti->sym;
1044 /* The vtable for TypeInfo_Struct. */
1045 this->layout_base (Type::typeinfostruct);
1047 if (!sd->members)
1048 return;
1050 /* Name of the struct declaration. */
1051 this->layout_string (sd->toPrettyChars ());
1053 /* Default initializer for struct. */
1054 tree ptr = (sd->zeroInit) ? null_pointer_node
1055 : build_address (aggregate_initializer_decl (sd));
1056 this->layout_field (d_array_value (array_type_node,
1057 size_int (sd->structsize), ptr));
1059 /* hash_t function (in void*) xtoHash; */
1060 tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash))
1061 : null_pointer_node;
1062 this->layout_field (xhash);
1064 if (sd->xhash)
1066 TypeFunction *tf = sd->xhash->type->toTypeFunction ();
1067 if (!tf->isnothrow || tf->trust == TRUSTsystem)
1069 warning (sd->xhash->loc, "toHash() must be declared as "
1070 "extern (D) size_t toHash() const nothrow @safe, "
1071 "not %s", tf->toChars ());
1075 /* bool function(in void*, in void*) xopEquals; */
1076 tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
1077 : null_pointer_node;
1078 this->layout_field (xeq);
1080 /* int function(in void*, in void*) xopCmp; */
1081 tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp))
1082 : null_pointer_node;
1083 this->layout_field (xcmp);
1085 /* string function(const(void)*) xtoString; */
1086 FuncDeclaration *fdx = search_toString (sd);
1087 if (fdx)
1088 this->layout_field (build_address (get_symbol_decl (fdx)));
1089 else
1090 this->layout_field (null_pointer_node);
1092 /* StructFlags m_flags; */
1093 int m_flags = StructFlags::none;
1094 if (ti->hasPointers ())
1095 m_flags |= StructFlags::hasPointers;
1096 this->layout_field (build_integer_cst (m_flags, d_uint_type));
1098 /* void function(void*) xdtor; */
1099 tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor))
1100 : null_pointer_node;
1101 this->layout_field (dtor);
1103 /* void function(void*) xpostblit; */
1104 if (sd->postblit && !(sd->postblit->storage_class & STCdisable))
1105 this->layout_field (build_address (get_symbol_decl (sd->postblit)));
1106 else
1107 this->layout_field (null_pointer_node);
1109 /* uint m_align; */
1110 this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type));
1112 /* immutable(void)* xgetRTInfo; */
1113 if (sd->getRTInfo)
1114 this->layout_field (build_expr (sd->getRTInfo, true));
1115 else if (m_flags & StructFlags::hasPointers)
1116 this->layout_field (size_one_node);
1119 /* Layout of TypeInfo_Tuple is:
1120 void **__vptr;
1121 void *__monitor;
1122 TypeInfo[] elements; */
1124 void visit (TypeInfoTupleDeclaration *d)
1126 TypeTuple *ti = d->tinfo->isTypeTuple ();
1128 /* The vtable for TypeInfo_Tuple. */
1129 this->layout_base (Type::typeinfotypelist);
1131 /* TypeInfo[] elements; */
1132 Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->length);
1133 vec<constructor_elt, va_gc> *elms = NULL;
1134 for (size_t i = 0; i < ti->arguments->length; i++)
1136 Parameter *arg = (*ti->arguments)[i];
1137 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1138 build_typeinfo (d->loc, arg->type));
1140 tree ctor = build_constructor (build_ctype (satype), elms);
1141 tree decl = this->internal_reference (ctor);
1143 tree length = size_int (ti->arguments->length);
1144 tree ptr = build_address (decl);
1145 this->layout_field (d_array_value (array_type_node, length, ptr));
1147 rest_of_decl_compilation (decl, 1, 0);
1152 /* Main entry point for TypeInfoVisitor interface to generate
1153 TypeInfo constructor for the TypeInfoDeclaration AST class D. */
1155 tree
1156 layout_typeinfo (TypeInfoDeclaration *d)
1158 if (!Type::dtypeinfo)
1159 create_frontend_tinfo_types ();
1161 TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d));
1162 d->accept (&v);
1163 return v.result ();
1166 /* Like layout_typeinfo, but generates the TypeInfo_Class for
1167 the class or interface declaration CD. */
1169 tree
1170 layout_classinfo (ClassDeclaration *cd)
1172 if (!Type::dtypeinfo)
1173 create_frontend_tinfo_types ();
1175 TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
1176 TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd));
1177 d->accept (&v);
1178 return v.result ();
1181 /* Get the offset to the BC's vtbl[] initializer from the start of CD.
1182 Returns "~0u" if the base class is not found in any vtable interfaces. */
1184 unsigned
1185 base_vtable_offset (ClassDeclaration *cd, BaseClass *bc)
1187 unsigned csymoffset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
1188 unsigned interfacesize = int_size_in_bytes (vtbl_interface_type_node);
1189 csymoffset += cd->vtblInterfaces->length * interfacesize;
1191 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
1193 BaseClass *b = (*cd->vtblInterfaces)[i];
1194 if (b == bc)
1195 return csymoffset;
1196 csymoffset += b->sym->vtbl.length * target.ptrsize;
1199 /* Check all overriding interface vtbl[]s. */
1200 for (ClassDeclaration *cd2 = cd->baseClass; cd2; cd2 = cd2->baseClass)
1202 for (size_t k = 0; k < cd2->vtblInterfaces->length; k++)
1204 BaseClass *bs = (*cd2->vtblInterfaces)[k];
1205 if (bs->fillVtbl (cd, NULL, 0))
1207 if (bc == bs)
1208 return csymoffset;
1209 csymoffset += bs->sym->vtbl.length * target.ptrsize;
1214 return ~0u;
1217 /* Layout fields that immediately come after the classinfo type for DECL if
1218 there's any interfaces or interface vtables to be added.
1219 This must be mirrored with base_vtable_offset(). */
1221 static tree
1222 layout_classinfo_interfaces (ClassDeclaration *decl)
1224 tree type = tinfo_types[TK_CLASSINFO_TYPE];
1225 size_t structsize = int_size_in_bytes (type);
1227 if (decl->vtblInterfaces->length)
1229 size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node);
1230 tree field;
1232 type = copy_aggregate_type (type);
1234 /* First layout the static array of Interface, which provides information
1235 about the vtables that follow. */
1236 tree domain = size_int (decl->vtblInterfaces->length - 1);
1237 tree arrtype = build_array_type (vtbl_interface_type_node,
1238 build_index_type (domain));
1239 field = create_field_decl (arrtype, NULL, 1, 1);
1240 insert_aggregate_field (type, field, structsize);
1241 structsize += decl->vtblInterfaces->length * interfacesize;
1243 /* For each interface, layout each vtable. */
1244 for (size_t i = 0; i < decl->vtblInterfaces->length; i++)
1246 BaseClass *b = (*decl->vtblInterfaces)[i];
1247 ClassDeclaration *id = b->sym;
1248 unsigned offset = base_vtable_offset (decl, b);
1250 if (id->vtbl.length && offset != ~0u)
1252 tree vtbldomain
1253 = build_index_type (size_int (id->vtbl.length - 1));
1254 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1256 field = create_field_decl (vtbltype, NULL, 1, 1);
1257 insert_aggregate_field (type, field, offset);
1258 structsize += id->vtbl.length * target.ptrsize;
1263 /* Layout the arrays of overriding interface vtables. */
1264 for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass)
1266 for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
1268 BaseClass *b = (*bcd->vtblInterfaces)[i];
1269 ClassDeclaration *id = b->sym;
1270 unsigned offset = base_vtable_offset (decl, b);
1272 if (id->vtbl.length && offset != ~0u)
1274 if (type == tinfo_types[TK_CLASSINFO_TYPE])
1275 type = copy_aggregate_type (type);
1277 tree vtbldomain
1278 = build_index_type (size_int (id->vtbl.length - 1));
1279 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1281 tree field = create_field_decl (vtbltype, NULL, 1, 1);
1282 insert_aggregate_field (type, field, offset);
1283 structsize += id->vtbl.length * target.ptrsize;
1288 /* Update the type size and record mode for the classinfo type. */
1289 if (type != tinfo_types[TK_CLASSINFO_TYPE])
1290 finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type);
1292 return type;
1295 /* Returns true if the TypeInfo for TYPE should be placed in
1296 the runtime library. */
1298 static bool
1299 builtin_typeinfo_p (Type *type)
1301 if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull)
1302 return !type->mod;
1304 if (type->ty == Tarray)
1306 /* Strings are so common, make them builtin. */
1307 Type *next = type->nextOf ();
1308 return !type->mod
1309 && ((next->isTypeBasic () != NULL && !next->mod)
1310 || (next->ty == Tchar && next->mod == MODimmutable)
1311 || (next->ty == Tchar && next->mod == MODconst));
1314 return false;
1317 /* Implements a visitor interface to create the decl tree for TypeInfo decls.
1318 TypeInfo_Class objects differ in that they also have information about
1319 the class type packed immediately after the TypeInfo symbol.
1321 If the frontend had an interface to allow distinguishing being these two
1322 AST types, then that would be better for us. */
1324 class TypeInfoDeclVisitor : public Visitor
1326 using Visitor::visit;
1328 public:
1329 TypeInfoDeclVisitor (void)
1333 void visit (TypeInfoDeclaration *tid)
1335 tree ident = get_identifier (tid->ident->toChars ());
1336 tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)];
1337 gcc_assert (type != NULL_TREE);
1339 /* Built-in typeinfo will be referenced as one-only. */
1340 tid->csym = declare_extern_var (ident, type);
1341 DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid);
1343 DECL_CONTEXT (tid->csym) = d_decl_context (tid);
1344 TREE_READONLY (tid->csym) = 1;
1347 void visit (TypeInfoClassDeclaration *tid)
1349 TypeClass *tc = tid->tinfo->isTypeClass ();
1350 tid->csym = get_classinfo_decl (tc->sym);
1354 /* Get the VAR_DECL of the TypeInfo for DECL. If this does not yet exist,
1355 create it. The TypeInfo decl provides information about the type of a given
1356 expression or object. */
1358 tree
1359 get_typeinfo_decl (TypeInfoDeclaration *decl)
1361 if (decl->csym)
1362 return decl->csym;
1364 gcc_assert (decl->tinfo->ty != Terror);
1366 TypeInfoDeclVisitor v = TypeInfoDeclVisitor ();
1367 decl->accept (&v);
1368 gcc_assert (decl->csym != NULL_TREE);
1370 return decl->csym;
1373 /* Get the VAR_DECL of the ClassInfo for DECL. If this does not yet exist,
1374 create it. The ClassInfo decl provides information about the dynamic type
1375 of a given class type or object. */
1377 tree
1378 get_classinfo_decl (ClassDeclaration *decl)
1380 if (decl->csym)
1381 return decl->csym;
1383 InterfaceDeclaration *id = decl->isInterfaceDeclaration ();
1384 tree ident = mangle_internal_decl (decl, id ? "__Interface" : "__Class", "Z");
1385 tree type = layout_classinfo_interfaces (decl);
1387 decl->csym = declare_extern_var (ident, type);
1388 DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);
1390 /* Class is a reference, want the record type. */
1391 DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type));
1392 /* ClassInfo cannot be const data, because we use the monitor on it. */
1393 TREE_READONLY (decl->csym) = 0;
1395 return decl->csym;
1398 /* Performs sanity checks on the `object.TypeInfo' type, raising an error if
1399 RTTI is disabled, or the type is missing. */
1401 void
1402 check_typeinfo_type (const Loc &loc, Scope *sc)
1404 if (!global.params.useTypeInfo)
1406 static int warned = 0;
1408 /* Even when compiling without RTTI we should still be able to evaluate
1409 TypeInfo at compile-time, just not at run-time. */
1410 if (!warned && (!sc || !(sc->flags & SCOPEctfe)))
1412 error_at (make_location_t (loc),
1413 "%<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. */
1436 tree
1437 build_typeinfo (const Loc &loc, Type *type)
1439 gcc_assert (type->ty != Terror);
1440 check_typeinfo_type (loc, NULL);
1441 create_typeinfo (type, NULL);
1442 return build_address (get_typeinfo_decl (type->vtinfo));
1445 /* Like layout_classinfo, but generates an Object that wraps around a
1446 pointer to C++ type_info so it can be distinguished from D TypeInfo. */
1448 void
1449 layout_cpp_typeinfo (ClassDeclaration *cd)
1451 if (!Type::dtypeinfo)
1452 create_frontend_tinfo_types ();
1454 gcc_assert (cd->isCPPclass ());
1456 tree decl = get_cpp_typeinfo_decl (cd);
1457 vec<constructor_elt, va_gc> *init = NULL;
1459 /* Use the vtable of __cpp_type_info_ptr, the EH personality routine
1460 expects this, as it uses .classinfo identity comparison to test for
1461 C++ catch handlers. */
1462 ClassDeclaration *cppti = ClassDeclaration::cpp_type_info_ptr;
1463 if (have_typeinfo_p (cppti))
1465 tree vptr = get_vtable_decl (cppti);
1466 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr));
1468 else
1469 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);
1471 if (cppti->hasMonitor ())
1472 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);
1474 /* Let C++ do the RTTI generation, and just reference the symbol as
1475 extern, knowing the underlying type is not required. */
1476 const char *ident = target.cpp.typeInfoMangle (cd);
1477 tree typeinfo = declare_extern_var (get_identifier (ident),
1478 unknown_type_node);
1479 TREE_READONLY (typeinfo) = 1;
1480 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo));
1482 /* Build the initializer and emit. */
1483 DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init);
1484 d_finish_decl (decl);
1487 /* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet
1488 exist, create it. The __cpp_type_info_ptr decl is then initialized with a
1489 pointer to the C++ type_info for the given class. */
1491 tree
1492 get_cpp_typeinfo_decl (ClassDeclaration *decl)
1494 gcc_assert (decl->isCPPclass ());
1496 if (decl->cpp_type_info_ptr_sym)
1497 return decl->cpp_type_info_ptr_sym;
1499 if (!tinfo_types[TK_CPPTI_TYPE])
1500 make_internal_typeinfo (TK_CPPTI_TYPE,
1501 Identifier::idPool ("__cpp_type_info_ptr"),
1502 ptr_type_node, NULL);
1504 tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", "");
1505 tree type = tinfo_types[TK_CPPTI_TYPE];
1507 decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type);
1508 DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL);
1510 /* Class is a reference, want the record type. */
1511 DECL_CONTEXT (decl->cpp_type_info_ptr_sym)
1512 = TREE_TYPE (build_ctype (decl->type));
1513 TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;
1515 /* Layout the initializer and emit the symbol. */
1516 layout_cpp_typeinfo (decl);
1518 return decl->cpp_type_info_ptr_sym;
1521 /* Get the exact TypeInfo for TYPE, if it doesn't exist, create it. */
1523 void
1524 create_typeinfo (Type *type, Module *mod)
1526 if (!Type::dtypeinfo)
1527 create_frontend_tinfo_types ();
1529 /* Do this since not all Type's are merged. */
1530 Type *t = type->merge2 ();
1531 Identifier *ident;
1533 if (!t->vtinfo)
1535 tinfo_kind tk = get_typeinfo_kind (t);
1536 switch (tk)
1538 case TK_SHARED_TYPE:
1539 case TK_CONST_TYPE:
1540 case TK_IMMUTABLE_TYPE:
1541 case TK_INOUT_TYPE:
1542 case TK_POINTER_TYPE:
1543 case TK_ARRAY_TYPE:
1544 case TK_VECTOR_TYPE:
1545 case TK_INTERFACE_TYPE:
1546 /* Kinds of TypeInfo that add one extra pointer field. */
1547 if (tk == TK_SHARED_TYPE)
1549 /* Does both `shared' and `shared const'. */
1550 t->vtinfo = TypeInfoSharedDeclaration::create (t);
1551 ident = Identifier::idPool ("TypeInfo_Shared");
1553 else if (tk == TK_CONST_TYPE)
1555 t->vtinfo = TypeInfoConstDeclaration::create (t);
1556 ident = Identifier::idPool ("TypeInfo_Const");
1558 else if (tk == TK_IMMUTABLE_TYPE)
1560 t->vtinfo = TypeInfoInvariantDeclaration::create (t);
1561 ident = Identifier::idPool ("TypeInfo_Invariant");
1563 else if (tk == TK_INOUT_TYPE)
1565 t->vtinfo = TypeInfoWildDeclaration::create (t);
1566 ident = Identifier::idPool ("TypeInfo_Wild");
1568 else if (tk == TK_POINTER_TYPE)
1570 t->vtinfo = TypeInfoPointerDeclaration::create (t);
1571 ident = Identifier::idPool ("TypeInfo_Pointer");
1573 else if (tk == TK_ARRAY_TYPE)
1575 t->vtinfo = TypeInfoArrayDeclaration::create (t);
1576 ident = Identifier::idPool ("TypeInfo_Array");
1578 else if (tk == TK_VECTOR_TYPE)
1580 t->vtinfo = TypeInfoVectorDeclaration::create (t);
1581 ident = Identifier::idPool ("TypeInfo_Vector");
1583 else if (tk == TK_INTERFACE_TYPE)
1585 t->vtinfo = TypeInfoInterfaceDeclaration::create (t);
1586 ident = Identifier::idPool ("TypeInfo_Interface");
1588 else
1589 gcc_unreachable ();
1591 if (!tinfo_types[tk])
1592 make_internal_typeinfo (tk, ident, ptr_type_node, NULL);
1593 break;
1595 case TK_STATICARRAY_TYPE:
1596 if (!tinfo_types[tk])
1598 ident = Identifier::idPool ("TypeInfo_StaticArray");
1599 make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node,
1600 NULL);
1602 t->vtinfo = TypeInfoStaticArrayDeclaration::create (t);
1603 break;
1605 case TK_ASSOCIATIVEARRAY_TYPE:
1606 if (!tinfo_types[tk])
1608 ident = Identifier::idPool ("TypeInfo_AssociativeArray");
1609 make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node,
1610 NULL);
1612 t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t);
1613 break;
1615 case TK_STRUCT_TYPE:
1616 if (!tinfo_types[tk])
1618 ident = Identifier::idPool ("TypeInfo_Struct");
1619 make_internal_typeinfo (tk, ident,
1620 array_type_node, array_type_node,
1621 ptr_type_node, ptr_type_node,
1622 ptr_type_node, ptr_type_node,
1623 d_uint_type, ptr_type_node,
1624 ptr_type_node, d_uint_type,
1625 ptr_type_node, NULL);
1627 t->vtinfo = TypeInfoStructDeclaration::create (t);
1628 break;
1630 case TK_ENUMERAL_TYPE:
1631 if (!tinfo_types[tk])
1633 ident = Identifier::idPool ("TypeInfo_Enum");
1634 make_internal_typeinfo (tk, ident,
1635 ptr_type_node, array_type_node,
1636 array_type_node, NULL);
1638 t->vtinfo = TypeInfoEnumDeclaration::create (t);
1639 break;
1641 case TK_FUNCTION_TYPE:
1642 case TK_DELEGATE_TYPE:
1643 /* Functions and delegates share a common TypeInfo layout. */
1644 if (tk == TK_FUNCTION_TYPE)
1646 t->vtinfo = TypeInfoFunctionDeclaration::create (t);
1647 ident = Identifier::idPool ("TypeInfo_Function");
1649 else if (tk == TK_DELEGATE_TYPE)
1651 t->vtinfo = TypeInfoDelegateDeclaration::create (t);
1652 ident = Identifier::idPool ("TypeInfo_Delegate");
1654 else
1655 gcc_unreachable ();
1657 if (!tinfo_types[tk])
1658 make_internal_typeinfo (tk, ident, ptr_type_node,
1659 array_type_node, NULL);
1660 break;
1662 case TK_TYPELIST_TYPE:
1663 if (!tinfo_types[tk])
1665 ident = Identifier::idPool ("TypeInfo_Tuple");
1666 make_internal_typeinfo (tk, ident, array_type_node, NULL);
1668 t->vtinfo = TypeInfoTupleDeclaration::create (t);
1669 break;
1671 case TK_CLASSINFO_TYPE:
1672 t->vtinfo = TypeInfoClassDeclaration::create (t);
1673 break;
1675 default:
1676 t->vtinfo = TypeInfoDeclaration::create (t);
1678 gcc_assert (t->vtinfo);
1680 /* If this has a custom implementation in rt/typeinfo, then
1681 do not generate a COMDAT for it. */
1682 if (!builtin_typeinfo_p (t))
1684 /* Find module that will go all the way to an object file. */
1685 if (mod)
1686 mod->members->push (t->vtinfo);
1687 else
1688 build_decl_tree (t->vtinfo);
1691 /* Types aren't merged, but we can share the vtinfo's. */
1692 if (!type->vtinfo)
1693 type->vtinfo = t->vtinfo;
1695 gcc_assert (type->vtinfo != NULL);
1698 /* Implements a visitor interface to check whether a type is speculative.
1699 TypeInfo_Struct would reference the members of the struct it is representing
1700 (e.g: opEquals via xopEquals field), so if it's instantiated in speculative
1701 context, TypeInfo creation should also be stopped to avoid possible
1702 `unresolved symbol' linker errors. */
1704 class SpeculativeTypeVisitor : public Visitor
1706 using Visitor::visit;
1708 bool result_;
1710 public:
1711 SpeculativeTypeVisitor (void)
1713 this->result_ = false;
1716 bool result (void)
1718 return this->result_;
1721 void visit (Type *t)
1723 Type *tb = t->toBasetype ();
1724 if (tb != t)
1725 tb->accept (this);
1728 void visit (TypeNext *t)
1730 if (t->next)
1731 t->next->accept (this);
1734 void visit (TypeBasic *)
1738 void visit (TypeVector *t)
1740 t->basetype->accept (this);
1743 void visit (TypeAArray *t)
1745 t->index->accept (this);
1746 visit ((TypeNext *) t);
1749 void visit (TypeFunction *t)
1751 visit ((TypeNext *) t);
1754 void visit (TypeStruct *t)
1756 StructDeclaration *sd = t->sym;
1757 if (TemplateInstance *ti = sd->isInstantiated ())
1759 if (!ti->needsCodegen ())
1761 if (ti->minst || sd->requestTypeInfo)
1762 return;
1764 this->result_ |= true;
1769 void visit (TypeClass *t)
1771 ClassDeclaration *cd = t->sym;
1772 if (TemplateInstance *ti = cd->isInstantiated ())
1774 if (!ti->needsCodegen () && !ti->minst)
1776 this->result_ |= true;
1781 void visit (TypeTuple *t)
1783 if (!t->arguments)
1784 return;
1786 for (size_t i = 0; i < t->arguments->length; i++)
1788 Type *tprm = (*t->arguments)[i]->type;
1789 if (tprm)
1790 tprm->accept (this);
1791 if (this->result_)
1792 return;
1797 /* Return true if type was instantiated in a speculative context. */
1799 bool
1800 speculative_type_p (Type *t)
1802 SpeculativeTypeVisitor v = SpeculativeTypeVisitor ();
1803 t->accept (&v);
1804 return v.result ();
1807 #include "gt-d-typeinfo.h"