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