Skip to content

Commit 7c6f96b

Browse files
committed
Emit struct & class TypeInfos incl. vtables into each referencing CU
1 parent 1c0accd commit 7c6f96b

File tree

6 files changed

+46
-51
lines changed

6 files changed

+46
-51
lines changed

gen/classes.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void DtoResolveClass(ClassDeclaration *cd) {
5656
DtoType(cd->type);
5757

5858
// create IrAggr
59-
IrClass *irAggr = getIrAggr(cd, true);
59+
getIrAggr(cd, true);
6060

6161
// make sure all fields really get their ir field
6262
for (auto vd : cd->fields) {
@@ -67,11 +67,6 @@ void DtoResolveClass(ClassDeclaration *cd) {
6767
}
6868
getIrField(vd, true);
6969
}
70-
71-
// interface only emit typeinfo and classinfo
72-
if (cd->isInterfaceDeclaration()) {
73-
irAggr->initializeInterface();
74-
}
7570
}
7671

7772
////////////////////////////////////////////////////////////////////////////////

gen/typinf.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,10 @@ LLGlobalVariable *DtoResolveTypeInfo(TypeInfoDeclaration *tid) {
503503
assert(!gIR->dcomputetarget);
504504

505505
if (!tid->ir->isResolved()) {
506-
tid->ir->setResolved();
507-
508506
DeclareOrDefineVisitor v;
509507
tid->accept(&v);
508+
509+
tid->ir->setResolved();
510510
}
511511

512512
return llvm::cast<LLGlobalVariable>(getIrValue(tid));

ir/iraggr.cpp

+7-15
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,9 @@ IrAggr::createInitializerConstant(const VarInitMap &explicitInitializers) {
174174
}
175175
}
176176

177-
// Add the initializers for the member fields. While we are traversing the
178-
// class hierarchy, use the opportunity to populate interfacesWithVtbls if
179-
// we haven't done so previously (due to e.g. ClassReferenceExp, we can
180-
// have multiple initializer constants for a single class).
181-
addFieldInitializers(constants, explicitInitializers, aggrdecl, offset,
182-
irClass && irClass->interfacesWithVtbls.empty());
177+
// Add the initializers for the member fields.
178+
unsigned dummy = 0;
179+
addFieldInitializers(constants, explicitInitializers, aggrdecl, offset, dummy);
183180

184181
// tail padding?
185182
const size_t structsize = aggrdecl->size(Loc());
@@ -218,12 +215,11 @@ IrAggr::createInitializerConstant(const VarInitMap &explicitInitializers) {
218215
void IrAggr::addFieldInitializers(
219216
llvm::SmallVectorImpl<llvm::Constant *> &constants,
220217
const VarInitMap &explicitInitializers, AggregateDeclaration *decl,
221-
unsigned &offset, bool populateInterfacesWithVtbls) {
222-
218+
unsigned &offset, unsigned &interfaceVtblIndex) {
223219
if (ClassDeclaration *cd = decl->isClassDeclaration()) {
224220
if (cd->baseClass) {
225221
addFieldInitializers(constants, explicitInitializers, cd->baseClass,
226-
offset, populateInterfacesWithVtbls);
222+
offset, interfaceVtblIndex);
227223
}
228224

229225
// has interface vtbls?
@@ -237,14 +233,10 @@ void IrAggr::addFieldInitializers(
237233
}
238234

239235
IrClass *irClass = static_cast<IrClass *>(this);
240-
size_t inter_idx = irClass->interfacesWithVtbls.size();
241236
for (auto bc : *cd->vtblInterfaces) {
242-
constants.push_back(irClass->getInterfaceVtblSymbol(bc, inter_idx));
237+
constants.push_back(irClass->getInterfaceVtblSymbol(bc, interfaceVtblIndex));
243238
offset += target.ptrsize;
244-
inter_idx++;
245-
246-
if (populateInterfacesWithVtbls)
247-
irClass->interfacesWithVtbls.push_back(bc);
239+
++interfaceVtblIndex;
248240
}
249241
}
250242
}

ir/iraggr.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class IrAggr {
103103
void addFieldInitializers(llvm::SmallVectorImpl<llvm::Constant *> &constants,
104104
const VarInitMap &explicitInitializers,
105105
AggregateDeclaration *decl, unsigned &offset,
106-
bool populateInterfacesWithVtbls);
106+
unsigned &interfaceVtblIndex);
107107
};
108108

