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