Fix vbtable indices when a class shares the vbptr with a non-virtual base
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194082 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 25f3e6f..31134be 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -295,9 +295,9 @@
Ty = Ty->getPointerTo()->getPointerTo();
VTable = CGF.Builder.CreateBitCast(VTable, Ty);
assert(VTable && "BuildVirtualCall = kext vtbl pointer is null");
- uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(GD);
+ uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
uint64_t AddressPoint =
- CGM.getVTableContext().getVTableLayout(RD)
+ CGM.getItaniumVTableContext().getVTableLayout(RD)
.getAddressPoint(BaseSubobject(RD, CharUnits::Zero()));
VTableIndex += AddressPoint;
llvm::Value *VFuncPtr =
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 540d405..9b131fd 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1062,7 +1062,7 @@
// lookup if we have multiple or virtual inheritance.
if (!isa<CXXDestructorDecl>(Method) &&
!CGM.getTarget().getCXXABI().isMicrosoft())
- VIndex = CGM.getVTableContext().getMethodVTableIndex(Method);
+ VIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(Method);
ContainingType = RecordTy;
}
@@ -1168,7 +1168,7 @@
// virtual base offset offset is -ve. The code generator emits dwarf
// expression where it expects +ve number.
BaseOffset =
- 0 - CGM.getVTableContext()
+ 0 - CGM.getItaniumVTableContext()
.getVirtualBaseOffsetOffset(RD, Base).getQuantity();
BFlags = llvm::DIDescriptor::FlagVirtual;
} else
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index 72d4220..aa687b9 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -846,7 +846,7 @@
CharUnits Offset;
if (Base->isVirtual())
Offset =
- CGM.getVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
+ CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
else {
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
Offset = Layout.getBaseClassOffset(BaseDecl);
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index 31beb02..bfff470 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -65,8 +65,8 @@
uint64_t AddressPoint;
if (VTTVT.getBase() == RD) {
// Just get the address point for the regular vtable.
- AddressPoint = VTContext.getVTableLayout(RD)
- .getAddressPoint(i->VTableBase);
+ AddressPoint =
+ ItaniumVTContext.getVTableLayout(RD).getAddressPoint(i->VTableBase);
assert(AddressPoint != 0 && "Did not find vtable address point!");
} else {
AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase);
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 996bd90..5d657b0 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -30,12 +30,12 @@
using namespace CodeGen;
CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
- : CGM(CGM), VTContext(CGM.getContext()) {
+ : CGM(CGM), ItaniumVTContext(CGM.getContext()) {
if (CGM.getTarget().getCXXABI().isMicrosoft()) {
// FIXME: Eventually, we should only have one of V*TContexts available.
// Today we use both in the Microsoft ABI as MicrosoftVFTableContext
// is not completely supported in CodeGen yet.
- VFTContext.reset(new MicrosoftVFTableContext(CGM.getContext()));
+ MicrosoftVTContext.reset(new MicrosoftVTableContext(CGM.getContext()));
}
}
@@ -439,10 +439,10 @@
return;
const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector;
- if (VFTContext.isValid()) {
- ThunkInfoVector = VFTContext->getThunkInfo(GD);
+ if (MicrosoftVTContext.isValid()) {
+ ThunkInfoVector = MicrosoftVTContext->getThunkInfo(GD);
} else {
- ThunkInfoVector = VTContext.getThunkInfo(GD);
+ ThunkInfoVector = ItaniumVTContext.getThunkInfo(GD);
}
if (!ThunkInfoVector)
@@ -581,9 +581,8 @@
DI->completeClassData(Base.getBase());
OwningPtr<VTableLayout> VTLayout(
- VTContext.createConstructionVTableLayout(Base.getBase(),
- Base.getBaseOffset(),
- BaseIsVirtual, RD));
+ ItaniumVTContext.createConstructionVTableLayout(
+ Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
// Add the address points.
AddressPoints = VTLayout->getAddressPoints();
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
index 7c94a07..e8cd55e 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -31,10 +31,10 @@
class CodeGenVTables {
CodeGenModule &CGM;
- // FIXME: Consider moving VTContext and VFTContext into respective CXXABI
- // classes?
- ItaniumVTableContext VTContext;
- OwningPtr<MicrosoftVFTableContext> VFTContext;
+ // FIXME: Consider moving ItaniumVTContext and MicrosoftVTContext into
+ // respective CXXABI classes?
+ ItaniumVTableContext ItaniumVTContext;
+ OwningPtr<MicrosoftVTableContext> MicrosoftVTContext;
/// VTableAddressPointsMapTy - Address points for a single vtable.
typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
@@ -72,9 +72,11 @@
CodeGenVTables(CodeGenModule &CGM);
- ItaniumVTableContext &getVTableContext() { return VTContext; }
+ ItaniumVTableContext &getItaniumVTableContext() { return ItaniumVTContext; }
- MicrosoftVFTableContext &getVFTableContext() { return *VFTContext.get(); }
+ MicrosoftVTableContext &getMicrosoftVTableContext() {
+ return *MicrosoftVTContext.get();
+ }
/// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
/// given record decl.
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 249ad33..45a9e20 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -523,12 +523,12 @@
CodeGenVTables &getVTables() { return VTables; }
- ItaniumVTableContext &getVTableContext() {
- return VTables.getVTableContext();
+ ItaniumVTableContext &getItaniumVTableContext() {
+ return VTables.getItaniumVTableContext();
}
- MicrosoftVFTableContext &getVFTableContext() {
- return VTables.getVFTableContext();
+ MicrosoftVTableContext &getMicrosoftVTableContext() {
+ return VTables.getMicrosoftVTableContext();
}
llvm::MDNode *getTBAAInfo(QualType QTy);
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index 03fea46..9b7cf17 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -570,7 +570,7 @@
// Get the function pointer (or index if this is a virtual function).
llvm::Constant *MemPtr[2];
if (MD->isVirtual()) {
- uint64_t Index = CGM.getVTableContext().getMethodVTableIndex(MD);
+ uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
const ASTContext &Context = getContext();
CharUnits PointerWidth =
@@ -780,7 +780,8 @@
const CXXRecordDecl *BaseClassDecl) {
llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy);
CharUnits VBaseOffsetOffset =
- CGM.getVTableContext().getVirtualBaseOffsetOffset(ClassDecl, BaseClassDecl);
+ CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
+ BaseClassDecl);
llvm::Value *VBaseOffsetPtr =
CGF.Builder.CreateConstGEP1_64(VTablePtr, VBaseOffsetOffset.getQuantity(),
@@ -927,7 +928,7 @@
if (VTable->hasInitializer())
return;
- ItaniumVTableContext &VTContext = CGM.getVTableContext();
+ ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
@@ -977,8 +978,9 @@
} else {
llvm::Constant *VTable =
CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits());
- uint64_t AddressPoint = CGM.getVTableContext().getVTableLayout(VTableClass)
- .getAddressPoint(Base);
+ uint64_t AddressPoint = CGM.getItaniumVTableContext()
+ .getVTableLayout(VTableClass)
+ .getAddressPoint(Base);
VTableAddressPoint =
CGF.Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
}
@@ -991,8 +993,9 @@
llvm::Constant *VTable = getAddrOfVTable(VTableClass, CharUnits());
// Find the appropriate vtable within the vtable group.
- uint64_t AddressPoint =
- CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);
+ uint64_t AddressPoint = CGM.getItaniumVTableContext()
+ .getVTableLayout(VTableClass)
+ .getAddressPoint(Base);
llvm::Value *Indices[] = {
llvm::ConstantInt::get(CGM.Int64Ty, 0),
llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)
@@ -1018,7 +1021,7 @@
Out.flush();
StringRef Name = OutName.str();
- ItaniumVTableContext &VTContext = CGM.getVTableContext();
+ ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
llvm::ArrayType *ArrayType = llvm::ArrayType::get(
CGM.Int8PtrTy, VTContext.getVTableLayout(RD).getNumVTableComponents());
@@ -1036,7 +1039,7 @@
Ty = Ty->getPointerTo()->getPointerTo();
llvm::Value *VTable = CGF.GetVTablePtr(This, Ty);
- uint64_t VTableIndex = CGM.getVTableContext().getMethodVTableIndex(GD);
+ uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
llvm::Value *VFuncPtr =
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
return CGF.Builder.CreateLoad(VFuncPtr);
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index de13116..7e3a47d 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -120,8 +120,8 @@
const CXXRecordDecl *getThisArgumentTypeForMethod(const CXXMethodDecl *MD) {
MD = MD->getCanonicalDecl();
if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD)) {
- MicrosoftVFTableContext::MethodVFTableLocation ML =
- CGM.getVFTableContext().getMethodVFTableLocation(MD);
+ MicrosoftVTableContext::MethodVFTableLocation ML =
+ CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
// The vbases might be ordered differently in the final overrider object
// and the complete object, so the "this" argument may sometimes point to
// memory that has no particular type (e.g. past the complete object).
@@ -423,7 +423,9 @@
int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity();
llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy);
- CharUnits VBTableChars = IntSize * GetVBTableIndex(ClassDecl, BaseClassDecl);
+ CharUnits VBTableChars =
+ IntSize *
+ CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
llvm::Value *VBTableOffset =
llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity());
@@ -593,8 +595,8 @@
// with the base one, so look up the deleting one instead.
LookupGD = GlobalDecl(DD, Dtor_Deleting);
}
- MicrosoftVFTableContext::MethodVFTableLocation ML =
- CGM.getVFTableContext().getMethodVFTableLocation(LookupGD);
+ MicrosoftVTableContext::MethodVFTableLocation ML =
+ CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
@@ -719,8 +721,8 @@
// to the final overrider subobject before use.
// See comments in the MicrosoftVFTableContext implementation for the details.
- MicrosoftVFTableContext::MethodVFTableLocation ML =
- CGM.getVFTableContext().getMethodVFTableLocation(LookupGD);
+ MicrosoftVTableContext::MethodVFTableLocation ML =
+ CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
CharUnits Adjustment = ML.VFTableOffset;
if (ML.VBase) {
const ASTRecordLayout &DerivedLayout =
@@ -801,11 +803,11 @@
void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
const CXXRecordDecl *RD) {
- MicrosoftVFTableContext &VFTContext = CGM.getVFTableContext();
- MicrosoftVFTableContext::VFPtrListTy VFPtrs = VFTContext.getVFPtrOffsets(RD);
+ MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
+ MicrosoftVTableContext::VFPtrListTy VFPtrs = VFTContext.getVFPtrOffsets(RD);
llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
- for (MicrosoftVFTableContext::VFPtrListTy::iterator I = VFPtrs.begin(),
+ for (MicrosoftVTableContext::VFPtrListTy::iterator I = VFPtrs.begin(),
E = VFPtrs.end(); I != E; ++I) {
llvm::GlobalVariable *VTable = getAddrOfVTable(RD, I->VFPtrFullOffset);
if (VTable->hasInitializer())
@@ -867,9 +869,9 @@
llvm::GlobalVariable *&VTable = I->second;
- MicrosoftVFTableContext &VFTContext = CGM.getVFTableContext();
- const MicrosoftVFTableContext::VFPtrListTy &VFPtrs =
- VFTContext.getVFPtrOffsets(RD);
+ MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
+ const MicrosoftVTableContext::VFPtrListTy &VFPtrs =
+ VTContext.getVFPtrOffsets(RD);
if (DeferredVFTables.insert(RD)) {
// We haven't processed this record type before.
@@ -895,7 +897,7 @@
llvm::ArrayType *ArrayType = llvm::ArrayType::get(
CGM.Int8PtrTy,
- VFTContext.getVFTableLayout(RD, VFPtrs[J].VFPtrFullOffset)
+ VTContext.getVFTableLayout(RD, VFPtrs[J].VFPtrFullOffset)
.getNumVTableComponents());
SmallString<256> Name;
@@ -920,8 +922,8 @@
llvm::Value *VPtr = adjustThisArgumentForVirtualCall(CGF, GD, This);
llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty);
- MicrosoftVFTableContext::MethodVFTableLocation ML =
- CGM.getVFTableContext().getMethodVFTableLocation(GD);
+ MicrosoftVTableContext::MethodVFTableLocation ML =
+ CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
llvm::Value *VFuncPtr =
Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
return Builder.CreateLoad(VFuncPtr);
diff --git a/lib/CodeGen/MicrosoftVBTables.cpp b/lib/CodeGen/MicrosoftVBTables.cpp
index b4b98d3..dabf52c 100644
--- a/lib/CodeGen/MicrosoftVBTables.cpp
+++ b/lib/CodeGen/MicrosoftVBTables.cpp
@@ -195,15 +195,13 @@
const ASTRecordLayout &DerivedLayout =
CGM.getContext().getASTRecordLayout(RD);
- SmallVector<llvm::Constant *, 4> Offsets;
+ SmallVector<llvm::Constant *, 4> Offsets(1 + ReusingBase->getNumVBases(), 0);
// The offset from ReusingBase's vbptr to itself always leads.
CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
- Offsets.push_back(
- llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity()));
+ Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
- // These are laid out in the same order as in Itanium, which is the same as
- // the order of the vbase iterator.
+ MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(),
E = ReusingBase->vbases_end(); I != E; ++I) {
const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
@@ -211,7 +209,9 @@
assert(!Offset.isNegative());
// Make it relative to the subobject vbptr.
Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset;
- Offsets.push_back(llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity()));
+ unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase);
+ assert(Offsets[VBIndex] == 0 && "The same vbindex seen twice?");
+ Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity());
}
assert(Offsets.size() ==