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