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