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