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