1 /* typeinfo.cc -- D runtime type identification.
2 Copyright (C) 2013-2022 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)
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/>. */
20 #include "coretypes.h"
22 #include "dmd/aggregate.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"
35 #include "fold-const.h"
36 #include "diagnostic.h"
37 #include "stringpool.h"
39 #include "stor-layout.h"
42 #include "d-frontend.h"
46 /* D returns type information to the user as TypeInfo class objects, and can
47 be retrieved for any type using `typeid()'. We also use type information
48 to implement many runtime library helpers, including `new', `delete', most
49 dynamic array operations, and all associative array operations.
51 Type information for a particular type is indicated with an ABI defined
52 structure derived from TypeInfo. This would all be very straight forward,
53 but for the fact that the runtime library provides the definitions of the
54 TypeInfo structure and the ABI defined derived classes in `object.d', as
55 well as having specific implementations of TypeInfo for built-in types
56 in `rt/typeinfo`. We cannot build declarations of these directly in the
57 compiler, but we need to layout objects of their type.
59 To get around this, we define layout compatible POD-structs and generate the
60 appropriate initializations for them. When we have to provide a TypeInfo to
61 the user, we cast the internal compiler type to TypeInfo.
63 It is only required that TypeInfo has a definition in `object.d'. It could
64 happen that we are generating a type information for a TypeInfo object that
65 has no declaration. We however only need the addresses of such incomplete
66 TypeInfo objects for static initialization. */
70 TK_TYPEINFO_TYPE
, /* object.TypeInfo */
71 TK_CLASSINFO_TYPE
, /* object.TypeInfo_Class */
72 TK_INTERFACE_TYPE
, /* object.TypeInfo_Interface */
73 TK_STRUCT_TYPE
, /* object.TypeInfo_Struct */
74 TK_POINTER_TYPE
, /* object.TypeInfo_Pointer */
75 TK_ARRAY_TYPE
, /* object.TypeInfo_Array */
76 TK_STATICARRAY_TYPE
, /* object.TypeInfo_StaticArray */
77 TK_ASSOCIATIVEARRAY_TYPE
, /* object.TypeInfo_AssociativeArray */
78 TK_VECTOR_TYPE
, /* object.TypeInfo_Vector */
79 TK_ENUMERAL_TYPE
, /* object.TypeInfo_Enum */
80 TK_FUNCTION_TYPE
, /* object.TypeInfo_Function */
81 TK_DELEGATE_TYPE
, /* object.TypeInfo_Delegate */
82 TK_TYPELIST_TYPE
, /* object.TypeInfo_Tuple */
83 TK_CONST_TYPE
, /* object.TypeInfo_Const */
84 TK_IMMUTABLE_TYPE
, /* object.TypeInfo_Invariant */
85 TK_SHARED_TYPE
, /* object.TypeInfo_Shared */
86 TK_INOUT_TYPE
, /* object.TypeInfo_Inout */
87 TK_CPPTI_TYPE
, /* object.__cpp_type_info_ptr */
91 /* An array of all internal TypeInfo derived types we need.
92 The TypeInfo and ClassInfo types are created early, the
93 remainder are generated as needed. */
95 static GTY(()) tree tinfo_types
[TK_END
];
97 /* Return the kind of TypeInfo used to describe TYPE. */
100 get_typeinfo_kind (Type
*type
)
102 /* Check head shared/const modifiers first. */
103 if (type
->isShared ())
104 return TK_SHARED_TYPE
;
105 else if (type
->isConst ())
106 return TK_CONST_TYPE
;
107 else if (type
->isImmutable ())
108 return TK_IMMUTABLE_TYPE
;
109 else if (type
->isWild ())
110 return TK_INOUT_TYPE
;
115 return TK_POINTER_TYPE
;
118 return TK_ARRAY_TYPE
;
121 return TK_STATICARRAY_TYPE
;
124 return TK_ASSOCIATIVEARRAY_TYPE
;
127 return TK_STRUCT_TYPE
;
130 return TK_VECTOR_TYPE
;
133 return TK_ENUMERAL_TYPE
;
136 return TK_FUNCTION_TYPE
;
139 return TK_DELEGATE_TYPE
;
142 return TK_TYPELIST_TYPE
;
145 if (type
->isTypeClass ()->sym
->isInterfaceDeclaration ())
146 return TK_INTERFACE_TYPE
;
148 return TK_CLASSINFO_TYPE
;
151 return TK_TYPEINFO_TYPE
;
155 /* Generate the RECORD_TYPE containing the data layout of a TypeInfo derivative
156 as used by the runtime. This layout must be consistent with that defined in
157 the `object.d' module. */
160 make_internal_typeinfo (tinfo_kind tk
, Identifier
*ident
, ...)
164 va_start (ap
, ident
);
166 /* First two fields are from the TypeInfo base class.
167 Note, finish_builtin_struct() expects these fields in reverse order. */
168 tree fields
= create_field_decl (ptr_type_node
, NULL
, 1, 1);
169 DECL_CHAIN (fields
) = create_field_decl (vtbl_ptr_type_node
, NULL
, 1, 1);
171 /* Now add the derived fields. */
172 tree field_type
= va_arg (ap
, tree
);
173 while (field_type
!= NULL_TREE
)
175 tree field
= create_field_decl (field_type
, NULL
, 1, 1);
176 DECL_CHAIN (field
) = fields
;
178 field_type
= va_arg (ap
, tree
);
181 /* Create the TypeInfo type. */
182 tree type
= make_node (RECORD_TYPE
);
183 finish_builtin_struct (type
, ident
->toChars (), fields
, NULL_TREE
);
185 tinfo_types
[tk
] = type
;
190 /* Reference to the `object` module, where all TypeInfo is defined. */
192 static Module
*object_module
;
194 /* Helper for create_frontend_tinfo_types. Creates a typeinfo class
195 declaration incase one wasn't supplied by reading `object.d'. */
198 make_frontend_typeinfo (Identifier
*ident
, ClassDeclaration
*base
= NULL
)
201 base
= Type::dtypeinfo
;
203 gcc_assert (object_module
);
205 /* Create object module in order to complete the semantic. */
206 if (!object_module
->_scope
)
207 object_module
->importAll (NULL
);
209 /* Object class doesn't exist, create a stub one that will cause an error if
211 Loc loc
= (object_module
->md
) ? object_module
->md
->loc
: object_module
->loc
;
214 if (!ClassDeclaration::object
)
216 ClassDeclaration
*object
217 = ClassDeclaration::create (loc
, Identifier::idPool ("Object"),
219 object
->parent
= object_module
;
220 object
->members
= d_gc_malloc
<Dsymbols
> ();
221 object
->storage_class
|= STCtemp
;
224 base
= ClassDeclaration::object
;
227 /* Assignment of global typeinfo variables is managed by the ClassDeclaration
228 constructor, so only need to new the declaration here. */
229 ClassDeclaration
*tinfo
= ClassDeclaration::create (loc
, ident
, NULL
, NULL
,
231 tinfo
->parent
= object_module
;
232 tinfo
->members
= d_gc_malloc
<Dsymbols
> ();
233 dsymbolSemantic (tinfo
, object_module
->_scope
);
234 tinfo
->baseClass
= base
;
235 /* This is a compiler generated class, and shouldn't be mistaken for being
236 the type declared in the runtime library. */
237 tinfo
->storage_class
|= STCtemp
;
240 /* Make sure the required builtin types exist for generating the TypeInfo
241 variable definitions. */
244 create_tinfo_types (Module
*mod
)
246 /* Build the internal TypeInfo and ClassInfo types.
247 See TypeInfoVisitor for documentation of field layout. */
248 make_internal_typeinfo (TK_TYPEINFO_TYPE
, Identifier::idPool ("TypeInfo"),
251 make_internal_typeinfo (TK_CLASSINFO_TYPE
,
252 Identifier::idPool ("TypeInfo_Class"),
253 array_type_node
, array_type_node
, array_type_node
,
254 array_type_node
, ptr_type_node
, ptr_type_node
,
255 ptr_type_node
, d_uint_type
, ptr_type_node
,
256 array_type_node
, ptr_type_node
, ptr_type_node
, NULL
);
261 /* Same as create_tinfo_types, but builds all front-end TypeInfo variable
265 create_frontend_tinfo_types (void)
267 /* If there's no object module, then neither can there be TypeInfo. */
268 if (object_module
== NULL
)
271 /* Create all frontend TypeInfo classes declarations. We rely on all
272 existing, even if only just as stubs. */
273 if (!Type::dtypeinfo
)
274 make_frontend_typeinfo (Identifier::idPool ("TypeInfo"),
275 ClassDeclaration::object
);
277 if (!Type::typeinfoclass
)
278 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class"));
280 if (!Type::typeinfointerface
)
281 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface"));
283 if (!Type::typeinfostruct
)
284 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct"));
286 if (!Type::typeinfopointer
)
287 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer"));
289 if (!Type::typeinfoarray
)
290 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array"));
292 if (!Type::typeinfostaticarray
)
293 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray"));
295 if (!Type::typeinfoassociativearray
)
296 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray"));
298 if (!Type::typeinfoenum
)
299 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum"));
301 if (!Type::typeinfofunction
)
302 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function"));
304 if (!Type::typeinfodelegate
)
305 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate"));
307 if (!Type::typeinfotypelist
)
308 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple"));
310 if (!Type::typeinfoconst
)
311 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const"));
313 if (!Type::typeinfoinvariant
)
314 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"),
315 Type::typeinfoconst
);
317 if (!Type::typeinfoshared
)
318 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"),
319 Type::typeinfoconst
);
321 if (!Type::typeinfowild
)
322 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"),
323 Type::typeinfoconst
);
325 if (!Type::typeinfovector
)
326 make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector"));
328 if (!ClassDeclaration::cpp_type_info_ptr
)
329 make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"),
330 ClassDeclaration::object
);
333 /* Return true if TypeInfo class TINFO is available in the runtime library. */
336 have_typeinfo_p (ClassDeclaration
*tinfo
)
338 /* Run-time typeinfo disabled on command line. */
339 if (!global
.params
.useTypeInfo
)
342 /* Can't layout TypeInfo if type is not declared, or is an opaque
343 declaration in the object module. */
344 if (!tinfo
|| !tinfo
->members
)
347 /* Typeinfo is compiler-generated. */
348 if (tinfo
->storage_class
& STCtemp
)
354 /* Implements the visitor interface to build the TypeInfo layout of all
355 TypeInfoDeclaration AST classes emitted from the D Front-end.
356 All visit methods accept one parameter D, which holds the frontend AST
357 of the TypeInfo class. They also don't return any value, instead the
358 generated symbol is cached internally and returned from the caller. */
360 class TypeInfoVisitor
: public Visitor
362 using Visitor::visit
;
365 vec
<constructor_elt
, va_gc
> *init_
;
367 /* Build an internal comdat symbol for the manifest constant VALUE, so that
368 its address can be taken. */
370 tree
internal_reference (tree value
)
372 /* Use the typeinfo decl name as a prefix for the internal symbol. */
373 const char *prefix
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (this->decl_
));
374 tree decl
= build_artificial_decl (TREE_TYPE (value
), value
, prefix
);
376 /* The internal pointer reference should be public, but not visible outside
377 the compilation unit. */
378 DECL_EXTERNAL (decl
) = 0;
379 TREE_PUBLIC (decl
) = 1;
380 DECL_VISIBILITY (decl
) = VISIBILITY_INTERNAL
;
381 set_linkage_for_decl (decl
);
387 /* Add VALUE to the constructor values list. */
389 void layout_field (tree value
)
391 CONSTRUCTOR_APPEND_ELT (this->init_
, NULL_TREE
, value
);
394 /* Write out STR as a static D string literal. */
396 void layout_string (const char *str
)
398 unsigned len
= strlen (str
);
399 tree value
= build_string (len
, str
);
401 TREE_TYPE (value
) = make_array_type (Type::tchar
, len
);
402 TREE_CONSTANT (value
) = 1;
403 TREE_READONLY (value
) = 1;
404 TREE_STATIC (value
) = 1;
406 /* Taking the address, so assign the literal to a static var. */
407 tree decl
= this->internal_reference (value
);
408 TREE_READONLY (decl
) = 1;
410 value
= d_array_value (build_ctype (Type::tchar
->arrayOf ()),
411 size_int (len
), build_address (decl
));
412 this->layout_field (value
);
415 /* Write out the __vptr and optionally __monitor fields of class CD. */
417 void layout_base (ClassDeclaration
*cd
)
419 gcc_assert (cd
!= NULL
);
421 if (have_typeinfo_p (cd
))
422 this->layout_field (build_address (get_vtable_decl (cd
)));
424 this->layout_field (null_pointer_node
);
426 if (cd
->hasMonitor ())
427 this->layout_field (null_pointer_node
);
430 /* Write out the interfaces field of class CD.
431 Returns the array of interfaces that the field is pointing to. */
433 tree
layout_interfaces (ClassDeclaration
*cd
)
435 size_t offset
= int_size_in_bytes (tinfo_types
[TK_CLASSINFO_TYPE
]);
436 tree csym
= build_address (get_classinfo_decl (cd
));
438 /* Put out the offset to where vtblInterfaces are written. */
439 tree value
= d_array_value (array_type_node
,
440 size_int (cd
->vtblInterfaces
->length
),
441 build_offset (csym
, size_int (offset
)));
442 this->layout_field (value
);
444 /* Internally, the compiler sees Interface as:
447 The run-time layout of Interface is:
448 TypeInfo_Class classinfo;
451 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
453 for (size_t i
= 0; i
< cd
->vtblInterfaces
->length
; i
++)
455 BaseClass
*b
= (*cd
->vtblInterfaces
)[i
];
456 ClassDeclaration
*id
= b
->sym
;
457 vec
<constructor_elt
, va_gc
> *v
= NULL
;
459 /* Fill in the vtbl[]. */
460 if (!cd
->isInterfaceDeclaration ())
461 b
->fillVtbl (cd
, &b
->vtbl
, 1);
463 /* ClassInfo for the interface. */
464 value
= build_address (get_classinfo_decl (id
));
465 CONSTRUCTOR_APPEND_ELT (v
, size_int (0), value
);
467 if (!cd
->isInterfaceDeclaration ())
469 /* The vtable of the interface length and ptr. */
470 unsigned voffset
= base_vtable_offset (cd
, b
);
471 gcc_assert (voffset
!= 0u);
472 value
= build_offset (csym
, size_int (voffset
));
474 CONSTRUCTOR_APPEND_ELT (v
, size_int (1),
475 size_int (id
->vtbl
.length
));
476 CONSTRUCTOR_APPEND_ELT (v
, size_int (2), value
);
479 /* The `this' offset. */
480 CONSTRUCTOR_APPEND_ELT (v
, size_int (3), size_int (b
->offset
));
482 /* Add to the array of interfaces. */
483 value
= build_constructor (vtbl_interface_type_node
, v
);
484 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
487 tree domain
= size_int (cd
->vtblInterfaces
->length
- 1);
488 tree arrtype
= build_array_type (vtbl_interface_type_node
,
489 build_index_type (domain
));
490 return build_constructor (arrtype
, elms
);
493 /* Write out the interfacing vtable[] of base class BCD that will be accessed
494 from the overriding class CD. If both are the same class, then this will
495 be its own vtable. INDEX is the offset in the interfaces array of the
496 base class where the Interface reference can be found.
497 This must be mirrored with base_vtable_offset(). */
499 void layout_base_vtable (ClassDeclaration
*cd
, ClassDeclaration
*bcd
,
502 BaseClass
*bs
= (*bcd
->vtblInterfaces
)[index
];
503 ClassDeclaration
*id
= bs
->sym
;
504 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
505 FuncDeclarations bvtbl
;
507 if (id
->vtbl
.length
== 0 || base_vtable_offset (cd
, bs
) == ~0u)
510 /* Fill bvtbl with the functions we want to put out. */
511 if (cd
!= bcd
&& !bs
->fillVtbl (cd
, &bvtbl
, 0))
514 /* First entry is struct Interface reference. */
515 if (id
->vtblOffset ())
517 size_t offset
= int_size_in_bytes (tinfo_types
[TK_CLASSINFO_TYPE
]);
518 offset
+= (index
* int_size_in_bytes (vtbl_interface_type_node
));
519 tree value
= build_offset (build_address (get_classinfo_decl (bcd
)),
521 CONSTRUCTOR_APPEND_ELT (elms
, size_zero_node
, value
);
524 for (size_t i
= id
->vtblOffset () ? 1 : 0; i
< id
->vtbl
.length
; i
++)
526 FuncDeclaration
*fd
= (cd
== bcd
) ? bs
->vtbl
[i
] : bvtbl
[i
];
529 tree value
= build_address (make_thunk (fd
, bs
->offset
));
530 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
), value
);
534 tree vtbldomain
= build_index_type (size_int (id
->vtbl
.length
- 1));
535 tree vtbltype
= build_array_type (vtable_entry_type
, vtbldomain
);
536 tree value
= build_constructor (vtbltype
, elms
);
537 this->layout_field (value
);
542 TypeInfoVisitor (tree decl
)
548 /* Return the completed constructor for the TypeInfo record. */
552 return build_struct_literal (TREE_TYPE (this->decl_
), this->init_
);
555 /* Layout of TypeInfo is:
559 void visit (TypeInfoDeclaration
*)
561 /* The vtable for TypeInfo. */
562 this->layout_base (Type::dtypeinfo
);
565 /* Layout of TypeInfo_Const is:
570 void visit (TypeInfoConstDeclaration
*d
)
572 Type
*tm
= d
->tinfo
->mutableOf ();
575 /* The vtable for TypeInfo_Const. */
576 this->layout_base (Type::typeinfoconst
);
578 /* TypeInfo for the mutable type. */
579 this->layout_field (build_typeinfo (d
->loc
, tm
));
582 /* Layout of TypeInfo_Immutable is:
587 void visit (TypeInfoInvariantDeclaration
*d
)
589 Type
*tm
= d
->tinfo
->mutableOf ();
592 /* The vtable for TypeInfo_Invariant. */
593 this->layout_base (Type::typeinfoinvariant
);
595 /* TypeInfo for the mutable type. */
596 this->layout_field (build_typeinfo (d
->loc
, tm
));
599 /* Layout of TypeInfo_Shared is:
604 void visit (TypeInfoSharedDeclaration
*d
)
606 Type
*tm
= d
->tinfo
->unSharedOf ();
609 /* The vtable for TypeInfo_Shared. */
610 this->layout_base (Type::typeinfoshared
);
612 /* TypeInfo for the unshared type. */
613 this->layout_field (build_typeinfo (d
->loc
, tm
));
616 /* Layout of TypeInfo_Inout is:
621 void visit (TypeInfoWildDeclaration
*d
)
623 Type
*tm
= d
->tinfo
->mutableOf ();
626 /* The vtable for TypeInfo_Inout. */
627 this->layout_base (Type::typeinfowild
);
629 /* TypeInfo for the mutable type. */
630 this->layout_field (build_typeinfo (d
->loc
, tm
));
633 /* Layout of TypeInfo_Enum is:
640 void visit (TypeInfoEnumDeclaration
*d
)
642 TypeEnum
*ti
= d
->tinfo
->isTypeEnum ();
643 EnumDeclaration
*ed
= ti
->sym
;
645 /* The vtable for TypeInfo_Enum. */
646 this->layout_base (Type::typeinfoenum
);
648 /* TypeInfo for enum members. */
649 tree memtype
= (ed
->memtype
) ? build_typeinfo (d
->loc
, ed
->memtype
)
651 this->layout_field (memtype
);
653 /* Name of the enum declaration. */
654 this->layout_string (ed
->toPrettyChars ());
656 /* Default initializer for enum. */
657 if (ed
->members
&& !d
->tinfo
->isZeroInit ())
659 tree length
= size_int (ed
->type
->size ());
660 tree ptr
= build_address (enum_initializer_decl (ed
));
661 this->layout_field (d_array_value (array_type_node
, length
, ptr
));
664 this->layout_field (null_array_node
);
667 /* Layout of TypeInfo_Pointer is:
672 void visit (TypeInfoPointerDeclaration
*d
)
674 TypePointer
*ti
= d
->tinfo
->isTypePointer ();
676 /* The vtable for TypeInfo_Pointer. */
677 this->layout_base (Type::typeinfopointer
);
679 /* TypeInfo for pointer-to type. */
680 this->layout_field (build_typeinfo (d
->loc
, ti
->next
));
683 /* Layout of TypeInfo_Array is:
688 void visit (TypeInfoArrayDeclaration
*d
)
690 TypeDArray
*ti
= d
->tinfo
->isTypeDArray ();
692 /* The vtable for TypeInfo_Array. */
693 this->layout_base (Type::typeinfoarray
);
695 /* TypeInfo for array of type. */
696 this->layout_field (build_typeinfo (d
->loc
, ti
->next
));
699 /* Layout of TypeInfo_StaticArray is:
705 void visit (TypeInfoStaticArrayDeclaration
*d
)
707 TypeSArray
*ti
= d
->tinfo
->isTypeSArray ();
709 /* The vtable for TypeInfo_StaticArray. */
710 this->layout_base (Type::typeinfostaticarray
);
712 /* TypeInfo for array of type. */
713 this->layout_field (build_typeinfo (d
->loc
, ti
->next
));
715 /* Static array length. */
716 this->layout_field (size_int (ti
->dim
->toInteger ()));
719 /* Layout of TypeInfo_AssociativeArray is:
725 void visit (TypeInfoAssociativeArrayDeclaration
*d
)
727 TypeAArray
*ti
= d
->tinfo
->isTypeAArray ();
729 /* The vtable for TypeInfo_AssociativeArray. */
730 this->layout_base (Type::typeinfoassociativearray
);
732 /* TypeInfo for value of type. */
733 this->layout_field (build_typeinfo (d
->loc
, ti
->next
));
735 /* TypeInfo for index of type. */
736 this->layout_field (build_typeinfo (d
->loc
, ti
->index
));
739 /* Layout of TypeInfo_Vector is:
744 void visit (TypeInfoVectorDeclaration
*d
)
746 TypeVector
*ti
= d
->tinfo
->isTypeVector ();
748 /* The vtable for TypeInfo_Vector. */
749 this->layout_base (Type::typeinfovector
);
751 /* TypeInfo for equivalent static array. */
752 this->layout_field (build_typeinfo (d
->loc
, ti
->basetype
));
755 /* Layout of TypeInfo_Function is:
761 void visit (TypeInfoFunctionDeclaration
*d
)
763 TypeFunction
*ti
= d
->tinfo
->isTypeFunction ();
764 gcc_assert (ti
->deco
!= NULL
);
766 /* The vtable for TypeInfo_Function. */
767 this->layout_base (Type::typeinfofunction
);
769 /* TypeInfo for function return value. */
770 this->layout_field (build_typeinfo (d
->loc
, ti
->next
));
772 /* Mangled name of function declaration. */
773 this->layout_string (d
->tinfo
->deco
);
776 /* Layout of TypeInfo_Delegate is:
782 void visit (TypeInfoDelegateDeclaration
*d
)
784 TypeDelegate
*ti
= d
->tinfo
->isTypeDelegate ();
785 gcc_assert (ti
->deco
!= NULL
);
787 /* The vtable for TypeInfo_Delegate. */
788 this->layout_base (Type::typeinfodelegate
);
790 /* TypeInfo for delegate return value. */
791 this->layout_field (build_typeinfo (d
->loc
, ti
->next
));
793 /* Mangled name of delegate declaration. */
794 this->layout_string (d
->tinfo
->deco
);
797 /* Layout of ClassInfo/TypeInfo_Class is:
803 Interface[] interfaces;
806 void function(Object) classInvariant;
809 OffsetTypeInfo[] m_offTi;
810 void function(Object) defaultConstructor;
811 immutable(void)* m_RTInfo;
813 Information relating to interfaces, and their vtables are laid out
814 immediately after the named fields, if there is anything to write. */
816 void visit (TypeInfoClassDeclaration
*d
)
818 TypeClass
*ti
= d
->tinfo
->isTypeClass ();
819 ClassDeclaration
*cd
= ti
->sym
;
821 /* The vtable for ClassInfo. */
822 this->layout_base (Type::typeinfoclass
);
827 tree interfaces
= NULL_TREE
;
829 if (!cd
->isInterfaceDeclaration ())
831 /* Default initializer for class. */
832 tree init
= aggregate_initializer_decl (cd
);
833 tree value
= d_array_value (array_type_node
, size_int (cd
->structsize
),
834 build_address (init
));
835 this->layout_field (value
);
837 /* Name of the class declaration. */
838 const char *name
= cd
->ident
->toChars ();
839 if (!(strlen (name
) > 9 && memcmp (name
, "TypeInfo_", 9) == 0))
840 name
= cd
->toPrettyChars (true);
841 this->layout_string (name
);
843 /* The vtable of the class declaration. */
844 value
= d_array_value (array_type_node
, size_int (cd
->vtbl
.length
),
845 build_address (get_vtable_decl (cd
)));
846 this->layout_field (value
);
848 /* Array of base interfaces that have their own vtable. */
849 if (cd
->vtblInterfaces
->length
)
850 interfaces
= this->layout_interfaces (cd
);
852 this->layout_field (null_array_node
);
854 /* TypeInfo_Class base; */
855 tree base
= (cd
->baseClass
)
856 ? build_address (get_classinfo_decl (cd
->baseClass
))
858 this->layout_field (base
);
860 /* void *destructor; */
861 tree dtor
= (cd
->tidtor
) ? build_address (get_symbol_decl (cd
->tidtor
))
863 this->layout_field (dtor
);
865 /* void function(Object) classInvariant; */
866 tree inv
= (cd
->inv
) ? build_address (get_symbol_decl (cd
->inv
))
868 this->layout_field (inv
);
870 /* ClassFlags m_flags; */
871 int flags
= ClassFlags::hasOffTi
;
872 if (cd
->isCOMclass ())
873 flags
|= ClassFlags::isCOMclass
;
875 if (cd
->isCPPclass ())
876 flags
|= ClassFlags::isCPPclass
;
878 flags
|= ClassFlags::hasGetMembers
;
879 flags
|= ClassFlags::hasTypeInfo
;
882 flags
|= ClassFlags::hasCtor
;
884 for (ClassDeclaration
*bcd
= cd
; bcd
; bcd
= bcd
->baseClass
)
888 flags
|= ClassFlags::hasDtor
;
893 if (cd
->isAbstract ())
894 flags
|= ClassFlags::isAbstract
;
896 for (ClassDeclaration
*bcd
= cd
; bcd
; bcd
= bcd
->baseClass
)
901 for (size_t i
= 0; i
< bcd
->members
->length
; i
++)
903 Dsymbol
*sm
= (*bcd
->members
)[i
];
904 if (sm
->hasPointers ())
909 flags
|= ClassFlags::noPointers
;
912 this->layout_field (build_integer_cst (flags
, d_uint_type
));
914 /* void *deallocator; */
915 this->layout_field (null_pointer_node
);
917 /* OffsetTypeInfo[] m_offTi; (not implemented) */
918 this->layout_field (null_array_node
);
920 /* void function(Object) defaultConstructor; */
921 if (cd
->defaultCtor
&& !(cd
->defaultCtor
->storage_class
& STCdisable
))
923 tree dctor
= get_symbol_decl (cd
->defaultCtor
);
924 this->layout_field (build_address (dctor
));
927 this->layout_field (null_pointer_node
);
929 /* immutable(void)* m_RTInfo; */
931 this->layout_field (build_expr (cd
->getRTInfo
, true));
932 else if (!(flags
& ClassFlags::noPointers
))
933 this->layout_field (size_one_node
);
935 this->layout_field (null_pointer_node
);
939 /* No initializer for interface. */
940 this->layout_field (null_array_node
);
942 /* Name of the interface declaration. */
943 this->layout_string (cd
->toPrettyChars (true));
945 /* No vtable for interface declaration. */
946 this->layout_field (null_array_node
);
948 /* Array of base interfaces that have their own vtable. */
949 if (cd
->vtblInterfaces
->length
)
950 interfaces
= this->layout_interfaces (cd
);
952 this->layout_field (null_array_node
);
954 /* TypeInfo_Class base;
956 void function(Object) classInvariant; */
957 this->layout_field (null_pointer_node
);
958 this->layout_field (null_pointer_node
);
959 this->layout_field (null_pointer_node
);
961 /* ClassFlags m_flags; */
962 int flags
= ClassFlags::hasOffTi
;
963 flags
|= ClassFlags::hasTypeInfo
;
964 if (cd
->isCOMinterface ())
965 flags
|= ClassFlags::isCOMclass
;
967 this->layout_field (build_integer_cst (flags
, d_uint_type
));
969 /* void *deallocator;
970 OffsetTypeInfo[] m_offTi; (not implemented)
971 void function(Object) defaultConstructor; */
972 this->layout_field (null_pointer_node
);
973 this->layout_field (null_array_node
);
974 this->layout_field (null_pointer_node
);
976 /* immutable(void)* m_RTInfo; */
978 this->layout_field (build_expr (cd
->getRTInfo
, true));
980 this->layout_field (null_pointer_node
);
983 /* Put out array of Interfaces. */
984 if (interfaces
!= NULL_TREE
)
985 this->layout_field (interfaces
);
987 if (!cd
->isInterfaceDeclaration ())
989 /* Put out this class' interface vtables[]. */
990 for (size_t i
= 0; i
< cd
->vtblInterfaces
->length
; i
++)
991 this->layout_base_vtable (cd
, cd
, i
);
993 /* Put out the overriding interface vtables[]. */
994 for (ClassDeclaration
*bcd
= cd
->baseClass
; bcd
; bcd
= bcd
->baseClass
)
996 for (size_t i
= 0; i
< bcd
->vtblInterfaces
->length
; i
++)
997 this->layout_base_vtable (cd
, bcd
, i
);
1002 /* Layout of TypeInfo_Interface is:
1005 TypeInfo_Class info; */
1007 void visit (TypeInfoInterfaceDeclaration
*d
)
1009 TypeClass
*ti
= d
->tinfo
->isTypeClass ();
1011 if (!ti
->sym
->vclassinfo
)
1012 ti
->sym
->vclassinfo
= TypeInfoClassDeclaration::create (ti
);
1014 /* The vtable for TypeInfo_Interface. */
1015 this->layout_base (Type::typeinfointerface
);
1017 /* TypeInfo for class inheriting the interface. */
1018 tree tidecl
= get_typeinfo_decl (ti
->sym
->vclassinfo
);
1019 this->layout_field (build_address (tidecl
));
1022 /* Layout of TypeInfo_Struct is:
1027 hash_t function(in void*) xtoHash;
1028 bool function(in void*, in void*) xopEquals;
1029 int function(in void*, in void*) xopCmp;
1030 string function(const(void)*) xtoString;
1031 StructFlags m_flags;
1032 void function(void*) xdtor;
1033 void function(void*) xpostblit;
1035 immutable(void)* xgetRTInfo; */
1037 void visit (TypeInfoStructDeclaration
*d
)
1039 TypeStruct
*ti
= d
->tinfo
->isTypeStruct ();
1040 StructDeclaration
*sd
= ti
->sym
;
1042 /* The vtable for TypeInfo_Struct. */
1043 this->layout_base (Type::typeinfostruct
);
1048 /* Mangled name of the struct declaration. */
1049 this->layout_string (ti
->deco
);
1051 /* Default initializer for struct. */
1052 tree ptr
= (sd
->zeroInit
) ? null_pointer_node
1053 : build_address (aggregate_initializer_decl (sd
));
1054 this->layout_field (d_array_value (array_type_node
,
1055 size_int (sd
->structsize
), ptr
));
1057 /* hash_t function (in void*) xtoHash; */
1058 tree xhash
= (sd
->xhash
) ? build_address (get_symbol_decl (sd
->xhash
))
1059 : null_pointer_node
;
1060 this->layout_field (xhash
);
1064 TypeFunction
*tf
= sd
->xhash
->type
->toTypeFunction ();
1065 if (!tf
->isnothrow () || tf
->trust
== TRUST::system
)
1067 warning (sd
->xhash
->loc
, "toHash() must be declared as "
1068 "extern (D) size_t toHash() const nothrow @safe, "
1069 "not %s", tf
->toChars ());
1073 /* bool function(in void*, in void*) xopEquals; */
1074 tree xeq
= (sd
->xeq
) ? build_address (get_symbol_decl (sd
->xeq
))
1075 : null_pointer_node
;
1076 this->layout_field (xeq
);
1078 /* int function(in void*, in void*) xopCmp; */
1079 tree xcmp
= (sd
->xcmp
) ? build_address (get_symbol_decl (sd
->xcmp
))
1080 : null_pointer_node
;
1081 this->layout_field (xcmp
);
1083 /* string function(const(void)*) xtoString; */
1084 FuncDeclaration
*fdx
= search_toString (sd
);
1086 this->layout_field (build_address (get_symbol_decl (fdx
)));
1088 this->layout_field (null_pointer_node
);
1090 /* StructFlags m_flags; */
1091 int m_flags
= StructFlags::none
;
1092 if (ti
->hasPointers ())
1093 m_flags
|= StructFlags::hasPointers
;
1094 this->layout_field (build_integer_cst (m_flags
, d_uint_type
));
1096 /* void function(void*) xdtor; */
1097 tree dtor
= (sd
->tidtor
) ? build_address (get_symbol_decl (sd
->tidtor
))
1098 : null_pointer_node
;
1099 this->layout_field (dtor
);
1101 /* void function(void*) xpostblit; */
1102 if (sd
->postblit
&& !(sd
->postblit
->storage_class
& STCdisable
))
1103 this->layout_field (build_address (get_symbol_decl (sd
->postblit
)));
1105 this->layout_field (null_pointer_node
);
1108 this->layout_field (build_integer_cst (ti
->alignsize (), d_uint_type
));
1110 /* immutable(void)* xgetRTInfo; */
1112 this->layout_field (build_expr (sd
->getRTInfo
, true));
1113 else if (m_flags
& StructFlags::hasPointers
)
1114 this->layout_field (size_one_node
);
1117 /* Layout of TypeInfo_Tuple is:
1120 TypeInfo[] elements; */
1122 void visit (TypeInfoTupleDeclaration
*d
)
1124 TypeTuple
*ti
= d
->tinfo
->isTypeTuple ();
1126 /* The vtable for TypeInfo_Tuple. */
1127 this->layout_base (Type::typeinfotypelist
);
1129 /* TypeInfo[] elements; */
1130 Type
*satype
= Type::tvoidptr
->sarrayOf (ti
->arguments
->length
);
1131 vec
<constructor_elt
, va_gc
> *elms
= NULL
;
1132 for (size_t i
= 0; i
< ti
->arguments
->length
; i
++)
1134 Parameter
*arg
= (*ti
->arguments
)[i
];
1135 CONSTRUCTOR_APPEND_ELT (elms
, size_int (i
),
1136 build_typeinfo (d
->loc
, arg
->type
));
1138 tree ctor
= build_constructor (build_ctype (satype
), elms
);
1139 tree decl
= this->internal_reference (ctor
);
1141 tree length
= size_int (ti
->arguments
->length
);
1142 tree ptr
= build_address (decl
);
1143 this->layout_field (d_array_value (array_type_node
, length
, ptr
));
1145 rest_of_decl_compilation (decl
, 1, 0);
1150 /* Main entry point for TypeInfoVisitor interface to generate
1151 TypeInfo constructor for the TypeInfoDeclaration AST class D. */
1154 layout_typeinfo (TypeInfoDeclaration
*d
)
1156 if (!Type::dtypeinfo
)
1157 create_frontend_tinfo_types ();
1159 TypeInfoVisitor v
= TypeInfoVisitor (get_typeinfo_decl (d
));
1164 /* Like layout_typeinfo, but generates the TypeInfo_Class for
1165 the class or interface declaration CD. */
1168 layout_classinfo (ClassDeclaration
*cd
)
1170 if (!Type::dtypeinfo
)
1171 create_frontend_tinfo_types ();
1173 TypeInfoClassDeclaration
*d
= TypeInfoClassDeclaration::create (cd
->type
);
1174 TypeInfoVisitor v
= TypeInfoVisitor (get_classinfo_decl (cd
));
1179 /* Get the offset to the BC's vtbl[] initializer from the start of CD.
1180 Returns "~0u" if the base class is not found in any vtable interfaces. */
1183 base_vtable_offset (ClassDeclaration
*cd
, BaseClass
*bc
)
1185 unsigned csymoffset
= int_size_in_bytes (tinfo_types
[TK_CLASSINFO_TYPE
]);
1186 unsigned interfacesize
= int_size_in_bytes (vtbl_interface_type_node
);
1187 csymoffset
+= cd
->vtblInterfaces
->length
* interfacesize
;
1189 for (size_t i
= 0; i
< cd
->vtblInterfaces
->length
; i
++)
1191 BaseClass
*b
= (*cd
->vtblInterfaces
)[i
];
1194 csymoffset
+= b
->sym
->vtbl
.length
* target
.ptrsize
;
1197 /* Check all overriding interface vtbl[]s. */
1198 for (ClassDeclaration
*cd2
= cd
->baseClass
; cd2
; cd2
= cd2
->baseClass
)
1200 for (size_t k
= 0; k
< cd2
->vtblInterfaces
->length
; k
++)
1202 BaseClass
*bs
= (*cd2
->vtblInterfaces
)[k
];
1203 if (bs
->fillVtbl (cd
, NULL
, 0))
1207 csymoffset
+= bs
->sym
->vtbl
.length
* target
.ptrsize
;
1215 /* Layout fields that immediately come after the classinfo type for DECL if
1216 there's any interfaces or interface vtables to be added.
1217 This must be mirrored with base_vtable_offset(). */
1220 layout_classinfo_interfaces (ClassDeclaration
*decl
)
1222 tree type
= tinfo_types
[TK_CLASSINFO_TYPE
];
1223 size_t structsize
= int_size_in_bytes (type
);
1225 if (decl
->vtblInterfaces
->length
)
1227 size_t interfacesize
= int_size_in_bytes (vtbl_interface_type_node
);
1230 type
= copy_aggregate_type (type
);
1232 /* First layout the static array of Interface, which provides information
1233 about the vtables that follow. */
1234 tree domain
= size_int (decl
->vtblInterfaces
->length
- 1);
1235 tree arrtype
= build_array_type (vtbl_interface_type_node
,
1236 build_index_type (domain
));
1237 field
= create_field_decl (arrtype
, NULL
, 1, 1);
1238 insert_aggregate_field (type
, field
, structsize
);
1239 structsize
+= decl
->vtblInterfaces
->length
* interfacesize
;
1241 /* For each interface, layout each vtable. */
1242 for (size_t i
= 0; i
< decl
->vtblInterfaces
->length
; i
++)
1244 BaseClass
*b
= (*decl
->vtblInterfaces
)[i
];
1245 ClassDeclaration
*id
= b
->sym
;
1246 unsigned offset
= base_vtable_offset (decl
, b
);
1248 if (id
->vtbl
.length
&& offset
!= ~0u)
1251 = build_index_type (size_int (id
->vtbl
.length
- 1));
1252 tree vtbltype
= build_array_type (vtable_entry_type
, vtbldomain
);
1254 field
= create_field_decl (vtbltype
, NULL
, 1, 1);
1255 insert_aggregate_field (type
, field
, offset
);
1256 structsize
+= id
->vtbl
.length
* target
.ptrsize
;
1261 /* Layout the arrays of overriding interface vtables. */
1262 for (ClassDeclaration
*bcd
= decl
->baseClass
; bcd
; bcd
= bcd
->baseClass
)
1264 for (size_t i
= 0; i
< bcd
->vtblInterfaces
->length
; i
++)
1266 BaseClass
*b
= (*bcd
->vtblInterfaces
)[i
];
1267 ClassDeclaration
*id
= b
->sym
;
1268 unsigned offset
= base_vtable_offset (decl
, b
);
1270 if (id
->vtbl
.length
&& offset
!= ~0u)
1272 if (type
== tinfo_types
[TK_CLASSINFO_TYPE
])
1273 type
= copy_aggregate_type (type
);
1276 = build_index_type (size_int (id
->vtbl
.length
- 1));
1277 tree vtbltype
= build_array_type (vtable_entry_type
, vtbldomain
);
1279 tree field
= create_field_decl (vtbltype
, NULL
, 1, 1);
1280 insert_aggregate_field (type
, field
, offset
);
1281 structsize
+= id
->vtbl
.length
* target
.ptrsize
;
1286 /* Update the type size and record mode for the classinfo type. */
1287 if (type
!= tinfo_types
[TK_CLASSINFO_TYPE
])
1288 finish_aggregate_type (structsize
, TYPE_ALIGN_UNIT (type
), type
);
1293 /* Returns true if the TypeInfo for TYPE should be placed in
1294 the runtime library. */
1297 builtin_typeinfo_p (Type
*type
)
1299 if (type
->isTypeBasic () || type
->ty
== TY::Tclass
|| type
->ty
== TY::Tnull
)
1302 if (type
->ty
== TY::Tarray
)
1304 /* Strings are so common, make them builtin. */
1305 Type
*next
= type
->nextOf ();
1307 && ((next
->isTypeBasic () != NULL
&& !next
->mod
)
1308 || (next
->ty
== TY::Tchar
&& next
->mod
== MODimmutable
)
1309 || (next
->ty
== TY::Tchar
&& next
->mod
== MODconst
));
1315 /* Implements a visitor interface to create the decl tree for TypeInfo decls.
1316 TypeInfo_Class objects differ in that they also have information about
1317 the class type packed immediately after the TypeInfo symbol.
1319 If the frontend had an interface to allow distinguishing being these two
1320 AST types, then that would be better for us. */
1322 class TypeInfoDeclVisitor
: public Visitor
1324 using Visitor::visit
;
1327 TypeInfoDeclVisitor (void)
1331 void visit (TypeInfoDeclaration
*tid
)
1333 tree ident
= get_identifier (tid
->ident
->toChars ());
1334 tree type
= tinfo_types
[get_typeinfo_kind (tid
->tinfo
)];
1335 gcc_assert (type
!= NULL_TREE
);
1337 /* Built-in typeinfo will be referenced as one-only. */
1338 tid
->csym
= declare_extern_var (ident
, type
);
1339 DECL_LANG_SPECIFIC (tid
->csym
) = build_lang_decl (tid
);
1341 DECL_CONTEXT (tid
->csym
) = d_decl_context (tid
);
1342 TREE_READONLY (tid
->csym
) = 1;
1345 void visit (TypeInfoClassDeclaration
*tid
)
1347 TypeClass
*tc
= tid
->tinfo
->isTypeClass ();
1348 tid
->csym
= get_classinfo_decl (tc
->sym
);
1352 /* Get the VAR_DECL of the TypeInfo for DECL. If this does not yet exist,
1353 create it. The TypeInfo decl provides information about the type of a given
1354 expression or object. */
1357 get_typeinfo_decl (TypeInfoDeclaration
*decl
)
1362 gcc_assert (decl
->tinfo
->ty
!= TY::Terror
);
1364 TypeInfoDeclVisitor v
= TypeInfoDeclVisitor ();
1366 gcc_assert (decl
->csym
!= NULL_TREE
);
1371 /* Get the VAR_DECL of the ClassInfo for DECL. If this does not yet exist,
1372 create it. The ClassInfo decl provides information about the dynamic type
1373 of a given class type or object. */
1376 get_classinfo_decl (ClassDeclaration
*decl
)
1381 InterfaceDeclaration
*id
= decl
->isInterfaceDeclaration ();
1382 tree ident
= mangle_internal_decl (decl
, id
? "__Interface" : "__Class", "Z");
1383 tree type
= layout_classinfo_interfaces (decl
);
1385 decl
->csym
= declare_extern_var (ident
, type
);
1386 DECL_LANG_SPECIFIC (decl
->csym
) = build_lang_decl (NULL
);
1388 /* Class is a reference, want the record type. */
1389 DECL_CONTEXT (decl
->csym
) = TREE_TYPE (build_ctype (decl
->type
));
1390 /* ClassInfo cannot be const data, because we use the monitor on it. */
1391 TREE_READONLY (decl
->csym
) = 0;
1396 /* Performs sanity checks on the `object.TypeInfo' type, raising an error if
1397 RTTI is disabled, or the type is missing. */
1400 check_typeinfo_type (const Loc
&loc
, Scope
*sc
)
1402 if (!global
.params
.useTypeInfo
)
1404 static int warned
= 0;
1406 /* Even when compiling without RTTI we should still be able to evaluate
1407 TypeInfo at compile-time, just not at run-time. */
1408 if (!warned
&& (!sc
|| !(sc
->flags
& SCOPEctfe
)))
1410 error_at (make_location_t (loc
),
1411 "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
1416 if (Type::dtypeinfo
== NULL
1417 || (Type::dtypeinfo
->storage_class
& STCtemp
))
1419 /* If TypeInfo has not been declared, warn about each location once. */
1422 if (loc
.filename
&& !warnloc
.equals (loc
))
1424 error_at (make_location_t (loc
),
1425 "%<object.TypeInfo%> could not be found, "
1426 "but is implicitly used");
1432 /* Returns typeinfo reference for TYPE. */
1435 build_typeinfo (const Loc
&loc
, Type
*type
)
1437 gcc_assert (type
->ty
!= TY::Terror
);
1438 check_typeinfo_type (loc
, NULL
);
1439 create_typeinfo (type
, NULL
);
1440 return build_address (get_typeinfo_decl (type
->vtinfo
));
1443 /* Like layout_classinfo, but generates an Object that wraps around a
1444 pointer to C++ type_info so it can be distinguished from D TypeInfo. */
1447 layout_cpp_typeinfo (ClassDeclaration
*cd
)
1449 if (!Type::dtypeinfo
)
1450 create_frontend_tinfo_types ();
1452 gcc_assert (cd
->isCPPclass ());
1454 tree decl
= get_cpp_typeinfo_decl (cd
);
1455 vec
<constructor_elt
, va_gc
> *init
= NULL
;
1457 /* Use the vtable of __cpp_type_info_ptr, the EH personality routine
1458 expects this, as it uses .classinfo identity comparison to test for
1459 C++ catch handlers. */
1460 ClassDeclaration
*cppti
= ClassDeclaration::cpp_type_info_ptr
;
1461 if (have_typeinfo_p (cppti
))
1463 tree vptr
= get_vtable_decl (cppti
);
1464 CONSTRUCTOR_APPEND_ELT (init
, NULL_TREE
, build_address (vptr
));
1467 CONSTRUCTOR_APPEND_ELT (init
, NULL_TREE
, null_pointer_node
);
1469 if (cppti
->hasMonitor ())
1470 CONSTRUCTOR_APPEND_ELT (init
, NULL_TREE
, null_pointer_node
);
1472 /* Let C++ do the RTTI generation, and just reference the symbol as
1473 extern, knowing the underlying type is not required. */
1474 const char *ident
= target
.cpp
.typeInfoMangle (cd
);
1475 tree typeinfo
= declare_extern_var (get_identifier (ident
),
1477 TREE_READONLY (typeinfo
) = 1;
1478 CONSTRUCTOR_APPEND_ELT (init
, NULL_TREE
, build_address (typeinfo
));
1480 /* Build the initializer and emit. */
1481 DECL_INITIAL (decl
) = build_struct_literal (TREE_TYPE (decl
), init
);
1482 d_finish_decl (decl
);
1485 /* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet
1486 exist, create it. The __cpp_type_info_ptr decl is then initialized with a
1487 pointer to the C++ type_info for the given class. */
1490 get_cpp_typeinfo_decl (ClassDeclaration
*decl
)
1492 gcc_assert (decl
->isCPPclass ());
1494 if (decl
->cpp_type_info_ptr_sym
)
1495 return decl
->cpp_type_info_ptr_sym
;
1497 if (!tinfo_types
[TK_CPPTI_TYPE
])
1498 make_internal_typeinfo (TK_CPPTI_TYPE
,
1499 Identifier::idPool ("__cpp_type_info_ptr"),
1500 ptr_type_node
, NULL
);
1502 tree ident
= mangle_internal_decl (decl
, "_cpp_type_info_ptr", "");
1503 tree type
= tinfo_types
[TK_CPPTI_TYPE
];
1505 decl
->cpp_type_info_ptr_sym
= declare_extern_var (ident
, type
);
1506 DECL_LANG_SPECIFIC (decl
->cpp_type_info_ptr_sym
) = build_lang_decl (NULL
);
1508 /* Class is a reference, want the record type. */
1509 DECL_CONTEXT (decl
->cpp_type_info_ptr_sym
)
1510 = TREE_TYPE (build_ctype (decl
->type
));
1511 TREE_READONLY (decl
->cpp_type_info_ptr_sym
) = 1;
1513 /* Layout the initializer and emit the symbol. */
1514 layout_cpp_typeinfo (decl
);
1516 return decl
->cpp_type_info_ptr_sym
;
1519 /* Get the exact TypeInfo for TYPE, if it doesn't exist, create it. */
1522 create_typeinfo (Type
*type
, Module
*mod
)
1524 if (!Type::dtypeinfo
)
1525 create_frontend_tinfo_types ();
1527 /* Do this since not all Type's are merged. */
1528 Type
*t
= type
->merge2 ();
1533 tinfo_kind tk
= get_typeinfo_kind (t
);
1536 case TK_SHARED_TYPE
:
1538 case TK_IMMUTABLE_TYPE
:
1540 case TK_POINTER_TYPE
:
1542 case TK_VECTOR_TYPE
:
1543 case TK_INTERFACE_TYPE
:
1544 /* Kinds of TypeInfo that add one extra pointer field. */
1545 if (tk
== TK_SHARED_TYPE
)
1547 /* Does both `shared' and `shared const'. */
1548 t
->vtinfo
= TypeInfoSharedDeclaration::create (t
);
1549 ident
= Identifier::idPool ("TypeInfo_Shared");
1551 else if (tk
== TK_CONST_TYPE
)
1553 t
->vtinfo
= TypeInfoConstDeclaration::create (t
);
1554 ident
= Identifier::idPool ("TypeInfo_Const");
1556 else if (tk
== TK_IMMUTABLE_TYPE
)
1558 t
->vtinfo
= TypeInfoInvariantDeclaration::create (t
);
1559 ident
= Identifier::idPool ("TypeInfo_Invariant");
1561 else if (tk
== TK_INOUT_TYPE
)
1563 t
->vtinfo
= TypeInfoWildDeclaration::create (t
);
1564 ident
= Identifier::idPool ("TypeInfo_Wild");
1566 else if (tk
== TK_POINTER_TYPE
)
1568 t
->vtinfo
= TypeInfoPointerDeclaration::create (t
);
1569 ident
= Identifier::idPool ("TypeInfo_Pointer");
1571 else if (tk
== TK_ARRAY_TYPE
)
1573 t
->vtinfo
= TypeInfoArrayDeclaration::create (t
);
1574 ident
= Identifier::idPool ("TypeInfo_Array");
1576 else if (tk
== TK_VECTOR_TYPE
)
1578 t
->vtinfo
= TypeInfoVectorDeclaration::create (t
);
1579 ident
= Identifier::idPool ("TypeInfo_Vector");
1581 else if (tk
== TK_INTERFACE_TYPE
)
1583 t
->vtinfo
= TypeInfoInterfaceDeclaration::create (t
);
1584 ident
= Identifier::idPool ("TypeInfo_Interface");
1589 if (!tinfo_types
[tk
])
1590 make_internal_typeinfo (tk
, ident
, ptr_type_node
, NULL
);
1593 case TK_STATICARRAY_TYPE
:
1594 if (!tinfo_types
[tk
])
1596 ident
= Identifier::idPool ("TypeInfo_StaticArray");
1597 make_internal_typeinfo (tk
, ident
, ptr_type_node
, size_type_node
,
1600 t
->vtinfo
= TypeInfoStaticArrayDeclaration::create (t
);
1603 case TK_ASSOCIATIVEARRAY_TYPE
:
1604 if (!tinfo_types
[tk
])
1606 ident
= Identifier::idPool ("TypeInfo_AssociativeArray");
1607 make_internal_typeinfo (tk
, ident
, ptr_type_node
, ptr_type_node
,
1610 t
->vtinfo
= TypeInfoAssociativeArrayDeclaration::create (t
);
1613 case TK_STRUCT_TYPE
:
1614 if (!tinfo_types
[tk
])
1616 ident
= Identifier::idPool ("TypeInfo_Struct");
1617 make_internal_typeinfo (tk
, ident
,
1618 array_type_node
, array_type_node
,
1619 ptr_type_node
, ptr_type_node
,
1620 ptr_type_node
, ptr_type_node
,
1621 d_uint_type
, ptr_type_node
,
1622 ptr_type_node
, d_uint_type
,
1623 ptr_type_node
, NULL
);
1625 t
->vtinfo
= TypeInfoStructDeclaration::create (t
);
1628 case TK_ENUMERAL_TYPE
:
1629 if (!tinfo_types
[tk
])
1631 ident
= Identifier::idPool ("TypeInfo_Enum");
1632 make_internal_typeinfo (tk
, ident
,
1633 ptr_type_node
, array_type_node
,
1634 array_type_node
, NULL
);
1636 t
->vtinfo
= TypeInfoEnumDeclaration::create (t
);
1639 case TK_FUNCTION_TYPE
:
1640 case TK_DELEGATE_TYPE
:
1641 /* Functions and delegates share a common TypeInfo layout. */
1642 if (tk
== TK_FUNCTION_TYPE
)
1644 t
->vtinfo
= TypeInfoFunctionDeclaration::create (t
);
1645 ident
= Identifier::idPool ("TypeInfo_Function");
1647 else if (tk
== TK_DELEGATE_TYPE
)
1649 t
->vtinfo
= TypeInfoDelegateDeclaration::create (t
);
1650 ident
= Identifier::idPool ("TypeInfo_Delegate");
1655 if (!tinfo_types
[tk
])
1656 make_internal_typeinfo (tk
, ident
, ptr_type_node
,
1657 array_type_node
, NULL
);
1660 case TK_TYPELIST_TYPE
:
1661 if (!tinfo_types
[tk
])
1663 ident
= Identifier::idPool ("TypeInfo_Tuple");
1664 make_internal_typeinfo (tk
, ident
, array_type_node
, NULL
);
1666 t
->vtinfo
= TypeInfoTupleDeclaration::create (t
);
1669 case TK_CLASSINFO_TYPE
:
1670 t
->vtinfo
= TypeInfoClassDeclaration::create (t
);
1674 t
->vtinfo
= TypeInfoDeclaration::create (t
);
1676 gcc_assert (t
->vtinfo
);
1678 /* If this has a custom implementation in rt/typeinfo, then
1679 do not generate a COMDAT for it. */
1680 if (!builtin_typeinfo_p (t
))
1682 /* Find module that will go all the way to an object file. */
1684 mod
->members
->push (t
->vtinfo
);
1686 build_decl_tree (t
->vtinfo
);
1689 /* Types aren't merged, but we can share the vtinfo's. */
1691 type
->vtinfo
= t
->vtinfo
;
1693 gcc_assert (type
->vtinfo
!= NULL
);
1696 /* Implements a visitor interface to check whether a type is speculative.
1697 TypeInfo_Struct would reference the members of the struct it is representing
1698 (e.g: opEquals via xopEquals field), so if it's instantiated in speculative
1699 context, TypeInfo creation should also be stopped to avoid possible
1700 `unresolved symbol' linker errors. */
1702 class SpeculativeTypeVisitor
: public Visitor
1704 using Visitor::visit
;
1709 SpeculativeTypeVisitor (void)
1711 this->result_
= false;
1716 return this->result_
;
1719 void visit (Type
*t
)
1721 Type
*tb
= t
->toBasetype ();
1726 void visit (TypeNext
*t
)
1729 t
->next
->accept (this);
1732 void visit (TypeBasic
*)
1736 void visit (TypeVector
*t
)
1738 t
->basetype
->accept (this);
1741 void visit (TypeAArray
*t
)
1743 t
->index
->accept (this);
1744 visit ((TypeNext
*) t
);
1747 void visit (TypeFunction
*t
)
1749 visit ((TypeNext
*) t
);
1752 void visit (TypeStruct
*t
)
1754 StructDeclaration
*sd
= t
->sym
;
1755 if (TemplateInstance
*ti
= sd
->isInstantiated ())
1757 if (!ti
->needsCodegen ())
1759 if (ti
->minst
|| sd
->requestTypeInfo
)
1762 this->result_
|= true;
1767 void visit (TypeClass
*t
)
1769 ClassDeclaration
*cd
= t
->sym
;
1770 if (TemplateInstance
*ti
= cd
->isInstantiated ())
1772 if (!ti
->needsCodegen () && !ti
->minst
)
1774 this->result_
|= true;
1779 void visit (TypeTuple
*t
)
1784 for (size_t i
= 0; i
< t
->arguments
->length
; i
++)
1786 Type
*tprm
= (*t
->arguments
)[i
]->type
;
1788 tprm
->accept (this);
1795 /* Return true if type was instantiated in a speculative context. */
1798 speculative_type_p (Type
*t
)
1800 SpeculativeTypeVisitor v
= SpeculativeTypeVisitor ();
1805 #include "gt-d-typeinfo.h"