@@ -128,7 +128,11 @@ void DtoResolveTypeInfo(TypeInfoDeclaration *tid) {
128128/* ========================================================================= */
129129
130130class LLVMDefineVisitor : public Visitor {
131+ LLGlobalVariable *const gvar;
132+
131133public:
134+ LLVMDefineVisitor (LLGlobalVariable *gvar) : gvar(gvar) {}
135+
132136 // Import all functions from class Visitor
133137 using Visitor::visit;
134138
@@ -140,7 +144,7 @@ class LLVMDefineVisitor : public Visitor {
140144 LOG_SCOPE;
141145
142146 RTTIBuilder b (Type::dtypeinfo);
143- b.finalize (getIrGlobal (decl) );
147+ b.finalize (gvar );
144148 }
145149
146150 /* ======================================================================= */
@@ -175,7 +179,7 @@ class LLVMDefineVisitor : public Visitor {
175179 }
176180
177181 // finish
178- b.finalize (getIrGlobal (decl) );
182+ b.finalize (gvar );
179183 }
180184
181185 /* ======================================================================= */
@@ -189,7 +193,7 @@ class LLVMDefineVisitor : public Visitor {
189193 // TypeInfo base
190194 b.push_typeinfo (decl->tinfo ->nextOf ());
191195 // finish
192- b.finalize (getIrGlobal (decl) );
196+ b.finalize (gvar );
193197 }
194198
195199 /* ======================================================================= */
@@ -203,7 +207,7 @@ class LLVMDefineVisitor : public Visitor {
203207 // TypeInfo base
204208 b.push_typeinfo (decl->tinfo ->nextOf ());
205209 // finish
206- b.finalize (getIrGlobal (decl) );
210+ b.finalize (gvar );
207211 }
208212
209213 /* ======================================================================= */
@@ -225,7 +229,7 @@ class LLVMDefineVisitor : public Visitor {
225229 b.push (DtoConstSize_t (static_cast <size_t >(tc->dim ->toUInteger ())));
226230
227231 // finish
228- b.finalize (getIrGlobal (decl) );
232+ b.finalize (gvar );
229233 }
230234
231235 /* ======================================================================= */
@@ -248,7 +252,7 @@ class LLVMDefineVisitor : public Visitor {
248252 b.push_typeinfo (tc->index );
249253
250254 // finish
251- b.finalize (getIrGlobal (decl) );
255+ b.finalize (gvar );
252256 }
253257
254258 /* ======================================================================= */
@@ -264,7 +268,7 @@ class LLVMDefineVisitor : public Visitor {
264268 // string deco
265269 b.push_string (decl->tinfo ->deco );
266270 // finish
267- b.finalize (getIrGlobal (decl) );
271+ b.finalize (gvar );
268272 }
269273
270274 /* ======================================================================= */
@@ -283,7 +287,7 @@ class LLVMDefineVisitor : public Visitor {
283287 // string deco
284288 b.push_string (decl->tinfo ->deco );
285289 // finish
286- b.finalize (getIrGlobal (decl) );
290+ b.finalize (gvar );
287291 }
288292
289293 /* ======================================================================= */
@@ -298,10 +302,44 @@ class LLVMDefineVisitor : public Visitor {
298302 TypeStruct *tc = static_cast <TypeStruct *>(decl->tinfo );
299303 StructDeclaration *sd = tc->sym ;
300304
305+ // On x86_64, class TypeInfo_Struct contains 2 additional fields
306+ // (m_arg1/m_arg2) which are used for the X86_64 System V ABI varargs
307+ // implementation. They are not present on any other cpu/os.
308+ const bool isX86_64 =
309+ global.params .targetTriple ->getArch () == llvm::Triple::x86_64;
310+ const unsigned expectedFields = 11 + (isX86_64 ? 2 : 0 );
311+ const unsigned actualFields =
312+ Type::typeinfostruct->fields .dim -
313+ 1 ; // union of xdtor/xdtorti counts as 2 overlapping fields
314+ if (actualFields != expectedFields) {
315+ error (Loc (), " Unexpected number of `object.TypeInfo_Struct` fields; "
316+ " druntime version does not match compiler" );
317+ fatal ();
318+ }
319+
320+ RTTIBuilder b (Type::typeinfostruct);
321+
301322 // handle opaque structs
302323 if (!sd->members ) {
303- RTTIBuilder b (Type::typeinfostruct);
304- b.finalize (getIrGlobal (decl));
324+ Logger::println (" is opaque struct, emitting dummy TypeInfo_Struct" );
325+
326+ b.push_null_void_array (); // name
327+ b.push_null_void_array (); // m_init
328+ b.push_null_vp (); // xtoHash
329+ b.push_null_vp (); // xopEquals
330+ b.push_null_vp (); // xopCmp
331+ b.push_null_vp (); // xtoString
332+ b.push_uint (0 ); // m_flags
333+ b.push_null_vp (); // xdtor/xdtorti
334+ b.push_null_vp (); // xpostblit
335+ b.push_uint (0 ); // m_align
336+ if (isX86_64) {
337+ b.push_null_vp (); // m_arg1
338+ b.push_null_vp (); // m_arg2
339+ }
340+ b.push_null_vp (); // m_RTInfo
341+
342+ b.finalize (gvar);
305343 return ;
306344 }
307345
@@ -343,19 +381,6 @@ class LLVMDefineVisitor : public Visitor {
343381 }
344382
345383 IrAggr *iraggr = getIrAggr (sd);
346- RTTIBuilder b (Type::typeinfostruct);
347-
348- // On x86_64, class TypeInfo_Struct contains 2 additional fields
349- // (m_arg1/m_arg2) which are used for the X86_64 System V ABI varargs
350- // implementation. They are not present on any other cpu/os.
351- const bool isX86_64 =
352- global.params .targetTriple ->getArch () == llvm::Triple::x86_64;
353- const unsigned expectedFields = 12 + (isX86_64 ? 2 : 0 );
354- if (Type::typeinfostruct->fields .dim != expectedFields) {
355- error (Loc (), " Unexpected number of `object.TypeInfo_Struct` fields; "
356- " druntime version does not match compiler" );
357- fatal ();
358- }
359384
360385 // string name
361386 b.push_string (sd->toPrettyChars ());
@@ -432,7 +457,7 @@ class LLVMDefineVisitor : public Visitor {
432457 }
433458
434459 // finish
435- b.finalize (getIrGlobal (decl) );
460+ b.finalize (gvar );
436461 }
437462
438463 /* ======================================================================= */
@@ -461,7 +486,7 @@ class LLVMDefineVisitor : public Visitor {
461486 b.push_classinfo (tc->sym );
462487
463488 // finish
464- b.finalize (getIrGlobal (decl) );
489+ b.finalize (gvar );
465490 }
466491
467492 /* ======================================================================= */
@@ -495,7 +520,7 @@ class LLVMDefineVisitor : public Visitor {
495520 b.push_array (arrC, dim, Type::dtypeinfo->type , nullptr );
496521
497522 // finish
498- b.finalize (getIrGlobal (decl) );
523+ b.finalize (gvar );
499524 }
500525
501526 /* ======================================================================= */
@@ -509,7 +534,7 @@ class LLVMDefineVisitor : public Visitor {
509534 // TypeInfo base
510535 b.push_typeinfo (decl->tinfo ->mutableOf ()->merge ());
511536 // finish
512- b.finalize (getIrGlobal (decl) );
537+ b.finalize (gvar );
513538 }
514539
515540 /* ======================================================================= */
@@ -523,7 +548,7 @@ class LLVMDefineVisitor : public Visitor {
523548 // TypeInfo base
524549 b.push_typeinfo (decl->tinfo ->mutableOf ()->merge ());
525550 // finish
526- b.finalize (getIrGlobal (decl) );
551+ b.finalize (gvar );
527552 }
528553
529554 /* ======================================================================= */
@@ -537,7 +562,7 @@ class LLVMDefineVisitor : public Visitor {
537562 // TypeInfo base
538563 b.push_typeinfo (decl->tinfo ->unSharedOf ()->merge ());
539564 // finish
540- b.finalize (getIrGlobal (decl) );
565+ b.finalize (gvar );
541566 }
542567
543568 /* ======================================================================= */
@@ -551,7 +576,7 @@ class LLVMDefineVisitor : public Visitor {
551576 // TypeInfo base
552577 b.push_typeinfo (decl->tinfo ->mutableOf ()->merge ());
553578 // finish
554- b.finalize (getIrGlobal (decl) );
579+ b.finalize (gvar );
555580 }
556581
557582 /* ======================================================================= */
@@ -568,7 +593,7 @@ class LLVMDefineVisitor : public Visitor {
568593 // TypeInfo base
569594 b.push_typeinfo (tv->basetype );
570595 // finish
571- b.finalize (getIrGlobal (decl) );
596+ b.finalize (gvar );
572597 }
573598};
574599
@@ -594,29 +619,22 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
594619 }
595620
596621 const auto irMangle = getIRMangledVarName (mangled, LINKd);
597- IrGlobal *irg = getIrGlobal (decl, true );
598- const LinkageWithCOMDAT lwc (LLGlobalValue::ExternalLinkage, false );
599-
600- irg->value = gIR ->module .getGlobalVariable (irMangle);
601- if (irg->value ) {
602- assert (irg->getType ()->isStructTy ());
622+ LLGlobalVariable *gvar = gIR ->module .getGlobalVariable (irMangle);
623+ if (gvar) {
624+ assert (gvar->getType ()->getContainedType (0 )->isStructTy ());
603625 } else {
604- LLType *type;
605- if (builtinTypeInfo (
606- decl->tinfo )) { // this is a declaration of a builtin __initZ var
607- type = Type::dtypeinfo->type ->ctype ->isClass ()->getMemoryLLType ();
608- } else {
609- type = LLStructType::create (gIR ->context (), decl->toPrettyChars ());
610- }
626+ LLType *type = DtoType (decl->type )->getPointerElementType ();
611627 // Create the symbol. We need to keep it mutable as the type is not declared
612628 // as immutable on the D side, and e.g. synchronized() can be used on the
613629 // implicit monitor.
614- auto g = new LLGlobalVariable (gIR ->module , type, false , lwc.first ,
615- nullptr , irMangle);
616- setLinkage (lwc, g);
617- irg->value = g;
630+ gvar =
631+ new LLGlobalVariable (gIR ->module , type, false ,
632+ LLGlobalValue::ExternalLinkage, nullptr , irMangle);
618633 }
619634
635+ IrGlobal *irg = getIrGlobal (decl, true );
636+ irg->value = gvar;
637+
620638 emitTypeMetadata (decl);
621639
622640 // check if the definition can be elided
@@ -626,8 +644,10 @@ void TypeInfoDeclaration_codegen(TypeInfoDeclaration *decl, IRState *p) {
626644 }
627645
628646 // define the TypeInfo global
629- LLVMDefineVisitor v;
647+ LLVMDefineVisitor v (gvar) ;
630648 decl->accept (&v);
649+
650+ setLinkage ({TYPEINFO_LINKAGE_TYPE, supportsCOMDAT ()}, gvar);
631651}
632652
633653/* ========================================================================= */
0 commit comments