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