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