]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/d/typeinfo.cc
d: Merge upstream dmd 48d704f08
[thirdparty/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 (((TypeClass *) type)->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), size_int (id->vtbl.length));
455 CONSTRUCTOR_APPEND_ELT (v, size_int (2), value);
456 }
457
458 /* The 'this' offset. */
459 CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));
460
461 /* Add to the array of interfaces. */
462 value = build_constructor (vtbl_interface_type_node, v);
463 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
464 }
465
466 tree domain = size_int (cd->vtblInterfaces->length - 1);
467 tree arrtype = build_array_type (vtbl_interface_type_node,
468 build_index_type (domain));
469 return build_constructor (arrtype, elms);
470 }
471
472 /* Write out the interfacing vtable[] of base class BCD that will be accessed
473 from the overriding class CD. If both are the same class, then this will
474 be its own vtable. INDEX is the offset in the interfaces array of the
475 base class where the Interface reference can be found.
476 This must be mirrored with base_vtable_offset(). */
477
478 void layout_base_vtable (ClassDeclaration *cd, ClassDeclaration *bcd,
479 size_t index)
480 {
481 BaseClass *bs = (*bcd->vtblInterfaces)[index];
482 ClassDeclaration *id = bs->sym;
483 vec<constructor_elt, va_gc> *elms = NULL;
484 FuncDeclarations bvtbl;
485
486 if (id->vtbl.length == 0 || base_vtable_offset (cd, bs) == ~0u)
487 return;
488
489 /* Fill bvtbl with the functions we want to put out. */
490 if (cd != bcd && !bs->fillVtbl (cd, &bvtbl, 0))
491 return;
492
493 /* First entry is struct Interface reference. */
494 if (id->vtblOffset ())
495 {
496 size_t offset = int_size_in_bytes (tinfo_types[TK_CLASSINFO_TYPE]);
497 offset += (index * int_size_in_bytes (vtbl_interface_type_node));
498 tree value = build_offset (build_address (get_classinfo_decl (bcd)),
499 size_int (offset));
500 CONSTRUCTOR_APPEND_ELT (elms, size_zero_node, value);
501 }
502
503 for (size_t i = id->vtblOffset () ? 1 : 0; i < id->vtbl.length; i++)
504 {
505 FuncDeclaration *fd = (cd == bcd) ? bs->vtbl[i] : bvtbl[i];
506 if (fd != NULL)
507 {
508 tree value = build_address (make_thunk (fd, bs->offset));
509 CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
510 }
511 }
512
513 tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
514 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
515 tree value = build_constructor (vtbltype, elms);
516 this->layout_field (value);
517 }
518
519
520 public:
521 TypeInfoVisitor (tree decl)
522 {
523 this->decl_ = decl;
524 this->init_ = NULL;
525 }
526
527 /* Return the completed constructor for the TypeInfo record. */
528
529 tree result (void)
530 {
531 return build_struct_literal (TREE_TYPE (this->decl_), this->init_);
532 }
533
534 /* Layout of TypeInfo is:
535 void **__vptr;
536 void *__monitor; */
537
538 void visit (TypeInfoDeclaration *)
539 {
540 /* The vtable for TypeInfo. */
541 this->layout_base (Type::dtypeinfo);
542 }
543
544 /* Layout of TypeInfo_Const is:
545 void **__vptr;
546 void *__monitor;
547 TypeInfo base; */
548
549 void visit (TypeInfoConstDeclaration *d)
550 {
551 Type *tm = d->tinfo->mutableOf ();
552 tm = tm->merge2 ();
553
554 /* The vtable for TypeInfo_Const. */
555 this->layout_base (Type::typeinfoconst);
556
557 /* TypeInfo for the mutable type. */
558 this->layout_field (build_typeinfo (d->loc, tm));
559 }
560
561 /* Layout of TypeInfo_Immutable is:
562 void **__vptr;
563 void *__monitor;
564 TypeInfo base; */
565
566 void visit (TypeInfoInvariantDeclaration *d)
567 {
568 Type *tm = d->tinfo->mutableOf ();
569 tm = tm->merge2 ();
570
571 /* The vtable for TypeInfo_Invariant. */
572 this->layout_base (Type::typeinfoinvariant);
573
574 /* TypeInfo for the mutable type. */
575 this->layout_field (build_typeinfo (d->loc, tm));
576 }
577
578 /* Layout of TypeInfo_Shared is:
579 void **__vptr;
580 void *__monitor;
581 TypeInfo base; */
582
583 void visit (TypeInfoSharedDeclaration *d)
584 {
585 Type *tm = d->tinfo->unSharedOf ();
586 tm = tm->merge2 ();
587
588 /* The vtable for TypeInfo_Shared. */
589 this->layout_base (Type::typeinfoshared);
590
591 /* TypeInfo for the unshared type. */
592 this->layout_field (build_typeinfo (d->loc, tm));
593 }
594
595 /* Layout of TypeInfo_Inout is:
596 void **__vptr;
597 void *__monitor;
598 TypeInfo base; */
599
600 void visit (TypeInfoWildDeclaration *d)
601 {
602 Type *tm = d->tinfo->mutableOf ();
603 tm = tm->merge2 ();
604
605 /* The vtable for TypeInfo_Inout. */
606 this->layout_base (Type::typeinfowild);
607
608 /* TypeInfo for the mutable type. */
609 this->layout_field (build_typeinfo (d->loc, tm));
610 }
611
612 /* Layout of TypeInfo_Enum is:
613 void **__vptr;
614 void *__monitor;
615 TypeInfo base;
616 string name;
617 void[] m_init; */
618
619 void visit (TypeInfoEnumDeclaration *d)
620 {
621 gcc_assert (d->tinfo->ty == Tenum);
622 TypeEnum *ti = (TypeEnum *) d->tinfo;
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 gcc_assert (d->tinfo->ty == Tpointer);
655 TypePointer *ti = (TypePointer *) d->tinfo;
656
657 /* The vtable for TypeInfo_Pointer. */
658 this->layout_base (Type::typeinfopointer);
659
660 /* TypeInfo for pointer-to type. */
661 this->layout_field (build_typeinfo (d->loc, ti->next));
662 }
663
664 /* Layout of TypeInfo_Array is:
665 void **__vptr;
666 void *__monitor;
667 TypeInfo value; */
668
669 void visit (TypeInfoArrayDeclaration *d)
670 {
671 gcc_assert (d->tinfo->ty == Tarray);
672 TypeDArray *ti = (TypeDArray *) d->tinfo;
673
674 /* The vtable for TypeInfo_Array. */
675 this->layout_base (Type::typeinfoarray);
676
677 /* TypeInfo for array of type. */
678 this->layout_field (build_typeinfo (d->loc, ti->next));
679 }
680
681 /* Layout of TypeInfo_StaticArray is:
682 void **__vptr;
683 void *__monitor;
684 TypeInfo value;
685 size_t len; */
686
687 void visit (TypeInfoStaticArrayDeclaration *d)
688 {
689 gcc_assert (d->tinfo->ty == Tsarray);
690 TypeSArray *ti = (TypeSArray *) d->tinfo;
691
692 /* The vtable for TypeInfo_StaticArray. */
693 this->layout_base (Type::typeinfostaticarray);
694
695 /* TypeInfo for array of type. */
696 this->layout_field (build_typeinfo (d->loc, ti->next));
697
698 /* Static array length. */
699 this->layout_field (size_int (ti->dim->toInteger ()));
700 }
701
702 /* Layout of TypeInfo_AssociativeArray is:
703 void **__vptr;
704 void *__monitor;
705 TypeInfo value;
706 TypeInfo key; */
707
708 void visit (TypeInfoAssociativeArrayDeclaration *d)
709 {
710 gcc_assert (d->tinfo->ty == Taarray);
711 TypeAArray *ti = (TypeAArray *) d->tinfo;
712
713 /* The vtable for TypeInfo_AssociativeArray. */
714 this->layout_base (Type::typeinfoassociativearray);
715
716 /* TypeInfo for value of type. */
717 this->layout_field (build_typeinfo (d->loc, ti->next));
718
719 /* TypeInfo for index of type. */
720 this->layout_field (build_typeinfo (d->loc, ti->index));
721 }
722
723 /* Layout of TypeInfo_Vector is:
724 void **__vptr;
725 void *__monitor;
726 TypeInfo base; */
727
728 void visit (TypeInfoVectorDeclaration *d)
729 {
730 gcc_assert (d->tinfo->ty == Tvector);
731 TypeVector *ti = (TypeVector *) d->tinfo;
732
733 /* The vtable for TypeInfo_Vector. */
734 this->layout_base (Type::typeinfovector);
735
736 /* TypeInfo for equivalent static array. */
737 this->layout_field (build_typeinfo (d->loc, ti->basetype));
738 }
739
740 /* Layout of TypeInfo_Function is:
741 void **__vptr;
742 void *__monitor;
743 TypeInfo next;
744 string deco; */
745
746 void visit (TypeInfoFunctionDeclaration *d)
747 {
748 gcc_assert (d->tinfo->ty == Tfunction && d->tinfo->deco != NULL);
749 TypeFunction *ti = (TypeFunction *) d->tinfo;
750
751 /* The vtable for TypeInfo_Function. */
752 this->layout_base (Type::typeinfofunction);
753
754 /* TypeInfo for function return value. */
755 this->layout_field (build_typeinfo (d->loc, ti->next));
756
757 /* Mangled name of function declaration. */
758 this->layout_string (d->tinfo->deco);
759 }
760
761 /* Layout of TypeInfo_Delegate is:
762 void **__vptr;
763 void *__monitor;
764 TypeInfo next;
765 string deco; */
766
767 void visit (TypeInfoDelegateDeclaration *d)
768 {
769 gcc_assert (d->tinfo->ty == Tdelegate && d->tinfo->deco != NULL);
770 TypeDelegate *ti = (TypeDelegate *) d->tinfo;
771
772 /* The vtable for TypeInfo_Delegate. */
773 this->layout_base (Type::typeinfodelegate);
774
775 /* TypeInfo for delegate return value. */
776 this->layout_field (build_typeinfo (d->loc, ti->next));
777
778 /* Mangled name of delegate declaration. */
779 this->layout_string (d->tinfo->deco);
780 }
781
782 /* Layout of ClassInfo/TypeInfo_Class is:
783 void **__vptr;
784 void *__monitor;
785 byte[] m_init;
786 string name;
787 void*[] vtbl;
788 Interface[] interfaces;
789 TypeInfo_Class base;
790 void *destructor;
791 void function(Object) classInvariant;
792 ClassFlags m_flags;
793 void *deallocator;
794 OffsetTypeInfo[] m_offTi;
795 void function(Object) defaultConstructor;
796 immutable(void)* m_RTInfo;
797
798 Information relating to interfaces, and their vtables are laid out
799 immediately after the named fields, if there is anything to write. */
800
801 void visit (TypeInfoClassDeclaration *d)
802 {
803 gcc_assert (d->tinfo->ty == Tclass);
804 TypeClass *ti = (TypeClass *) d->tinfo;
805 ClassDeclaration *cd = ti->sym;
806
807 /* The vtable for ClassInfo. */
808 this->layout_base (Type::typeinfoclass);
809
810 if (!cd->members)
811 return;
812
813 tree interfaces = NULL_TREE;
814
815 if (!cd->isInterfaceDeclaration ())
816 {
817 /* Default initializer for class. */
818 tree init = aggregate_initializer_decl (cd);
819 tree value = d_array_value (array_type_node, size_int (cd->structsize),
820 build_address (init));
821 this->layout_field (value);
822
823 /* Name of the class declaration. */
824 const char *name = cd->ident->toChars ();
825 if (!(strlen (name) > 9 && memcmp (name, "TypeInfo_", 9) == 0))
826 name = cd->toPrettyChars ();
827 this->layout_string (name);
828
829 /* The vtable of the class declaration. */
830 value = d_array_value (array_type_node, size_int (cd->vtbl.length),
831 build_address (get_vtable_decl (cd)));
832 this->layout_field (value);
833
834 /* Array of base interfaces that have their own vtable. */
835 if (cd->vtblInterfaces->length)
836 interfaces = this->layout_interfaces (cd);
837 else
838 this->layout_field (null_array_node);
839
840 /* TypeInfo_Class base; */
841 tree base = (cd->baseClass)
842 ? build_address (get_classinfo_decl (cd->baseClass))
843 : null_pointer_node;
844 this->layout_field (base);
845
846 /* void *destructor; */
847 tree dtor = (cd->dtor) ? build_address (get_symbol_decl (cd->dtor))
848 : null_pointer_node;
849 this->layout_field (dtor);
850
851 /* void function(Object) classInvariant; */
852 tree inv = (cd->inv) ? build_address (get_symbol_decl (cd->inv))
853 : null_pointer_node;
854 this->layout_field (inv);
855
856 /* ClassFlags m_flags; */
857 ClassFlags::Type flags = ClassFlags::hasOffTi;
858 if (cd->isCOMclass ())
859 flags |= ClassFlags::isCOMclass;
860
861 if (cd->isCPPclass ())
862 flags |= ClassFlags::isCPPclass;
863
864 flags |= ClassFlags::hasGetMembers;
865 flags |= ClassFlags::hasTypeInfo;
866
867 if (cd->ctor)
868 flags |= ClassFlags::hasCtor;
869
870 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
871 {
872 if (bcd->dtor)
873 {
874 flags |= ClassFlags::hasDtor;
875 break;
876 }
877 }
878
879 if (cd->isAbstract ())
880 flags |= ClassFlags::isAbstract;
881
882 for (ClassDeclaration *bcd = cd; bcd; bcd = bcd->baseClass)
883 {
884 if (!bcd->members)
885 continue;
886
887 for (size_t i = 0; i < bcd->members->length; i++)
888 {
889 Dsymbol *sm = (*bcd->members)[i];
890 if (sm->hasPointers ())
891 goto Lhaspointers;
892 }
893 }
894
895 flags |= ClassFlags::noPointers;
896
897 Lhaspointers:
898 this->layout_field (build_integer_cst (flags, d_uint_type));
899
900 /* void *deallocator; */
901 tree ddtor = (cd->aggDelete)
902 ? build_address (get_symbol_decl (cd->aggDelete))
903 : null_pointer_node;
904 this->layout_field (ddtor);
905
906 /* OffsetTypeInfo[] m_offTi; (not implemented) */
907 this->layout_field (null_array_node);
908
909 /* void function(Object) defaultConstructor; */
910 if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable))
911 {
912 tree dctor = get_symbol_decl (cd->defaultCtor);
913 this->layout_field (build_address (dctor));
914 }
915 else
916 this->layout_field (null_pointer_node);
917
918 /* immutable(void)* m_RTInfo; */
919 if (cd->getRTInfo)
920 this->layout_field (build_expr (cd->getRTInfo, true));
921 else if (!(flags & ClassFlags::noPointers))
922 this->layout_field (size_one_node);
923 }
924 else
925 {
926 /* No initializer for interface. */
927 this->layout_field (null_array_node);
928
929 /* Name of the interface declaration. */
930 this->layout_string (cd->toPrettyChars ());
931
932 /* No vtable for interface declaration. */
933 this->layout_field (null_array_node);
934
935 /* Array of base interfaces that have their own vtable. */
936 if (cd->vtblInterfaces->length)
937 interfaces = this->layout_interfaces (cd);
938 else
939 this->layout_field (null_array_node);
940
941 /* TypeInfo_Class base;
942 void *destructor;
943 void function(Object) classInvariant; */
944 this->layout_field (null_pointer_node);
945 this->layout_field (null_pointer_node);
946 this->layout_field (null_pointer_node);
947
948 /* ClassFlags m_flags; */
949 ClassFlags::Type flags = ClassFlags::hasOffTi;
950 flags |= ClassFlags::hasTypeInfo;
951 if (cd->isCOMinterface ())
952 flags |= ClassFlags::isCOMclass;
953
954 this->layout_field (build_integer_cst (flags, d_uint_type));
955
956 /* void *deallocator;
957 OffsetTypeInfo[] m_offTi; (not implemented)
958 void function(Object) defaultConstructor; */
959 this->layout_field (null_pointer_node);
960 this->layout_field (null_array_node);
961 this->layout_field (null_pointer_node);
962
963 /* immutable(void)* m_RTInfo; */
964 if (cd->getRTInfo)
965 this->layout_field (build_expr (cd->getRTInfo, true));
966 else
967 this->layout_field (null_pointer_node);
968 }
969
970 /* Put out array of Interfaces. */
971 if (interfaces != NULL_TREE)
972 this->layout_field (interfaces);
973
974 if (!cd->isInterfaceDeclaration ())
975 {
976 /* Put out this class' interface vtables[]. */
977 for (size_t i = 0; i < cd->vtblInterfaces->length; i++)
978 this->layout_base_vtable (cd, cd, i);
979
980 /* Put out the overriding interface vtables[]. */
981 for (ClassDeclaration *bcd = cd->baseClass; bcd; bcd = bcd->baseClass)
982 {
983 for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
984 this->layout_base_vtable (cd, bcd, i);
985 }
986 }
987 }
988
989 /* Layout of TypeInfo_Interface is:
990 void **__vptr;
991 void *__monitor;
992 TypeInfo_Class info; */
993
994 void visit (TypeInfoInterfaceDeclaration *d)
995 {
996 gcc_assert (d->tinfo->ty == Tclass);
997 TypeClass *ti = (TypeClass *) d->tinfo;
998
999 if (!ti->sym->vclassinfo)
1000 ti->sym->vclassinfo = TypeInfoClassDeclaration::create (ti);
1001
1002 /* The vtable for TypeInfo_Interface. */
1003 this->layout_base (Type::typeinfointerface);
1004
1005 /* TypeInfo for class inheriting the interface. */
1006 tree tidecl = get_typeinfo_decl (ti->sym->vclassinfo);
1007 this->layout_field (build_address (tidecl));
1008 }
1009
1010 /* Layout of TypeInfo_Struct is:
1011 void **__vptr;
1012 void *__monitor;
1013 string name;
1014 void[] m_init;
1015 hash_t function(in void*) xtoHash;
1016 bool function(in void*, in void*) xopEquals;
1017 int function(in void*, in void*) xopCmp;
1018 string function(const(void)*) xtoString;
1019 StructFlags m_flags;
1020 void function(void*) xdtor;
1021 void function(void*) xpostblit;
1022 uint m_align;
1023 version (X86_64)
1024 TypeInfo m_arg1;
1025 TypeInfo m_arg2;
1026 immutable(void)* xgetRTInfo; */
1027
1028 void visit (TypeInfoStructDeclaration *d)
1029 {
1030 gcc_assert (d->tinfo->ty == Tstruct);
1031 TypeStruct *ti = (TypeStruct *) d->tinfo;
1032 StructDeclaration *sd = ti->sym;
1033
1034 /* The vtable for TypeInfo_Struct. */
1035 this->layout_base (Type::typeinfostruct);
1036
1037 if (!sd->members)
1038 return;
1039
1040 /* Name of the struct declaration. */
1041 this->layout_string (sd->toPrettyChars ());
1042
1043 /* Default initializer for struct. */
1044 tree ptr = (sd->zeroInit) ? null_pointer_node
1045 : build_address (aggregate_initializer_decl (sd));
1046 this->layout_field (d_array_value (array_type_node,
1047 size_int (sd->structsize), ptr));
1048
1049 /* hash_t function (in void*) xtoHash; */
1050 tree xhash = (sd->xhash) ? build_address (get_symbol_decl (sd->xhash))
1051 : null_pointer_node;
1052 this->layout_field (xhash);
1053
1054 if (sd->xhash)
1055 {
1056 TypeFunction *tf = (TypeFunction *) sd->xhash->type;
1057 gcc_assert (tf->ty == Tfunction);
1058 if (!tf->isnothrow || tf->trust == TRUSTsystem)
1059 {
1060 warning (sd->xhash->loc, "toHash() must be declared as "
1061 "extern (D) size_t toHash() const nothrow @safe, "
1062 "not %s", tf->toChars ());
1063 }
1064 }
1065
1066 /* bool function(in void*, in void*) xopEquals; */
1067 tree xeq = (sd->xeq) ? build_address (get_symbol_decl (sd->xeq))
1068 : null_pointer_node;
1069 this->layout_field (xeq);
1070
1071 /* int function(in void*, in void*) xopCmp; */
1072 tree xcmp = (sd->xcmp) ? build_address (get_symbol_decl (sd->xcmp))
1073 : null_pointer_node;
1074 this->layout_field (xcmp);
1075
1076 /* string function(const(void)*) xtoString; */
1077 FuncDeclaration *fdx = search_toString (sd);
1078 if (fdx)
1079 this->layout_field (build_address (get_symbol_decl (fdx)));
1080 else
1081 this->layout_field (null_pointer_node);
1082
1083 /* StructFlags m_flags; */
1084 StructFlags::Type m_flags = 0;
1085 if (ti->hasPointers ())
1086 m_flags |= StructFlags::hasPointers;
1087 this->layout_field (build_integer_cst (m_flags, d_uint_type));
1088
1089 /* void function(void*) xdtor; */
1090 tree dtor = (sd->dtor) ? build_address (get_symbol_decl (sd->dtor))
1091 : null_pointer_node;
1092 this->layout_field (dtor);
1093
1094 /* void function(void*) xpostblit; */
1095 if (sd->postblit && !(sd->postblit->storage_class & STCdisable))
1096 this->layout_field (build_address (get_symbol_decl (sd->postblit)));
1097 else
1098 this->layout_field (null_pointer_node);
1099
1100 /* uint m_align; */
1101 this->layout_field (build_integer_cst (ti->alignsize (), d_uint_type));
1102
1103 if (global.params.is64bit)
1104 {
1105 /* TypeInfo m_arg1; */
1106 tree arg1type = (sd->arg1type) ? build_typeinfo (d->loc, sd->arg1type)
1107 : null_pointer_node;
1108 this->layout_field (arg1type);
1109
1110 /* TypeInfo m_arg2; */
1111 tree arg2type = (sd->arg2type) ? build_typeinfo (d->loc, sd->arg2type)
1112 : null_pointer_node;
1113 this->layout_field (arg2type);
1114 }
1115
1116 /* immutable(void)* xgetRTInfo; */
1117 if (sd->getRTInfo)
1118 this->layout_field (build_expr (sd->getRTInfo, true));
1119 else if (m_flags & StructFlags::hasPointers)
1120 this->layout_field (size_one_node);
1121 }
1122
1123 /* Layout of TypeInfo_Tuple is:
1124 void **__vptr;
1125 void *__monitor;
1126 TypeInfo[] elements; */
1127
1128 void visit (TypeInfoTupleDeclaration *d)
1129 {
1130 gcc_assert (d->tinfo->ty == Ttuple);
1131 TypeTuple *ti = (TypeTuple *) d->tinfo;
1132
1133 /* The vtable for TypeInfo_Tuple. */
1134 this->layout_base (Type::typeinfotypelist);
1135
1136 /* TypeInfo[] elements; */
1137 Type *satype = Type::tvoidptr->sarrayOf (ti->arguments->length);
1138 vec<constructor_elt, va_gc> *elms = NULL;
1139 for (size_t i = 0; i < ti->arguments->length; i++)
1140 {
1141 Parameter *arg = (*ti->arguments)[i];
1142 CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
1143 build_typeinfo (d->loc, arg->type));
1144 }
1145 tree ctor = build_constructor (build_ctype (satype), elms);
1146 tree decl = this->internal_reference (ctor);
1147
1148 tree length = size_int (ti->arguments->length);
1149 tree ptr = build_address (decl);
1150 this->layout_field (d_array_value (array_type_node, length, ptr));
1151
1152 rest_of_decl_compilation (decl, 1, 0);
1153 }
1154 };
1155
1156
1157 /* Main entry point for TypeInfoVisitor interface to generate
1158 TypeInfo constructor for the TypeInfoDeclaration AST class D. */
1159
1160 tree
1161 layout_typeinfo (TypeInfoDeclaration *d)
1162 {
1163 if (!Type::dtypeinfo)
1164 create_frontend_tinfo_types ();
1165
1166 TypeInfoVisitor v = TypeInfoVisitor (get_typeinfo_decl (d));
1167 d->accept (&v);
1168 return v.result ();
1169 }
1170
1171 /* Like layout_typeinfo, but generates the TypeInfo_Class for
1172 the class or interface declaration CD. */
1173
1174 tree
1175 layout_classinfo (ClassDeclaration *cd)
1176 {
1177 if (!Type::dtypeinfo)
1178 create_frontend_tinfo_types ();
1179
1180 TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
1181 TypeInfoVisitor v = TypeInfoVisitor (get_classinfo_decl (cd));
1182 d->accept (&v);
1183 return v.result ();
1184 }
1185
1186 /* Layout fields that immediately come after the classinfo type for DECL if
1187 there's any interfaces or interface vtables to be added.
1188 This must be mirrored with base_vtable_offset(). */
1189
1190 static tree
1191 layout_classinfo_interfaces (ClassDeclaration *decl)
1192 {
1193 tree type = tinfo_types[TK_CLASSINFO_TYPE];
1194 size_t structsize = int_size_in_bytes (type);
1195
1196 if (decl->vtblInterfaces->length)
1197 {
1198 size_t interfacesize = int_size_in_bytes (vtbl_interface_type_node);
1199 tree field;
1200
1201 type = copy_aggregate_type (type);
1202
1203 /* First layout the static array of Interface, which provides information
1204 about the vtables that follow. */
1205 tree domain = size_int (decl->vtblInterfaces->length - 1);
1206 tree arrtype = build_array_type (vtbl_interface_type_node,
1207 build_index_type (domain));
1208 field = create_field_decl (arrtype, NULL, 1, 1);
1209 insert_aggregate_field (type, field, structsize);
1210 structsize += decl->vtblInterfaces->length * interfacesize;
1211
1212 /* For each interface, layout each vtable. */
1213 for (size_t i = 0; i < decl->vtblInterfaces->length; i++)
1214 {
1215 BaseClass *b = (*decl->vtblInterfaces)[i];
1216 ClassDeclaration *id = b->sym;
1217 unsigned offset = base_vtable_offset (decl, b);
1218
1219 if (id->vtbl.length && offset != ~0u)
1220 {
1221 tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
1222 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1223
1224 field = create_field_decl (vtbltype, NULL, 1, 1);
1225 insert_aggregate_field (type, field, offset);
1226 structsize += id->vtbl.length * Target::ptrsize;
1227 }
1228 }
1229 }
1230
1231 /* Layout the arrays of overriding interface vtables. */
1232 for (ClassDeclaration *bcd = decl->baseClass; bcd; bcd = bcd->baseClass)
1233 {
1234 for (size_t i = 0; i < bcd->vtblInterfaces->length; i++)
1235 {
1236 BaseClass *b = (*bcd->vtblInterfaces)[i];
1237 ClassDeclaration *id = b->sym;
1238 unsigned offset = base_vtable_offset (decl, b);
1239
1240 if (id->vtbl.length && offset != ~0u)
1241 {
1242 if (type == tinfo_types[TK_CLASSINFO_TYPE])
1243 type = copy_aggregate_type (type);
1244
1245 tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
1246 tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
1247
1248 tree field = create_field_decl (vtbltype, NULL, 1, 1);
1249 insert_aggregate_field (type, field, offset);
1250 structsize += id->vtbl.length * Target::ptrsize;
1251 }
1252 }
1253 }
1254
1255 /* Update the type size and record mode for the classinfo type. */
1256 if (type != tinfo_types[TK_CLASSINFO_TYPE])
1257 finish_aggregate_type (structsize, TYPE_ALIGN_UNIT (type), type);
1258
1259 return type;
1260 }
1261
1262 /* Returns true if the TypeInfo for TYPE should be placed in
1263 the runtime library. */
1264
1265 static bool
1266 builtin_typeinfo_p (Type *type)
1267 {
1268 if (type->isTypeBasic () || type->ty == Tclass || type->ty == Tnull)
1269 return !type->mod;
1270
1271 if (type->ty == Tarray)
1272 {
1273 /* Strings are so common, make them builtin. */
1274 Type *next = type->nextOf ();
1275 return !type->mod
1276 && ((next->isTypeBasic () != NULL && !next->mod)
1277 || (next->ty == Tchar && next->mod == MODimmutable)
1278 || (next->ty == Tchar && next->mod == MODconst));
1279 }
1280
1281 return false;
1282 }
1283
1284 /* Implements a visitor interface to create the decl tree for TypeInfo decls.
1285 TypeInfo_Class objects differ in that they also have information about
1286 the class type packed immediately after the TypeInfo symbol.
1287
1288 If the frontend had an interface to allow distinguishing being these two
1289 AST types, then that would be better for us. */
1290
1291 class TypeInfoDeclVisitor : public Visitor
1292 {
1293 using Visitor::visit;
1294
1295 public:
1296 TypeInfoDeclVisitor (void)
1297 {
1298 }
1299
1300 void visit (TypeInfoDeclaration *tid)
1301 {
1302 tree ident = get_identifier (tid->ident->toChars ());
1303 tree type = tinfo_types[get_typeinfo_kind (tid->tinfo)];
1304 gcc_assert (type != NULL_TREE);
1305
1306 tid->csym = declare_extern_var (ident, type);
1307 DECL_LANG_SPECIFIC (tid->csym) = build_lang_decl (tid);
1308
1309 DECL_CONTEXT (tid->csym) = d_decl_context (tid);
1310 TREE_READONLY (tid->csym) = 1;
1311
1312 /* Built-in typeinfo will be referenced as one-only. */
1313 gcc_assert (!tid->isInstantiated ());
1314
1315 if (builtin_typeinfo_p (tid->tinfo))
1316 d_linkonce_linkage (tid->csym);
1317 else
1318 d_comdat_linkage (tid->csym);
1319 }
1320
1321 void visit (TypeInfoClassDeclaration *tid)
1322 {
1323 gcc_assert (tid->tinfo->ty == Tclass);
1324 TypeClass *tc = (TypeClass *) tid->tinfo;
1325 tid->csym = get_classinfo_decl (tc->sym);
1326 }
1327 };
1328
1329 /* Get the VAR_DECL of the TypeInfo for DECL. If this does not yet exist,
1330 create it. The TypeInfo decl provides information about the type of a given
1331 expression or object. */
1332
1333 tree
1334 get_typeinfo_decl (TypeInfoDeclaration *decl)
1335 {
1336 if (decl->csym)
1337 return decl->csym;
1338
1339 gcc_assert (decl->tinfo->ty != Terror);
1340
1341 TypeInfoDeclVisitor v = TypeInfoDeclVisitor ();
1342 decl->accept (&v);
1343 gcc_assert (decl->csym != NULL_TREE);
1344
1345 return decl->csym;
1346 }
1347
1348 /* Get the VAR_DECL of the ClassInfo for DECL. If this does not yet exist,
1349 create it. The ClassInfo decl provides information about the dynamic type
1350 of a given class type or object. */
1351
1352 tree
1353 get_classinfo_decl (ClassDeclaration *decl)
1354 {
1355 if (decl->csym)
1356 return decl->csym;
1357
1358 InterfaceDeclaration *id = decl->isInterfaceDeclaration ();
1359 tree ident = mangle_internal_decl (decl, id ? "__Interface" : "__Class", "Z");
1360 tree type = layout_classinfo_interfaces (decl);
1361
1362 decl->csym = declare_extern_var (ident, type);
1363 DECL_LANG_SPECIFIC (decl->csym) = build_lang_decl (NULL);
1364
1365 /* Class is a reference, want the record type. */
1366 DECL_CONTEXT (decl->csym) = TREE_TYPE (build_ctype (decl->type));
1367 /* ClassInfo cannot be const data, because we use the monitor on it. */
1368 TREE_READONLY (decl->csym) = 0;
1369
1370 return decl->csym;
1371 }
1372
1373 /* Returns typeinfo reference for TYPE. */
1374
1375 tree
1376 build_typeinfo (const Loc &loc, Type *type)
1377 {
1378 if (!global.params.useTypeInfo)
1379 {
1380 static int warned = 0;
1381
1382 if (!warned)
1383 {
1384 error_at (make_location_t (loc),
1385 "%<object.TypeInfo%> cannot be used with %<-fno-rtti%>");
1386 warned = 1;
1387 }
1388 }
1389
1390 gcc_assert (type->ty != Terror);
1391 create_typeinfo (type, NULL);
1392 return build_address (get_typeinfo_decl (type->vtinfo));
1393 }
1394
1395 /* Like layout_classinfo, but generates an Object that wraps around a
1396 pointer to C++ type_info so it can be distinguished from D TypeInfo. */
1397
1398 void
1399 layout_cpp_typeinfo (ClassDeclaration *cd)
1400 {
1401 if (!Type::dtypeinfo)
1402 create_frontend_tinfo_types ();
1403
1404 gcc_assert (cd->isCPPclass ());
1405
1406 tree decl = get_cpp_typeinfo_decl (cd);
1407 vec<constructor_elt, va_gc> *init = NULL;
1408
1409 /* Use the vtable of __cpp_type_info_ptr, the EH personality routine
1410 expects this, as it uses .classinfo identity comparison to test for
1411 C++ catch handlers. */
1412 tree vptr = get_vtable_decl (ClassDeclaration::cpp_type_info_ptr);
1413 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (vptr));
1414 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, null_pointer_node);
1415
1416 /* Let C++ do the RTTI generation, and just reference the symbol as
1417 extern, knowing the underlying type is not required. */
1418 const char *ident = Target::cppTypeInfoMangle (cd);
1419 tree typeinfo = declare_extern_var (get_identifier (ident),
1420 unknown_type_node);
1421 TREE_READONLY (typeinfo) = 1;
1422 CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_address (typeinfo));
1423
1424 /* Build the initializer and emit. */
1425 DECL_INITIAL (decl) = build_struct_literal (TREE_TYPE (decl), init);
1426 DECL_EXTERNAL (decl) = 0;
1427 d_pushdecl (decl);
1428 rest_of_decl_compilation (decl, 1, 0);
1429 }
1430
1431 /* Get the VAR_DECL of the __cpp_type_info_ptr for DECL. If this does not yet
1432 exist, create it. The __cpp_type_info_ptr decl is then initialized with a
1433 pointer to the C++ type_info for the given class. */
1434
1435 tree
1436 get_cpp_typeinfo_decl (ClassDeclaration *decl)
1437 {
1438 gcc_assert (decl->isCPPclass ());
1439
1440 if (decl->cpp_type_info_ptr_sym)
1441 return decl->cpp_type_info_ptr_sym;
1442
1443 if (!tinfo_types[TK_CPPTI_TYPE])
1444 make_internal_typeinfo (TK_CPPTI_TYPE,
1445 Identifier::idPool ("__cpp_type_info_ptr"),
1446 ptr_type_node, NULL);
1447
1448 tree ident = mangle_internal_decl (decl, "_cpp_type_info_ptr", "");
1449 tree type = tinfo_types[TK_CPPTI_TYPE];
1450
1451 decl->cpp_type_info_ptr_sym = declare_extern_var (ident, type);
1452 DECL_LANG_SPECIFIC (decl->cpp_type_info_ptr_sym) = build_lang_decl (NULL);
1453
1454 /* Class is a reference, want the record type. */
1455 DECL_CONTEXT (decl->cpp_type_info_ptr_sym)
1456 = TREE_TYPE (build_ctype (decl->type));
1457 TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;
1458
1459 d_comdat_linkage (decl->cpp_type_info_ptr_sym);
1460
1461 /* Layout the initializer and emit the symbol. */
1462 layout_cpp_typeinfo (decl);
1463
1464 return decl->cpp_type_info_ptr_sym;
1465 }
1466
1467 /* Get the exact TypeInfo for TYPE, if it doesn't exist, create it. */
1468
1469 void
1470 create_typeinfo (Type *type, Module *mod)
1471 {
1472 if (!Type::dtypeinfo)
1473 create_frontend_tinfo_types ();
1474
1475 /* Do this since not all Type's are merged. */
1476 Type *t = type->merge2 ();
1477 Identifier *ident;
1478
1479 if (!t->vtinfo)
1480 {
1481 tinfo_kind tk = get_typeinfo_kind (t);
1482 switch (tk)
1483 {
1484 case TK_SHARED_TYPE:
1485 case TK_CONST_TYPE:
1486 case TK_IMMUTABLE_TYPE:
1487 case TK_INOUT_TYPE:
1488 case TK_POINTER_TYPE:
1489 case TK_ARRAY_TYPE:
1490 case TK_VECTOR_TYPE:
1491 case TK_INTERFACE_TYPE:
1492 /* Kinds of TypeInfo that add one extra pointer field. */
1493 if (tk == TK_SHARED_TYPE)
1494 {
1495 /* Does both 'shared' and 'shared const'. */
1496 t->vtinfo = TypeInfoSharedDeclaration::create (t);
1497 ident = Identifier::idPool ("TypeInfo_Shared");
1498 }
1499 else if (tk == TK_CONST_TYPE)
1500 {
1501 t->vtinfo = TypeInfoConstDeclaration::create (t);
1502 ident = Identifier::idPool ("TypeInfo_Const");
1503 }
1504 else if (tk == TK_IMMUTABLE_TYPE)
1505 {
1506 t->vtinfo = TypeInfoInvariantDeclaration::create (t);
1507 ident = Identifier::idPool ("TypeInfo_Invariant");
1508 }
1509 else if (tk == TK_INOUT_TYPE)
1510 {
1511 t->vtinfo = TypeInfoWildDeclaration::create (t);
1512 ident = Identifier::idPool ("TypeInfo_Wild");
1513 }
1514 else if (tk == TK_POINTER_TYPE)
1515 {
1516 t->vtinfo = TypeInfoPointerDeclaration::create (t);
1517 ident = Identifier::idPool ("TypeInfo_Pointer");
1518 }
1519 else if (tk == TK_ARRAY_TYPE)
1520 {
1521 t->vtinfo = TypeInfoArrayDeclaration::create (t);
1522 ident = Identifier::idPool ("TypeInfo_Array");
1523 }
1524 else if (tk == TK_VECTOR_TYPE)
1525 {
1526 t->vtinfo = TypeInfoVectorDeclaration::create (t);
1527 ident = Identifier::idPool ("TypeInfo_Vector");
1528 }
1529 else if (tk == TK_INTERFACE_TYPE)
1530 {
1531 t->vtinfo = TypeInfoInterfaceDeclaration::create (t);
1532 ident = Identifier::idPool ("TypeInfo_Interface");
1533 }
1534 else
1535 gcc_unreachable ();
1536
1537 if (!tinfo_types[tk])
1538 make_internal_typeinfo (tk, ident, ptr_type_node, NULL);
1539 break;
1540
1541 case TK_STATICARRAY_TYPE:
1542 if (!tinfo_types[tk])
1543 {
1544 ident = Identifier::idPool ("TypeInfo_StaticArray");
1545 make_internal_typeinfo (tk, ident, ptr_type_node, size_type_node,
1546 NULL);
1547 }
1548 t->vtinfo = TypeInfoStaticArrayDeclaration::create (t);
1549 break;
1550
1551 case TK_ASSOCIATIVEARRAY_TYPE:
1552 if (!tinfo_types[tk])
1553 {
1554 ident = Identifier::idPool ("TypeInfo_AssociativeArray");
1555 make_internal_typeinfo (tk, ident, ptr_type_node, ptr_type_node,
1556 NULL);
1557 }
1558 t->vtinfo = TypeInfoAssociativeArrayDeclaration::create (t);
1559 break;
1560
1561 case TK_STRUCT_TYPE:
1562 if (!tinfo_types[tk])
1563 {
1564 /* Some ABIs add extra TypeInfo fields on the end. */
1565 tree argtype = global.params.is64bit ? ptr_type_node : NULL_TREE;
1566
1567 ident = Identifier::idPool ("TypeInfo_Struct");
1568 make_internal_typeinfo (tk, ident,
1569 array_type_node, array_type_node,
1570 ptr_type_node, ptr_type_node,
1571 ptr_type_node, ptr_type_node,
1572 d_uint_type, ptr_type_node,
1573 ptr_type_node, d_uint_type,
1574 ptr_type_node, argtype, argtype, NULL);
1575 }
1576 t->vtinfo = TypeInfoStructDeclaration::create (t);
1577 break;
1578
1579 case TK_ENUMERAL_TYPE:
1580 if (!tinfo_types[tk])
1581 {
1582 ident = Identifier::idPool ("TypeInfo_Enum");
1583 make_internal_typeinfo (tk, ident,
1584 ptr_type_node, array_type_node,
1585 array_type_node, NULL);
1586 }
1587 t->vtinfo = TypeInfoEnumDeclaration::create (t);
1588 break;
1589
1590 case TK_FUNCTION_TYPE:
1591 case TK_DELEGATE_TYPE:
1592 /* Functions and delegates share a common TypeInfo layout. */
1593 if (tk == TK_FUNCTION_TYPE)
1594 {
1595 t->vtinfo = TypeInfoFunctionDeclaration::create (t);
1596 ident = Identifier::idPool ("TypeInfo_Function");
1597 }
1598 else if (tk == TK_DELEGATE_TYPE)
1599 {
1600 t->vtinfo = TypeInfoDelegateDeclaration::create (t);
1601 ident = Identifier::idPool ("TypeInfo_Delegate");
1602 }
1603 else
1604 gcc_unreachable ();
1605
1606 if (!tinfo_types[tk])
1607 make_internal_typeinfo (tk, ident, ptr_type_node,
1608 array_type_node, NULL);
1609 break;
1610
1611 case TK_TYPELIST_TYPE:
1612 if (!tinfo_types[tk])
1613 {
1614 ident = Identifier::idPool ("TypeInfo_Tuple");
1615 make_internal_typeinfo (tk, ident, array_type_node, NULL);
1616 }
1617 t->vtinfo = TypeInfoTupleDeclaration::create (t);
1618 break;
1619
1620 case TK_CLASSINFO_TYPE:
1621 t->vtinfo = TypeInfoClassDeclaration::create (t);
1622 break;
1623
1624 default:
1625 t->vtinfo = TypeInfoDeclaration::create (t);
1626 }
1627 gcc_assert (t->vtinfo);
1628
1629 /* If this has a custom implementation in rt/typeinfo, then
1630 do not generate a COMDAT for it. */
1631 if (!builtin_typeinfo_p (t))
1632 {
1633 /* Find module that will go all the way to an object file. */
1634 if (mod)
1635 mod->members->push (t->vtinfo);
1636 else
1637 build_decl_tree (t->vtinfo);
1638 }
1639 }
1640 /* Types aren't merged, but we can share the vtinfo's. */
1641 if (!type->vtinfo)
1642 type->vtinfo = t->vtinfo;
1643
1644 gcc_assert (type->vtinfo != NULL);
1645 }
1646
1647 /* Implements a visitor interface to check whether a type is speculative.
1648 TypeInfo_Struct would reference the members of the struct it is representing
1649 (e.g: opEquals via xopEquals field), so if it's instantiated in speculative
1650 context, TypeInfo creation should also be stopped to avoid possible
1651 `unresolved symbol' linker errors. */
1652
1653 class SpeculativeTypeVisitor : public Visitor
1654 {
1655 using Visitor::visit;
1656
1657 bool result_;
1658
1659 public:
1660 SpeculativeTypeVisitor (void)
1661 {
1662 this->result_ = false;
1663 }
1664
1665 bool result (void)
1666 {
1667 return this->result_;
1668 }
1669
1670 void visit (Type *t)
1671 {
1672 Type *tb = t->toBasetype ();
1673 if (tb != t)
1674 tb->accept (this);
1675 }
1676
1677 void visit (TypeNext *t)
1678 {
1679 if (t->next)
1680 t->next->accept (this);
1681 }
1682
1683 void visit (TypeBasic *)
1684 {
1685 }
1686
1687 void visit (TypeVector *t)
1688 {
1689 t->basetype->accept (this);
1690 }
1691
1692 void visit (TypeAArray *t)
1693 {
1694 t->index->accept (this);
1695 visit ((TypeNext *)t);
1696 }
1697
1698 void visit (TypeFunction *t)
1699 {
1700 visit ((TypeNext *)t);
1701 }
1702
1703 void visit (TypeStruct *t)
1704 {
1705 StructDeclaration *sd = t->sym;
1706 if (TemplateInstance *ti = sd->isInstantiated ())
1707 {
1708 if (!ti->needsCodegen ())
1709 {
1710 if (ti->minst || sd->requestTypeInfo)
1711 return;
1712
1713 this->result_ |= true;
1714 }
1715 }
1716 }
1717
1718 void visit (TypeClass *t)
1719 {
1720 ClassDeclaration *cd = t->sym;
1721 if (TemplateInstance *ti = cd->isInstantiated ())
1722 {
1723 if (!ti->needsCodegen () && !ti->minst)
1724 {
1725 this->result_ |= true;
1726 }
1727 }
1728 }
1729
1730 void visit (TypeTuple *t)
1731 {
1732 if (!t->arguments)
1733 return;
1734
1735 for (size_t i = 0; i < t->arguments->length; i++)
1736 {
1737 Type *tprm = (*t->arguments)[i]->type;
1738 if (tprm)
1739 tprm->accept (this);
1740 if (this->result_)
1741 return;
1742 }
1743 }
1744 };
1745
1746 /* Return true if type was instantiated in a speculative context. */
1747
1748 bool
1749 speculative_type_p (Type *t)
1750 {
1751 SpeculativeTypeVisitor v = SpeculativeTypeVisitor ();
1752 t->accept (&v);
1753 return v.result ();
1754 }
1755
1756 #include "gt-d-typeinfo.h"