Fix ICE in lto_symtab_merge_symbols_1 (PR lto/88004).
[official-gcc.git] / gcc / d / typeinfo.cc
blob0c2b695b09ae76d4bfdc06743a90f399ff704b96
1 /* typeinfo.cc -- D runtime type identification.
2 Copyright (C) 2013-2018 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/template.h"
31 #include "dmd/target.h"
33 #include "tree.h"
34 #include "fold-const.h"
35 #include "diagnostic.h"
36 #include "stringpool.h"
37 #include "toplev.h"
38 #include "stor-layout.h"
40 #include "d-tree.h"
41 #include "d-target.h"
44 /* D returns type information to the user as TypeInfo class objects, and can
45 be retrieved for any type using `typeid()'. We also use type information
46 to implement many runtime library helpers, including `new', `delete', most
47 dynamic array operations, and all associative array operations.
49 Type information for a particular type is indicated with an ABI defined
50 structure derived from TypeInfo. This would all be very straight forward,
51 but for the fact that the runtime library provides the definitions of the
52 TypeInfo structure and the ABI defined derived classes in `object.d', as
53 well as having specific implementations of TypeInfo for built-in types
54 in `rt/typeinfo`. We cannot build declarations of these directly in the
55 compiler, but we need to layout objects of their type.
57 To get around this, we define layout compatible POD-structs and generate the
58 appropriate initializations for them. When we have to provide a TypeInfo to
59 the user, we cast the internal compiler type to TypeInfo.
61 It is only required that TypeInfo has a definition in `object.d'. It could
62 happen that we are generating a type information for a TypeInfo object that
63 has no declaration. We however only need the addresses of such incomplete
64 TypeInfo objects for static initialization. */
66 enum tinfo_kind
68 TK_TYPEINFO_TYPE, /* object.TypeInfo */
69 TK_CLASSINFO_TYPE, /* object.TypeInfo_Class */
70 TK_INTERFACE_TYPE, /* object.TypeInfo_Interface */
71 TK_STRUCT_TYPE, /* object.TypeInfo_Struct */
72 TK_POINTER_TYPE, /* object.TypeInfo_Pointer */
73 TK_ARRAY_TYPE, /* object.TypeInfo_Array */
74 TK_STATICARRAY_TYPE, /* object.TypeInfo_StaticArray */
75 TK_ASSOCIATIVEARRAY_TYPE, /* object.TypeInfo_AssociativeArray */
76 TK_VECTOR_TYPE, /* object.TypeInfo_Vector */
77 TK_ENUMERAL_TYPE, /* object.TypeInfo_Enum */
78 TK_FUNCTION_TYPE, /* object.TypeInfo_Function */
79 TK_DELEGATE_TYPE, /* object.TypeInfo_Delegate */
80 TK_TYPELIST_TYPE, /* object.TypeInfo_Tuple */
81 TK_CONST_TYPE, /* object.TypeInfo_Const */
82 TK_IMMUTABLE_TYPE, /* object.TypeInfo_Invariant */
83 TK_SHARED_TYPE, /* object.TypeInfo_Shared */
84 TK_INOUT_TYPE, /* object.TypeInfo_Inout */
85 TK_CPPTI_TYPE, /* object.__cpp_type_info_ptr */
86 TK_END
89 /* An array of all internal TypeInfo derived types we need.
90 The TypeInfo and ClassInfo types are created early, the
91 remainder are generated as needed. */
93 static GTY(()) tree tinfo_types[TK_END];
95 /* Return the kind of TypeInfo used to describe TYPE. */
97 static tinfo_kind
98 get_typeinfo_kind (Type *type)
100 /* Check head shared/const modifiers first. */
101 if (type->isShared ())
102 return TK_SHARED_TYPE;
103 else if (type->isConst ())
104 return TK_CONST_TYPE;
105 else if (type->isImmutable ())
106 return TK_IMMUTABLE_TYPE;
107 else if (type->isWild ())
108 return TK_INOUT_TYPE;
110 switch (type->ty)
112 case Tpointer:
113 return TK_POINTER_TYPE;
115 case Tarray:
116 return TK_ARRAY_TYPE;
118 case Tsarray:
119 return TK_STATICARRAY_TYPE;
121 case Taarray:
122 return TK_ASSOCIATIVEARRAY_TYPE;
124 case Tstruct:
125 return TK_STRUCT_TYPE;
127 case Tvector:
128 return TK_VECTOR_TYPE;
130 case Tenum:
131 return TK_ENUMERAL_TYPE;
133 case Tfunction:
134 return TK_FUNCTION_TYPE;
136 case Tdelegate:
137 return TK_DELEGATE_TYPE;
139 case Ttuple:
140 return TK_TYPELIST_TYPE;
142 case Tclass:
143 if (((TypeClass *) type)->sym->isInterfaceDeclaration ())
144 return TK_INTERFACE_TYPE;
145 else
146 return TK_CLASSINFO_TYPE;
148 default:
149 return TK_TYPEINFO_TYPE;
153 /* Generate the RECORD_TYPE containing the data layout of a TypeInfo derivative
154 as used by the runtime. This layout must be consistent with that defined in
155 the `object.d' module. */
157 static void
158 make_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...)
160 va_list ap;
162 va_start (ap, ident);
164 /* First two fields are from the TypeInfo base class.
165 Note, finish_builtin_struct() expects these fields in reverse order. */
166 tree fields = create_field_decl (ptr_type_node, NULL, 1, 1);
167 DECL_CHAIN (fields) = create_field_decl (vtbl_ptr_type_node, NULL, 1, 1);
169 /* Now add the derived fields. */
170 tree field_type = va_arg (ap, tree);
171 while (field_type != NULL_TREE)
173 tree field = create_field_decl (field_type, NULL, 1, 1);
174 DECL_CHAIN (field) = fields;
175 fields = field;
176 field_type = va_arg (ap, tree);
179 /* Create the TypeInfo type. */
180 tree type = make_node (RECORD_TYPE);
181 finish_builtin_struct (type, ident->toChars (), fields, NULL_TREE);
183 tinfo_types[tk] = type;
185 va_end (ap);
188 /* Helper for create_tinfo_types. Creates a typeinfo class declaration
189 incase one wasn't supplied by reading `object.d'. */
191 static void
192 make_frontend_typeinfo (Module *mod, Identifier *ident,
193 ClassDeclaration *base = NULL)
195 if (!base)
196 base = Type::dtypeinfo;
198 /* Create object module in order to complete the semantic. */
199 if (!mod->_scope)
200 mod->importAll (NULL);
202 /* Assignment of global typeinfo variables is managed by the ClassDeclaration
203 constructor, so only need to new the declaration here. */
204 Loc loc = (mod->md) ? mod->md->loc : mod->loc;
205 ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL,
206 true);
207 tinfo->parent = mod;
208 tinfo->semantic (mod->_scope);
209 tinfo->baseClass = base;
212 /* Make sure the required builtin types exist for generating the TypeInfo
213 variable definitions. */
215 void
216 create_tinfo_types (Module *mod)
218 /* Build the internal TypeInfo and ClassInfo types.
219 See TypeInfoVisitor for documentation of field layout. */
220 make_internal_typeinfo (TK_TYPEINFO_TYPE, Identifier::idPool ("TypeInfo"),
221 NULL);
223 make_internal_typeinfo (TK_CLASSINFO_TYPE,
224 Identifier::idPool ("TypeInfo_Class"),
225 array_type_node, array_type_node, array_type_node,
226 array_type_node, ptr_type_node, ptr_type_node,
227 ptr_type_node, d_uint_type, ptr_type_node,
228 array_type_node, ptr_type_node, ptr_type_node, NULL);
230 /* Create all frontend TypeInfo classes declarations. We rely on all
231 existing, even if only just as stubs. */
232 if (!Type::dtypeinfo)
233 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo"),
234 ClassDeclaration::object);
236 if (!Type::typeinfoclass)
237 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Class"));
239 if (!Type::typeinfointerface)
240 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Interface"));
242 if (!Type::typeinfostruct)
243 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Struct"));
245 if (!Type::typeinfopointer)
246 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Pointer"));
248 if (!Type::typeinfoarray)
249 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Array"));
251 if (!Type::typeinfostaticarray)
252 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_StaticArray"));
254 if (!Type::typeinfoassociativearray)
255 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_AssociativeArray"));
257 if (!Type::typeinfoenum)
258 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Enum"));
260 if (!Type::typeinfofunction)
261 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Function"));
263 if (!Type::typeinfodelegate)
264 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Delegate"));
266 if (!Type::typeinfotypelist)
267 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Tuple"));
269 if (!Type::typeinfoconst)
270 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Const"));
272 if (!Type::typeinfoinvariant)
273 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Invariant"),
274 Type::typeinfoconst);
276 if (!Type::typeinfoshared)
277 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Shared"),
278 Type::typeinfoconst);
280 if (!Type::typeinfowild)
281 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Wild"),
282 Type::typeinfoconst);
284 if (!Type::typeinfovector)
285 make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Vector"));
287 if (!ClassDeclaration::cpp_type_info_ptr)
288 make_frontend_typeinfo (mod, Identifier::idPool ("__cpp_type_info_ptr"),
289 ClassDeclaration::object);
292 /* Implements the visitor interface to build the TypeInfo layout of all
293 TypeInfoDeclaration AST classes emitted from the D Front-end.
294 All visit methods accept one parameter D, which holds the frontend AST
295 of the TypeInfo class. They also don't return any value, instead the
296 generated symbol is cached internally and returned from the caller. */
298 class TypeInfoVisitor : public Visitor
300 using Visitor::visit;
302 tree type_;
303 vec<constructor_elt, va_gc> *init_;
305 /* Add VALUE to the constructor values list. */
307 void layout_field (tree value)
309 CONSTRUCTOR_APPEND_ELT (this->init_, NULL_TREE, value);
312 /* Write out STR as a static D string literal. */
314 void layout_string (const char *str)
316 unsigned len = strlen (str);
317 tree value = build_string (len, str);
319 TREE_TYPE (value) = make_array_type (Type::tchar, len);
320 TREE_CONSTANT (value) = 1;
321 TREE_READONLY (value) = 1;
322 TREE_STATIC (value) = 1;
324 /* Taking the address, so assign the literal to a static var. */
325 tree decl = build_artificial_decl (TREE_TYPE (value), value);
326 TREE_READONLY (decl) = 1;
327 DECL_EXTERNAL (decl) = 0;
328 d_pushdecl (decl);
330 value = d_array_value (build_ctype (Type::tchar->arrayOf ()),
331 size_int (len), build_address (decl));
332 this->layout_field (value);
336 /* Write out the __vptr and __monitor fields of class CD. */
338 void layout_base (ClassDeclaration *cd)
340 gcc_assert (cd != NULL);
341 this->layout_field (build_address (get_vtable_decl (cd)));
342 this->layout_field (null_pointer_node);
345 /* Write out the interfaces field of class CD.
346 Returns the array of interfaces that the field is pointing to. */
348 tree layout_interfaces (ClassDeclaration *cd)
350 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
351 tree csym = build_address (get_classinfo_decl (cd));
353 /* Put out the offset to where vtblInterfaces are written. */
354 tree value = d_array_value (array_type_node,
355 size_int (cd->vtblInterfaces->dim),
356 build_offset (csym, size_int (offset)));
357 this->layout_field (value);
359 /* Internally, the compiler sees Interface as:
360 void*[4] interface;
362 The run-time layout of Interface is:
363 TypeInfo_Class classinfo;
364 void*[] vtbl;
365 size_t offset; */
366 vec<constructor_elt, va_gc> *elms = NULL;
368 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
370 BaseClass *b = (*cd->vtblInterfaces)[i];
371 ClassDeclaration *id = b->sym;
372 vec<constructor_elt, va_gc> *v = NULL;
374 /* Fill in the vtbl[]. */
375 if (!cd->isInterfaceDeclaration ())
376 b->fillVtbl (cd, &b->vtbl, 1);
378 /* ClassInfo for the interface. */
379 value = build_address (get_classinfo_decl (id));
380 CONSTRUCTOR_APPEND_ELT (v, size_int (0), value);
382 if (!cd->isInterfaceDeclaration ())
384 /* The vtable of the interface length and ptr. */
385 unsigned voffset = base_vtable_offset (cd, b);
386 gcc_assert (voffset != 0u);
387 value = build_offset (csym, size_int (voffset));
389 CONSTRUCTOR_APPEND_ELT (v, size_int (1), size_int (id->vtbl.dim));
390 CONSTRUCTOR_APPEND_ELT (v, size_int (2), value);
393 /* The 'this' offset. */
394 CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));
396 /* Add to the array of interfaces. */
397 value = build_constructor (vtbl_interface_type_node, v);
398 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
401 tree domain = size_int (cd->vtblInterfaces->dim - 1);
402 tree arrtype = build_array_type (vtbl_interface_type_node,
403 build_index_type (domain));
404 return build_constructor (arrtype, elms);
407 /* Write out the interfacing vtable[] of base class BCD that will be accessed
408 from the overriding class CD. If both are the same class, then this will
409 be its own vtable. INDEX is the offset in the interfaces array of the
410 base class where the Interface reference can be found.
411 This must be mirrored with base_vtable_offset(). */
413 void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd,
414 size_t index)
416 BaseClass *bs = (*bcd->vtblInterfaces)[index];
417 ClassDeclaration *id = bs->sym;
418 vec<constructor_elt, va_gc> *elms = NULL;
419 FuncDeclarations bvtbl;
421 if (id->vtbl.dim == 0 || base_vtable_offset (cd, bs) == ~0u)
422 return;
424 /* Fill bvtbl with the functions we want to put out. */
425 if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0))
426 return;
428 /* First entry is struct Interface reference. */
429 if (id->vtblOffset ())
431 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
432 offset += (index * int_size_in_bytes (vtbl_interface_type_node));
433 tree value = build_offset (build_address (get_classinfo_decl (bcd)),
434 size_int (offset));
435 CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value);
438 for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.dim; i++)
440 FuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i];
441 if (fd != NULL)
443 tree value = build_address (make_thunk (fd, bs->offset));
444 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
448 tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1));
449 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
450 tree value = build_constructor (vtbltype, elms);
451 this->layout_field (value);
455 public:
456 TypeInfoVisitor (tree type)
458 this->type_ = type;
459 this->init_ = NULL;
462 /* Return the completed constructor for the TypeInfo record. */
464 tree result (void)
466 return build_struct_literal (this->type_, this->init_);
469 /* Layout of TypeInfo is:
470 void **__vptr;
471 void *__monitor; */
473 void visit (TypeInfoDeclaration *)
475 /* The vtable for TypeInfo. */
476 this->layout_base (Type::dtypeinfo);
479 /* Layout of TypeInfo_Const is:
480 void **__vptr;
481 void *__monitor;
482 TypeInfo base; */
484 void visit (TypeInfoConstDeclaration *d)
486 Type *tm = d->tinfo->mutableOf ();
487 tm = tm->merge2 ();
489 /* The vtable for TypeInfo_Const. */
490 this->layout_base (Type::typeinfoconst);
492 /* TypeInfo for the mutable type. */
493 this->layout_field (build_typeinfo (tm));
496 /* Layout of TypeInfo_Immutable is:
497 void **__vptr;
498 void *__monitor;
499 TypeInfo base; */
501 void visit (TypeInfoInvariantDeclaration *d)
503 Type *tm = d->tinfo->mutableOf ();
504 tm = tm->merge2 ();
506 /* The vtable for TypeInfo_Invariant. */
507 this->layout_base (Type::typeinfoinvariant);
509 /* TypeInfo for the mutable type. */
510 this->layout_field (build_typeinfo (tm));
513 /* Layout of TypeInfo_Shared is:
514 void **__vptr;
515 void *__monitor;
516 TypeInfo base; */
518 void visit (TypeInfoSharedDeclaration *d)
520 Type *tm = d->tinfo->unSharedOf ();
521 tm = tm->merge2 ();
523 /* The vtable for TypeInfo_Shared. */
524 this->layout_base (Type::typeinfoshared);
526 /* TypeInfo for the unshared type. */
527 this->layout_field (build_typeinfo (tm));
530 /* Layout of TypeInfo_Inout is:
531 void **__vptr;
532 void *__monitor;
533 TypeInfo base; */
535 void visit (TypeInfoWildDeclaration *d)
537 Type *tm = d->tinfo->mutableOf ();
538 tm = tm->merge2 ();
540 /* The vtable for TypeInfo_Inout. */
541 this->layout_base (Type::typeinfowild);
543 /* TypeInfo for the mutable type. */
544 this->layout_field (build_typeinfo (tm));
547 /* Layout of TypeInfo_Enum is:
548 void **__vptr;
549 void *__monitor;
550 TypeInfo base;
551 string name;
552 void[] m_init; */
554 void visit (TypeInfoEnumDeclaration *d)
556 gcc_assert (d->tinfo->ty == Tenum);
557 TypeEnum *ti = (TypeEnum *) d->tinfo;
558 EnumDeclaration *ed = ti->sym;
560 /* The vtable for TypeInfo_Enum. */
561 this->layout_base (Type::typeinfoenum);
563 /* TypeInfo for enum members. */
564 tree memtype = (ed->memtype) ? build_typeinfo (ed->memtype)
565 : null_pointer_node;
566 this->layout_field (memtype);
568 /* Name of the enum declaration. */
569 this->layout_string (ed->toPrettyChars ());
571 /* Default initializer for enum. */
572 if (ed->members && !d->tinfo->isZeroInit ())
574 tree length = size_int (ed->type->size ());
575 tree ptr = build_address (enum_initializer_decl (ed));
576 this->layout_field (d_array_value (array_type_node, length, ptr));
578 else
579 this->layout_field (null_array_node);
582 /* Layout of TypeInfo_Pointer is:
583 void **__vptr;
584 void *__monitor;
585 TypeInfo m_next; */
587 void visit (TypeInfoPointerDeclaration *d)
589 gcc_assert (d->tinfo->ty == Tpointer);
590 TypePointer *ti = (TypePointer *) d->tinfo;
592 /* The vtable for TypeInfo_Pointer. */
593 this->layout_base (Type::typeinfopointer);
595 /* TypeInfo for pointer-to type. */
596 this->layout_field (build_typeinfo (ti->next));
599 /* Layout of TypeInfo_Array is:
600 void **__vptr;
601 void *__monitor;
602 TypeInfo value; */
604 void visit (TypeInfoArrayDeclaration *d)
606 gcc_assert (d->tinfo->ty == Tarray);
607 TypeDArray *ti = (TypeDArray *) d->tinfo;
609 /* The vtable for TypeInfo_Array. */
610 this->layout_base (Type::typeinfoarray);
612 /* TypeInfo for array of type. */
613 this->layout_field (build_typeinfo (ti->next));
616 /* Layout of TypeInfo_StaticArray is:
617 void **__vptr;
618 void *__monitor;
619 TypeInfo value;
620 size_t len; */
622 void visit (TypeInfoStaticArrayDeclaration *d)
624 gcc_assert (d->tinfo->ty == Tsarray);
625 TypeSArray *ti = (TypeSArray *) d->tinfo;
627 /* The vtable for TypeInfo_StaticArray. */
628 this->layout_base (Type::typeinfostaticarray);
630 /* TypeInfo for array of type. */
631 this->layout_field (build_typeinfo (ti->next));
633 /* Static array length. */
634 this->layout_field (size_int (ti->dim->toInteger ()));
637 /* Layout of TypeInfo_AssociativeArray is:
638 void **__vptr;
639 void *__monitor;
640 TypeInfo value;
641 TypeInfo key; */
643 void visit (TypeInfoAssociativeArrayDeclaration *d)
645 gcc_assert (d->tinfo->ty == Taarray);
646 TypeAArray *ti = (TypeAArray *) d->tinfo;
648 /* The vtable for TypeInfo_AssociativeArray. */
649 this->layout_base (Type::typeinfoassociativearray);
651 /* TypeInfo for value of type. */
652 this->layout_field (build_typeinfo (ti->next));
654 /* TypeInfo for index of type. */
655 this->layout_field (build_typeinfo (ti->index));
658 /* Layout of TypeInfo_Vector is:
659 void **__vptr;
660 void *__monitor;
661 TypeInfo base; */
663 void visit (TypeInfoVectorDeclaration *d)
665 gcc_assert (d->tinfo->ty == Tvector);
666 TypeVector *ti = (TypeVector *) d->tinfo;
668 /* The vtable for TypeInfo_Vector. */
669 this->layout_base (Type::typeinfovector);
671 /* TypeInfo for equivalent static array. */
672 this->layout_field (build_typeinfo (ti->basetype));
675 /* Layout of TypeInfo_Function is:
676 void **__vptr;
677 void *__monitor;
678 TypeInfo next;
679 string deco; */
681 void visit (TypeInfoFunctionDeclaration *d)
683 gcc_assert (d->tinfo->ty == Tfunction && d->tinfo->deco != NULL);
684 TypeFunction *ti = (TypeFunction *) d->tinfo;
686 /* The vtable for TypeInfo_Function. */
687 this->layout_base (Type::typeinfofunction);
689 /* TypeInfo for function return value. */
690 this->layout_field (build_typeinfo (ti->next));
692 /* Mangled name of function declaration. */
693 this->layout_string (d->tinfo->deco);
696 /* Layout of TypeInfo_Delegate is:
697 void **__vptr;
698 void *__monitor;
699 TypeInfo next;
700 string deco; */
702 void visit (TypeInfoDelegateDeclaration *d)
704 gcc_assert (d->tinfo->ty == Tdelegate && d->tinfo->deco != NULL);
705 TypeDelegate *ti = (TypeDelegate *) d->tinfo;
707 /* The vtable for TypeInfo_Delegate. */
708 this->layout_base (Type::typeinfodelegate);
710 /* TypeInfo for delegate return value. */
711 this->layout_field (build_typeinfo (ti->next));
713 /* Mangled name of delegate declaration. */
714 this->layout_string (d->tinfo->deco);
717 /* Layout of ClassInfo/TypeInfo_Class is:
718 void **__vptr;
719 void *__monitor;
720 byte[] m_init;
721 string name;
722 void*[] vtbl;
723 Interface[] interfaces;
724 TypeInfo_Class base;
725 void *destructor;
726 void function(Object) classInvariant;
727 ClassFlags m_flags;
728 void *deallocator;
729 OffsetTypeInfo[] m_offTi;
730 void function(Object) defaultConstructor;
731 immutable(void)* m_RTInfo;
733 Information relating to interfaces, and their vtables are laid out
734 immediately after the named fields, if there is anything to write. */
736 void visit (TypeInfoClassDeclaration *d)
738 gcc_assert (d->tinfo->ty == Tclass);
739 TypeClass *ti = (TypeClass *) d->tinfo;
740 ClassDeclaration *cd = ti->sym;
742 /* The vtable for ClassInfo. */
743 this->layout_base (Type::typeinfoclass);
745 if (!cd->members)
746 return;
748 tree interfaces = NULL_TREE;
750 if (!cd->isInterfaceDeclaration ())
752 /* Default initializer for class. */
753 tree init = aggregate_initializer_decl (cd);
754 tree value = d_array_value (array_type_node, size_int (cd->structsize),
755 build_address (init));
756 this->layout_field (value);
758 /* Name of the class declaration. */
759 const char *name = cd->ident->toChars ();
760 if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0))
761 name = cd->toPrettyChars ();
762 this->layout_string (name);
764 /* The vtable of the class declaration. */
765 value = d_array_value (array_type_node, size_int (cd->vtbl.dim),
766 build_address (get_vtable_decl (cd)));
767 this->layout_field (value);
769 /* Array of base interfaces that have their own vtable. */
770 if (cd->vtblInterfaces->dim)
771 interfaces = this->layout_interfaces (cd);
772 else
773 this->layout_field (null_array_node);
775 /* TypeInfo_Class base; */
776 tree base = (cd->baseClass)
777 ? build_address (get_classinfo_decl (cd->baseClass))
778 : null_pointer_node;
779 this->layout_field (base);
781 /* void *destructor; */
782 tree dtor = (cd->dtor) ? build_address (get_symbol_decl (cd->dtor))
783 : null_pointer_node;
784 this->layout_field (dtor);
786 /* void function(Object) classInvariant; */
787 tree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv))
788 : null_pointer_node;
789 this->layout_field (inv);
791 /* ClassFlags m_flags; */
792 ClassFlags::Type flags = ClassFlags::hasOffTi;
793 if (cd->isCOMclass ())
794 flags |= ClassFlags::isCOMclass;
796 if (cd->isCPPclass ())
797 flags |= ClassFlags::isCPPclass;
799 flags |= ClassFlags::hasGetMembers;
800 flags |= ClassFlags::hasTypeInfo;
802 if (cd->ctor)
803 flags |= ClassFlags::hasCtor;
805 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
807 if (bcd->dtor)
809 flags |= ClassFlags::hasDtor;
810 break;
814 if (cd->isAbstract ())
815 flags |= ClassFlags::isAbstract;
817 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
819 if (!bcd->members)
820 continue;
822 for (size_t i = 0; i < bcd->members->dim; i++)
824 Dsymbol *sm = (*bcd->members)[i];
825 if (sm->hasPointers ())
826 goto Lhaspointers;
830 flags |= ClassFlags::noPointers;
832 Lhaspointers:
833 this->layout_field (size_int (flags));
835 /* void *deallocator; */
836 tree ddtor = (cd->aggDelete)
837 ? build_address (get_symbol_decl (cd->aggDelete))
838 : null_pointer_node;
839 this->layout_field (ddtor);
841 /* OffsetTypeInfo[] m_offTi; (not implemented) */
842 this->layout_field (null_array_node);
844 /* void function(Object) defaultConstructor; */
845 if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable))
847 tree dctor = get_symbol_decl (cd->defaultCtor);
848 this->layout_field (build_address (dctor));
850 else
851 this->layout_field (null_pointer_node);
853 /* immutable(void)* m_RTInfo; */
854 if (cd->getRTInfo)
855 this->layout_field (build_expr (cd->getRTInfo, true));
856 else if (!(flags & ClassFlags::noPointers))
857 this->layout_field (size_one_node);
859 else
861 /* No initializer for interface. */
862 this->layout_field (null_array_node);
864 /* Name of the interface declaration. */
865 this->layout_string (cd->toPrettyChars ());
867 /* No vtable for interface declaration. */
868 this->layout_field (null_array_node);
870 /* Array of base interfaces that have their own vtable. */
871 if (cd->vtblInterfaces->dim)
872 interfaces = this->layout_interfaces (cd);
873 else
874 this->layout_field (null_array_node);
876 /* TypeInfo_Class base;
877 void *destructor;
878 void function(Object) classInvariant; */
879 this->layout_field (null_pointer_node);
880 this->layout_field (null_pointer_node);
881 this->layout_field (null_pointer_node);
883 /* ClassFlags m_flags; */
884 ClassFlags::Type flags = ClassFlags::hasOffTi;
885 flags |= ClassFlags::hasTypeInfo;
886 if (cd->isCOMinterface ())
887 flags |= ClassFlags::isCOMclass;
889 this->layout_field (size_int (flags));
891 /* void *deallocator;
892 OffsetTypeInfo[] m_offTi; (not implemented)
893 void function(Object) defaultConstructor; */
894 this->layout_field (null_pointer_node);
895 this->layout_field (null_array_node);
896 this->layout_field (null_pointer_node);
898 /* immutable(void)* m_RTInfo; */
899 if (cd->getRTInfo)
900 this->layout_field (build_expr (cd->getRTInfo, true));
901 else
902 this->layout_field (null_pointer_node);
905 /* Put out array of Interfaces. */
906 if (interfaces != NULL_TREE)
907 this->layout_field (interfaces);
909 if (!cd->isInterfaceDeclaration ())
911 /* Put out this class' interface vtables[]. */
912 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
913 this->layout_base_vtable (cd, cd, i);
915 /* Put out the overriding interface vtables[]. */
916 for (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass)
918 for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++)
919 this->layout_base_vtable (cd, bcd, i);
924 /* Layout of TypeInfo_Interface is:
925 void **__vptr;
926 void *__monitor;
927 TypeInfo_Class info; */
929 void visit (TypeInfoInterfaceDeclaration *d)
931 gcc_assert (d->tinfo->ty == Tclass);
932 TypeClass *ti = (TypeClass *) d->tinfo;
934 if (!ti->sym->vclassinfo)
935 ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti);
937 /* The vtable for TypeInfo_Interface. */
938 this->layout_base (Type::typeinfointerface);
940 /* TypeInfo for class inheriting the interface. */
941 tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo);
942 this->layout_field (build_address (tidecl));
945 /* Layout of TypeInfo_Struct is:
946 void **__vptr;
947 void *__monitor;
948 string name;
949 void[] m_init;
950 hash_t function(in void*) xtoHash;
951 bool function(in void*, in void*) xopEquals;
952 int function(in void*, in void*) xopCmp;
953 string function(const(void)*) xtoString;
954 StructFlags m_flags;
955 void function(void*) xdtor;
956 void function(void*) xpostblit;
957 uint m_align;
958 version (X86_64)
959 TypeInfo m_arg1;
960 TypeInfo m_arg2;
961 immutable(void)* xgetRTInfo; */
963 void visit (TypeInfoStructDeclaration *d)
965 gcc_assert (d->tinfo->ty == Tstruct);
966 TypeStruct *ti = (TypeStruct *) d->tinfo;
967 StructDeclaration *sd = ti->sym;
969 /* The vtable for TypeInfo_Struct. */
970 this->layout_base (Type::typeinfostruct);
972 if (!sd->members)
973 return;
975 /* Name of the struct declaration. */
976 this->layout_string (sd->toPrettyChars ());
978 /* Default initializer for struct. */
979 tree ptr = (sd->zeroInit) ? null_pointer_node
980 : build_address (aggregate_initializer_decl (sd));
981 this->layout_field (d_array_value (array_type_node,
982 size_int (sd->structsize), ptr));
984 /* hash_t function (in void*) xtoHash; */
985 tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash))
986 : null_pointer_node;
987 this->layout_field (xhash);
989 if (sd->xhash)
991 TypeFunction *tf = (TypeFunction *) sd->xhash->type;
992 gcc_assert (tf->ty == Tfunction);
993 if (!tf->isnothrow || tf->trust == TRUSTsystem)
995 warning (sd->xhash->loc, "toHash() must be declared as "
996 "extern (D) size_t toHash() const nothrow @safe, "
997 "not %s", tf->toChars ());
1001 /* bool function(in void*, in void*) xopEquals; */
1002 tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
1003 : null_pointer_node;
1004 this->layout_field (xeq);
1006 /* int function(in void*, in void*) xopCmp; */
1007 tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp))
1008 : null_pointer_node;
1009 this->layout_field (xcmp);
1011 /* string function(const(void)*) xtoString; */
1012 FuncDeclaration *fdx = search_toString (sd);
1013 if (fdx)
1014 this->layout_field (build_address (get_symbol_decl (fdx)));
1015 else
1016 this->layout_field (null_pointer_node);
1018 /* StructFlags m_flags; */
1019 StructFlags::Type m_flags = 0;
1020 if (ti->hasPointers ())
1021 m_flags |= StructFlags::hasPointers;
1022 this->layout_field (size_int (m_flags));
1024 /* void function(void*) xdtor; */
1025 tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor))
1026 : null_pointer_node;
1027 this->layout_field (dtor);
1029 /* void function(void*) xpostblit; */
1030 if (sd->postblit && !(sd->postblit->storage_class & STCdisable))
1031 this->layout_field (build_address (get_symbol_decl (sd->postblit)));
1032 else
1033 this->layout_field (null_pointer_node);
1035 /* uint m_align; */
1036 this->layout_field (size_int (ti->alignsize ()));
1038 if (global.params.is64bit)
1040 /* TypeInfo m_arg1; */
1041 tree arg1type = (sd->arg1type) ? build_typeinfo (sd->arg1type)
1042 : null_pointer_node;
1043 this->layout_field (arg1type);
1045 /* TypeInfo m_arg2; */
1046 tree arg2type = (sd->arg2type) ? build_typeinfo (sd->arg2type)
1047 : null_pointer_node;
1048 this->layout_field (arg2type);
1051 /* immutable(void)* xgetRTInfo; */
1052 if (sd->getRTInfo)
1053 this->layout_field (build_expr (sd->getRTInfo, true));
1054 else if (m_flags & StructFlags::hasPointers)
1055 this->layout_field (size_one_node);
1058 /* Layout of TypeInfo_Tuple is:
1059 void **__vptr;
1060 void *__monitor;
1061 TypeInfo[] elements; */
1063 void visit (TypeInfoTupleDeclaration *d)
1065 gcc_assert (d->tinfo->ty == Ttuple);
1066 TypeTuple *ti = (TypeTuple *) d->tinfo;
1068 /* The vtable for TypeInfo_Tuple. */
1069 this->layout_base (Type::typeinfotypelist);
1071 /* TypeInfo[] elements; */
1072 Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->dim);
1073 vec<constructor_elt, va_gc> *elms = NULL;
1074 for (size_t i = 0; i < ti->arguments->dim; i++)
1076 Parameter *arg = (*ti->arguments)[i];
1077 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1078 build_typeinfo (arg->type));
1080 tree ctor = build_constructor (build_ctype (satype), elms);
1081 tree decl = build_artificial_decl (TREE_TYPE (ctor), ctor);
1083 /* The internal pointer reference should be public, but not visible outside
1084 the compilation unit, as it's referencing COMDAT decls. */
1085 TREE_PUBLIC (decl) = 1;
1086 DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
1087 DECL_COMDAT (decl) = 1;
1089 tree length = size_int (ti->arguments->dim);
1090 tree ptr = build_address (decl);
1091 this->layout_field (d_array_value (array_type_node, length, ptr));
1093 d_pushdecl (decl);
1094 rest_of_decl_compilation (decl, 1, 0);
1099 /* Main entry point for TypeInfoVisitor interface to generate
1100 TypeInfo constructor for the TypeInfoDeclaration AST class D. */
1102 tree
1103 layout_typeinfo (TypeInfoDeclaration *d)
1105 tree type = TREE_TYPE (get_typeinfo_decl (d));
1106 TypeInfoVisitor v = TypeInfoVisitor (type);
1107 d->accept (&v);
1108 return v.result ();
1111 /* Like layout_typeinfo, but generates the TypeInfo_Class for
1112 the class or interface declaration CD. */
1114 tree
1115 layout_classinfo (ClassDeclaration *cd)
1117 TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
1118 tree type = TREE_TYPE (get_classinfo_decl (cd));
1119 TypeInfoVisitor v = TypeInfoVisitor (type);
1120 d->accept (&v);
1121 return v.result ();
1124 /* Layout fields that immediately come after the classinfo type for DECL if
1125 there's any interfaces or interface vtables to be added.
1126 This must be mirrored with base_vtable_offset(). */
1128 static tree
1129 layout_classinfo_interfaces (ClassDeclaration *decl)
1131 tree type = tinfo_types[TK_CLASSINFO_TYPE];
1132 size_t structsize = int_size_in_bytes (type);
1134 if (decl->vtblInterfaces->dim)
1136 size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node);
1137 tree field;
1139 type = copy_aggregate_type (type);
1141 /* First layout the static array of Interface, which provides information
1142 about the vtables that follow. */
1143 tree domain = size_int (decl->vtblInterfaces->dim - 1);
1144 tree arrtype = build_array_type (vtbl_interface_type_node,
1145 build_index_type (domain));
1146 field = create_field_decl (arrtype, NULL, 1, 1);
1147 insert_aggregate_field (type, field, structsize);
1148 structsize += decl->vtblInterfaces->dim * interfacesize;
1150 /* For each interface, layout each vtable. */
1151 for (size_t i = 0; i < decl->vtblInterfaces->dim; i++)
1153 BaseClass *b = (*decl->vtblInterfaces)[i];
1154 ClassDeclaration *id = b->sym;
1155 unsigned offset = base_vtable_offset (decl, b);
1157 if (id->vtbl.dim && offset != ~0u)
1159 tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1));
1160 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1162 field = create_field_decl (vtbltype, NULL, 1, 1);
1163 insert_aggregate_field (type, field, offset);
1164 structsize += id->vtbl.dim * Target::ptrsize;
1169 /* Layout the arrays of overriding interface vtables. */
1170 for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass)
1172 for (size_t i = 0; i < bcd->vtblInterfaces->dim; i++)
1174 BaseClass *b = (*bcd->vtblInterfaces)[i];
1175 ClassDeclaration *id = b->sym;
1176 unsigned offset = base_vtable_offset (decl, b);
1178 if (id->vtbl.dim && offset != ~0u)
1180 if (type == tinfo_types[TK_CLASSINFO_TYPE])
1181 type = copy_aggregate_type (type);
1183 tree vtbldomain = build_index_type (size_int (id->vtbl.dim - 1));
1184 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1186 tree field = create_field_decl (vtbltype, NULL, 1, 1);
1187 insert_aggregate_field (type, field, offset);
1188 structsize += id->vtbl.dim * Target::ptrsize;
1193 /* Update the type size and record mode for the classinfo type. */
1194 if (type != tinfo_types[TK_CLASSINFO_TYPE])
1195 finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type, NULL);
1197 return type;
1200 /* Returns true if the TypeInfo for TYPE should be placed in
1201 the runtime library. */
1203 static bool
1204 builtin_typeinfo_p (Type *type)
1206 if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull)
1207 return !type->mod;
1209 if (type->ty == Tarray)
1211 /* Strings are so common, make them builtin. */
1212 Type *next = type->nextOf ();
1213 return !type->mod
1214 && ((next->isTypeBasic () != NULL && !next->mod)
1215 || (next->ty == Tchar && next->mod == MODimmutable)
1216 || (next->ty == Tchar && next->mod == MODconst));
1219 return false;
1222 /* Implements a visitor interface to create the decl tree for TypeInfo decls.
1223 TypeInfo_Class objects differ in that they also have information about
1224 the class type packed immediately after the TypeInfo symbol.
1226 If the frontend had an interface to allow distinguishing being these two
1227 AST types, then that would be better for us. */
1229 class TypeInfoDeclVisitor : public Visitor
1231 using Visitor::visit;
1233 public:
1234 TypeInfoDeclVisitor (void)
1238 void visit (TypeInfoDeclaration *tid)
1240 tree ident = get_identifier (tid->ident->toChars ());
1241 tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)];
1242 gcc_assert (type != NULL_TREE);
1244 tid->csym = declare_extern_var (ident, type);
1245 DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid);
1247 DECL_CONTEXT (tid->csym) = d_decl_context (tid);
1248 TREE_READONLY (tid->csym) = 1;
1250 /* Built-in typeinfo will be referenced as one-only. */
1251 gcc_assert (!tid->isInstantiated ());
1253 if (builtin_typeinfo_p (tid->tinfo))
1254 d_linkonce_linkage (tid->csym);
1255 else
1256 d_comdat_linkage (tid->csym);
1259 void visit (TypeInfoClassDeclaration *tid)
1261 gcc_assert (tid->tinfo->ty == Tclass);
1262 TypeClass *tc = (TypeClass *) tid->tinfo;
1263 tid->csym = get_classinfo_decl (tc->sym);
1267 /* Get the VAR_DECL of the TypeInfo for DECL. If this does not yet exist,
1268 create it. The TypeInfo decl provides information about the type of a given
1269 expression or object. */
1271 tree
1272 get_typeinfo_decl (TypeInfoDeclaration *decl)
1274 if (decl->csym)
1275 return decl->csym;
1277 gcc_assert (decl->tinfo->ty != Terror);
1279 TypeInfoDeclVisitor v = TypeInfoDeclVisitor ();
1280 decl->accept (&v);
1281 gcc_assert (decl->csym != NULL_TREE);
1283 return decl->csym;
1286 /* Get the VAR_DECL of the ClassInfo for DECL. If this does not yet exist,
1287 create it. The ClassInfo decl provides information about the dynamic type
1288 of a given class type or object. */
1290 tree
1291 get_classinfo_decl (ClassDeclaration *decl)
1293 if (decl->csym)
1294 return decl->csym;
1296 InterfaceDeclaration *id = decl->isInterfaceDeclaration ();
1297 tree ident = mangle_internal_decl (decl, id ? "__Interface" : "__Class", "Z");
1298 tree type = layout_classinfo_interfaces (decl);
1300 decl->csym = declare_extern_var (ident, type);
1301 DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);
1303 /* Class is a reference, want the record type. */
1304 DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type));
1305 /* ClassInfo cannot be const data, because we use the monitor on it. */
1306 TREE_READONLY (decl->csym) = 0;
1308 return decl->csym;
1311 /* Returns typeinfo reference for TYPE. */
1313 tree
1314 build_typeinfo (Type *type)
1316 gcc_assert (type->ty != Terror);
1317 create_typeinfo (type, NULL);
1318 return build_address (get_typeinfo_decl (type->vtinfo));
1321 /* Like layout_classinfo, but generates an Object that wraps around a
1322 pointer to C++ type_info so it can be distinguished from D TypeInfo. */
1324 void
1325 layout_cpp_typeinfo (ClassDeclaration *cd)
1327 gcc_assert (cd->isCPPclass ());
1329 tree decl = get_cpp_typeinfo_decl (cd);
1330 vec<constructor_elt, va_gc> *init = NULL;
1332 /* Use the vtable of __cpp_type_info_ptr, the EH personality routine
1333 expects this, as it uses .classinfo identity comparison to test for
1334 C++ catch handlers. */
1335 tree vptr = get_vtable_decl (ClassDeclaration::cpp_type_info_ptr);
1336 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr));
1337 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);
1339 /* Let C++ do the RTTI generation, and just reference the symbol as
1340 extern, knowing the underlying type is not required. */
1341 const char *ident = Target::cppTypeInfoMangle (cd);
1342 tree typeinfo = declare_extern_var (get_identifier (ident),
1343 unknown_type_node);
1344 TREE_READONLY (typeinfo) = 1;
1345 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo));
1347 /* Build the initializer and emit. */
1348 DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init);
1349 DECL_EXTERNAL (decl) = 0;
1350 d_pushdecl (decl);
1351 rest_of_decl_compilation (decl, 1, 0);
1354 /* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet
1355 exist, create it. The __cpp_type_info_ptr decl is then initialized with a
1356 pointer to the C++ type_info for the given class. */
1358 tree
1359 get_cpp_typeinfo_decl (ClassDeclaration *decl)
1361 gcc_assert (decl->isCPPclass ());
1363 if (decl->cpp_type_info_ptr_sym)
1364 return decl->cpp_type_info_ptr_sym;
1366 if (!tinfo_types[TK_CPPTI_TYPE])
1367 make_internal_typeinfo (TK_CPPTI_TYPE,
1368 Identifier::idPool ("__cpp_type_info_ptr"),
1369 ptr_type_node, NULL);
1371 tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", "");
1372 tree type = tinfo_types[TK_CPPTI_TYPE];
1374 decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type);
1375 DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL);
1377 /* Class is a reference, want the record type. */
1378 DECL_CONTEXT (decl->cpp_type_info_ptr_sym)
1379 = TREE_TYPE (build_ctype (decl->type));
1380 TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;
1382 d_comdat_linkage (decl->cpp_type_info_ptr_sym);
1384 /* Layout the initializer and emit the symbol. */
1385 layout_cpp_typeinfo (decl);
1387 return decl->cpp_type_info_ptr_sym;
1390 /* Get the exact TypeInfo for TYPE, if it doesn't exist, create it. */
1392 void
1393 create_typeinfo (Type *type, Module *mod)
1395 /* Do this since not all Type's are merged. */
1396 Type *t = type->merge2 ();
1397 Identifier *ident;
1399 if (!t->vtinfo)
1401 tinfo_kind tk = get_typeinfo_kind (t);
1402 switch (tk)
1404 case TK_SHARED_TYPE:
1405 case TK_CONST_TYPE:
1406 case TK_IMMUTABLE_TYPE:
1407 case TK_INOUT_TYPE:
1408 case TK_POINTER_TYPE:
1409 case TK_ARRAY_TYPE:
1410 case TK_VECTOR_TYPE:
1411 case TK_INTERFACE_TYPE:
1412 /* Kinds of TypeInfo that add one extra pointer field. */
1413 if (tk == TK_SHARED_TYPE)
1415 /* Does both 'shared' and 'shared const'. */
1416 t->vtinfo = TypeInfoSharedDeclaration::create (t);
1417 ident = Identifier::idPool ("TypeInfo_Shared");
1419 else if (tk == TK_CONST_TYPE)
1421 t->vtinfo = TypeInfoConstDeclaration::create (t);
1422 ident = Identifier::idPool ("TypeInfo_Const");
1424 else if (tk == TK_IMMUTABLE_TYPE)
1426 t->vtinfo = TypeInfoInvariantDeclaration::create (t);
1427 ident = Identifier::idPool ("TypeInfo_Invariant");
1429 else if (tk == TK_INOUT_TYPE)
1431 t->vtinfo = TypeInfoWildDeclaration::create (t);
1432 ident = Identifier::idPool ("TypeInfo_Wild");
1434 else if (tk == TK_POINTER_TYPE)
1436 t->vtinfo = TypeInfoPointerDeclaration::create (t);
1437 ident = Identifier::idPool ("TypeInfo_Pointer");
1439 else if (tk == TK_ARRAY_TYPE)
1441 t->vtinfo = TypeInfoArrayDeclaration::create (t);
1442 ident = Identifier::idPool ("TypeInfo_Array");
1444 else if (tk == TK_VECTOR_TYPE)
1446 t->vtinfo = TypeInfoVectorDeclaration::create (t);
1447 ident = Identifier::idPool ("TypeInfo_Vector");
1449 else if (tk == TK_INTERFACE_TYPE)
1451 t->vtinfo = TypeInfoInterfaceDeclaration::create (t);
1452 ident = Identifier::idPool ("TypeInfo_Interface");
1454 else
1455 gcc_unreachable ();
1457 if (!tinfo_types[tk])
1458 make_internal_typeinfo (tk, ident, ptr_type_node, NULL);
1459 break;
1461 case TK_STATICARRAY_TYPE:
1462 if (!tinfo_types[tk])
1464 ident = Identifier::idPool ("TypeInfo_StaticArray");
1465 make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node,
1466 NULL);
1468 t->vtinfo = TypeInfoStaticArrayDeclaration::create (t);
1469 break;
1471 case TK_ASSOCIATIVEARRAY_TYPE:
1472 if (!tinfo_types[tk])
1474 ident = Identifier::idPool ("TypeInfo_AssociativeArray");
1475 make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node,
1476 NULL);
1478 t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t);
1479 break;
1481 case TK_STRUCT_TYPE:
1482 if (!tinfo_types[tk])
1484 /* Some ABIs add extra TypeInfo fields on the end. */
1485 tree argtype = global.params.is64bit ? ptr_type_node : NULL_TREE;
1487 ident = Identifier::idPool ("TypeInfo_Struct");
1488 make_internal_typeinfo (tk, ident,
1489 array_type_node, array_type_node,
1490 ptr_type_node, ptr_type_node,
1491 ptr_type_node, ptr_type_node,
1492 size_type_node, ptr_type_node,
1493 ptr_type_node, size_type_node,
1494 ptr_type_node, argtype, argtype, NULL);
1496 t->vtinfo = TypeInfoStructDeclaration::create (t);
1497 break;
1499 case TK_ENUMERAL_TYPE:
1500 if (!tinfo_types[tk])
1502 ident = Identifier::idPool ("TypeInfo_Enum");
1503 make_internal_typeinfo (tk, ident,
1504 ptr_type_node, array_type_node,
1505 array_type_node, NULL);
1507 t->vtinfo = TypeInfoEnumDeclaration::create (t);
1508 break;
1510 case TK_FUNCTION_TYPE:
1511 case TK_DELEGATE_TYPE:
1512 /* Functions and delegates share a common TypeInfo layout. */
1513 if (tk == TK_FUNCTION_TYPE)
1515 t->vtinfo = TypeInfoFunctionDeclaration::create (t);
1516 ident = Identifier::idPool ("TypeInfo_Function");
1518 else if (tk == TK_DELEGATE_TYPE)
1520 t->vtinfo = TypeInfoDelegateDeclaration::create (t);
1521 ident = Identifier::idPool ("TypeInfo_Delegate");
1523 else
1524 gcc_unreachable ();
1526 if (!tinfo_types[tk])
1527 make_internal_typeinfo (tk, ident, ptr_type_node,
1528 array_type_node, NULL);
1529 break;
1531 case TK_TYPELIST_TYPE:
1532 if (!tinfo_types[tk])
1534 ident = Identifier::idPool ("TypeInfo_Tuple");
1535 make_internal_typeinfo (tk, ident, array_type_node, NULL);
1537 t->vtinfo = TypeInfoTupleDeclaration::create (t);
1538 break;
1540 case TK_CLASSINFO_TYPE:
1541 t->vtinfo = TypeInfoClassDeclaration::create (t);
1542 break;
1544 default:
1545 t->vtinfo = TypeInfoDeclaration::create (t);
1547 gcc_assert (t->vtinfo);
1549 /* If this has a custom implementation in rt/typeinfo, then
1550 do not generate a COMDAT for it. */
1551 if (!builtin_typeinfo_p (t))
1553 /* Find module that will go all the way to an object file. */
1554 if (mod)
1555 mod->members->push (t->vtinfo);
1556 else
1557 build_decl_tree (t->vtinfo);
1560 /* Types aren't merged, but we can share the vtinfo's. */
1561 if (!type->vtinfo)
1562 type->vtinfo = t->vtinfo;
1564 gcc_assert (type->vtinfo != NULL);
1567 /* Implements a visitor interface to check whether a type is speculative.
1568 TypeInfo_Struct would reference the members of the struct it is representing
1569 (e.g: opEquals via xopEquals field), so if it's instantiated in speculative
1570 context, TypeInfo creation should also be stopped to avoid possible
1571 `unresolved symbol' linker errors. */
1573 class SpeculativeTypeVisitor : public Visitor
1575 using Visitor::visit;
1577 bool result_;
1579 public:
1580 SpeculativeTypeVisitor (void)
1582 this->result_ = false;
1585 bool result (void)
1587 return this->result_;
1590 void visit (Type *t)
1592 Type *tb = t->toBasetype ();
1593 if (tb != t)
1594 tb->accept (this);
1597 void visit (TypeNext *t)
1599 if (t->next)
1600 t->next->accept (this);
1603 void visit (TypeBasic *)
1607 void visit (TypeVector *t)
1609 t->basetype->accept (this);
1612 void visit (TypeAArray *t)
1614 t->index->accept (this);
1615 visit ((TypeNext *)t);
1618 void visit (TypeFunction *t)
1620 visit ((TypeNext *)t);
1623 void visit (TypeStruct *t)
1625 StructDeclaration *sd = t->sym;
1626 if (TemplateInstance *ti = sd->isInstantiated ())
1628 if (!ti->needsCodegen ())
1630 if (ti->minst || sd->requestTypeInfo)
1631 return;
1633 this->result_ |= true;
1638 void visit (TypeClass *t)
1640 ClassDeclaration *cd = t->sym;
1641 if (TemplateInstance *ti = cd->isInstantiated ())
1643 if (!ti->needsCodegen () && !ti->minst)
1645 this->result_ |= true;
1650 void visit (TypeTuple *t)
1652 if (!t->arguments)
1653 return;
1655 for (size_t i = 0; i < t->arguments->dim; i++)
1657 Type *tprm = (*t->arguments)[i]->type;
1658 if (tprm)
1659 tprm->accept (this);
1660 if (this->result_)
1661 return;
1666 /* Return true if type was instantiated in a speculative context. */
1668 bool
1669 speculative_type_p (Type *t)
1671 SpeculativeTypeVisitor v = SpeculativeTypeVisitor ();
1672 t->accept (&v);
1673 return v.result ();
1676 #include "gt-d-typeinfo.h"