109109
/// Represents a struct.
@@ -122,7 +122,7 @@ class IrStruct : public IrAggr {
122122
/// Represents a class/interface.
123123
class IrClass : public IrAggr {
124124
public:
125-
explicit IrClass(ClassDeclaration *cd) : IrAggr(cd) {}
125+
explicit IrClass(ClassDeclaration *cd);
126126

127127
/// Creates the __ClassZ/__InterfaceZ symbol lazily.
128128
llvm::GlobalVariable *getClassInfoSymbol(bool define = false);
@@ -133,9 +133,6 @@ class IrClass : public IrAggr {
133133
/// Defines all interface vtbls.
134134
void defineInterfaceVtbls();
135135

136-
/// Initialize interface.
137-
void initializeInterface();
138-
139136
private:
140137
/// Vtbl global.
141138
llvm::GlobalVariable *vtbl = nullptr;
@@ -157,6 +154,8 @@ class IrClass : public IrAggr {
157154
/// Corresponds to the Interface instances needed to be output.
158155
std::vector<BaseClass *> interfacesWithVtbls;
159156

157+
void addInterfaceVtbls(ClassDeclaration *cd);
158+
160159
/// Builds the __ClassZ/__InterfaceZ initializer constant lazily.
161160
llvm::Constant *getClassInfoInit();
162161

ir/irclass.cpp

+28-22
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,28 @@
4141

4242
//////////////////////////////////////////////////////////////////////////////
4343

44+
IrClass::IrClass(ClassDeclaration *cd) : IrAggr(cd) {
45+
addInterfaceVtbls(cd);
46+
47+
assert(interfacesWithVtbls.size() ==
48+
stripModifiers(type)->ctype->isClass()->getNumInterfaceVtbls() &&
49+
"inconsistent number of interface vtables in this class");
50+
}
51+
52+
void IrClass::addInterfaceVtbls(ClassDeclaration *cd) {
53+
if (cd->baseClass && !cd->isInterfaceDeclaration()) {
54+
addInterfaceVtbls(cd->baseClass);
55+
}
56+
57+
if (cd->vtblInterfaces) {
58+
for (auto bc : *cd->vtblInterfaces) {
59+
interfacesWithVtbls.push_back(bc);
60+
}
61+
}
62+
}
63+
64+
//////////////////////////////////////////////////////////////////////////////
65+
4466
LLGlobalVariable *IrClass::getVtblSymbol(bool define) {
4567
if (!vtbl) {
4668
const auto irMangle = getIRMangledVTableSymbolName(aggrdecl);
@@ -108,12 +130,15 @@ LLGlobalVariable *IrClass::getClassInfoSymbol(bool define) {
108130
node->addOperand(llvm::MDNode::get(
109131
gIR->context(), llvm::makeArrayRef(mdVals, CD_NumFields)));
110132
}
133+
134+
if (!define && DtoIsTemplateInstance(aggrdecl))
135+
define = true;
111136
}
112137

113138
if (define) {
114139
auto init = getClassInfoInit();
115140
if (!typeInfo->hasInitializer())
116-
defineGlobal(typeInfo, init, aggrdecl, true);
141+
defineGlobal(typeInfo, init, aggrdecl);
117142
}
118143

119144
return typeInfo;
@@ -711,9 +736,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
711736
if (cd->isInterfaceDeclaration()) {
712737
vtb = DtoConstSlice(DtoConstSize_t(0), getNullValue(voidptrptr_type));
713738
} else {
714-
auto itv = interfaceVtblMap.find({it->sym, i});
715-
assert(itv != interfaceVtblMap.end() && "interface vtbl not found");
716-
vtb = itv->second;
739+
vtb = getInterfaceVtblSymbol(it, i);
717740
vtb = DtoBitCast(vtb, voidptrptr_type);
718741
auto vtblSize = itc->getVtblType()->getNumContainedTypes();
719742
vtb = DtoConstSlice(DtoConstSize_t(vtblSize), vtb);
@@ -735,7 +758,7 @@ LLConstant *IrClass::getClassInfoInterfaces() {
735758
// create and apply initializer
736759
LLConstant *arr = LLConstantArray::get(array_type, constants);
737760
auto ciarr = getInterfaceArraySymbol();
738-
defineGlobal(ciarr, arr, cd, true);
761+
defineGlobal(ciarr, arr, cd);
739762

740763
// return null, only baseclass provide interfaces
741764
if (cd->vtblInterfaces->length == 0) {
@@ -753,20 +776,3 @@ LLConstant *IrClass::getClassInfoInterfaces() {
753776
// return as a slice
754777
return DtoConstSlice(DtoConstSize_t(cd->vtblInterfaces->length), ptr);
755778
}
756-
757-
//////////////////////////////////////////////////////////////////////////////
758-
759-
void IrClass::initializeInterface() {
760-
InterfaceDeclaration *base = aggrdecl->isInterfaceDeclaration();
761-
assert(base && "not interface");
762-
763-
// has interface vtbls?
764-
if (!base->vtblInterfaces) {
765-
return;
766-
}
767-
768-
for (auto bc : *base->vtblInterfaces) {
769-
// add to the interface list
770-
interfacesWithVtbls.push_back(bc);
771-
}
772-
}

ir/irstruct.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,15 @@ LLGlobalVariable* IrStruct::getTypeInfoSymbol(bool define) {
5252
getTypeInfoStructMemType(), irMangle, false);
5353

5454
emitTypeInfoMetadata(typeInfo, aggrdecl->type);
55+
56+
if (!define && DtoIsTemplateInstance(aggrdecl))
57+
define = true;
5558
}
5659

5760
if (define) {
5861
auto init = getTypeInfoInit();
5962
if (!typeInfo->hasInitializer())
60-
defineGlobal(typeInfo, init, aggrdecl, true);
63+
defineGlobal(typeInfo, init, aggrdecl);
6164
}
6265

6366
return typeInfo;

0 commit comments

Comments
 (0)