[ms-cxxabi] Move CodeGenVTables::needsVTTParameter to ItaniumCXXABI.
This function only makes sense there. Eventually it should no longer be part of the CGCXXABI interface, as it is an Itanium-specific detail. Differential Revision: http://llvm-reviews.chandlerc.com/D821 llvm-svn: 185213
This commit is contained in:
parent
4146b0404e
commit
66f82e68c3
|
@ -293,3 +293,7 @@ LValue CGCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||||
ErrorUnsupportedABI(CGF, "odr-use of thread_local global");
|
ErrorUnsupportedABI(CGF, "odr-use of thread_local global");
|
||||||
return LValue();
|
return LValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -331,6 +331,9 @@ public:
|
||||||
QualType ElementType, llvm::Value *&NumElements,
|
QualType ElementType, llvm::Value *&NumElements,
|
||||||
llvm::Value *&AllocPtr, CharUnits &CookieSize);
|
llvm::Value *&AllocPtr, CharUnits &CookieSize);
|
||||||
|
|
||||||
|
/// Return whether the given global decl needs a VTT parameter.
|
||||||
|
virtual bool NeedsVTTParameter(GlobalDecl GD);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Returns the extra size required in order to store the array
|
/// Returns the extra size required in order to store the array
|
||||||
/// cookie for the given type. Assumes that an array cookie is
|
/// cookie for the given type. Assumes that an array cookie is
|
||||||
|
|
|
@ -286,7 +286,7 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
|
||||||
llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,
|
llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,
|
||||||
bool ForVirtualBase,
|
bool ForVirtualBase,
|
||||||
bool Delegating) {
|
bool Delegating) {
|
||||||
if (!CodeGenVTables::needsVTTParameter(GD)) {
|
if (!CGM.getCXXABI().NeedsVTTParameter(GD)) {
|
||||||
// This constructor/destructor does not need a VTT parameter.
|
// This constructor/destructor does not need a VTT parameter.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,
|
||||||
} else if (RD == Base) {
|
} else if (RD == Base) {
|
||||||
// If the record matches the base, this is the complete ctor/dtor
|
// If the record matches the base, this is the complete ctor/dtor
|
||||||
// variant calling the base variant in a class with virtual bases.
|
// variant calling the base variant in a class with virtual bases.
|
||||||
assert(!CodeGenVTables::needsVTTParameter(CurGD) &&
|
assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) &&
|
||||||
"doing no-op VTT offset in base dtor/ctor?");
|
"doing no-op VTT offset in base dtor/ctor?");
|
||||||
assert(!ForVirtualBase && "Can't have same class as virtual base!");
|
assert(!ForVirtualBase && "Can't have same class as virtual base!");
|
||||||
SubVTTIndex = 0;
|
SubVTTIndex = 0;
|
||||||
|
@ -319,7 +319,7 @@ llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,
|
||||||
assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
|
assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CodeGenVTables::needsVTTParameter(CurGD)) {
|
if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
|
||||||
// A VTT parameter was passed to the constructor, use it.
|
// A VTT parameter was passed to the constructor, use it.
|
||||||
VTT = LoadCXXVTT();
|
VTT = LoadCXXVTT();
|
||||||
VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
|
VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
|
||||||
|
@ -1742,7 +1742,7 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
|
||||||
QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy);
|
QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy);
|
||||||
DelegateArgs.add(RValue::get(VTT), VoidPP);
|
DelegateArgs.add(RValue::get(VTT), VoidPP);
|
||||||
|
|
||||||
if (CodeGenVTables::needsVTTParameter(CurGD)) {
|
if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
|
||||||
assert(I != E && "cannot skip vtt parameter, already done with args");
|
assert(I != E && "cannot skip vtt parameter, already done with args");
|
||||||
assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type");
|
assert((*I)->getType() == VoidPP && "skipping parameter not of vtt type");
|
||||||
++I;
|
++I;
|
||||||
|
@ -1874,9 +1874,10 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,
|
||||||
// Compute the address point.
|
// Compute the address point.
|
||||||
llvm::Value *VTableAddressPoint;
|
llvm::Value *VTableAddressPoint;
|
||||||
|
|
||||||
|
bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CurGD);
|
||||||
|
|
||||||
// Check if we need to use a vtable from the VTT.
|
// Check if we need to use a vtable from the VTT.
|
||||||
if (CodeGenVTables::needsVTTParameter(CurGD) &&
|
if (NeedsVTTParam && (RD->getNumVBases() || NearestVBase)) {
|
||||||
(RD->getNumVBases() || NearestVBase)) {
|
|
||||||
// Get the secondary vpointer index.
|
// Get the secondary vpointer index.
|
||||||
uint64_t VirtualPointerIndex =
|
uint64_t VirtualPointerIndex =
|
||||||
CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
|
CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
|
||||||
|
@ -1899,7 +1900,7 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,
|
||||||
llvm::Value *VirtualOffset = 0;
|
llvm::Value *VirtualOffset = 0;
|
||||||
CharUnits NonVirtualOffset = CharUnits::Zero();
|
CharUnits NonVirtualOffset = CharUnits::Zero();
|
||||||
|
|
||||||
if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) {
|
if (NeedsVTTParam && NearestVBase) {
|
||||||
// We need to use the virtual base offset offset because the virtual base
|
// We need to use the virtual base offset offset because the virtual base
|
||||||
// might have a different offset in the most derived class.
|
// might have a different offset in the most derived class.
|
||||||
VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this,
|
VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this,
|
||||||
|
|
|
@ -120,24 +120,6 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) {
|
|
||||||
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
|
||||||
|
|
||||||
// We don't have any virtual bases, just return early.
|
|
||||||
if (!MD->getParent()->getNumVBases())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if we have a base constructor.
|
|
||||||
if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Check if we have a base destructor.
|
|
||||||
if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
|
uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD,
|
||||||
BaseSubobject Base) {
|
BaseSubobject Base) {
|
||||||
BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
|
BaseSubobjectPairTy ClassSubobjectPair(RD, Base);
|
||||||
|
|
|
@ -77,11 +77,6 @@ public:
|
||||||
|
|
||||||
VTableContext &getVTableContext() { return VTContext; }
|
VTableContext &getVTableContext() { return VTContext; }
|
||||||
|
|
||||||
/// needsVTTParameter - Return whether the given global decl needs a VTT
|
|
||||||
/// parameter, which it does if it's a base constructor or destructor with
|
|
||||||
/// virtual bases.
|
|
||||||
static bool needsVTTParameter(GlobalDecl GD);
|
|
||||||
|
|
||||||
/// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
|
/// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
|
||||||
/// given record decl.
|
/// given record decl.
|
||||||
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
|
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
|
||||||
|
|
|
@ -162,6 +162,8 @@ public:
|
||||||
llvm::Function *InitFunc);
|
llvm::Function *InitFunc);
|
||||||
LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||||
const DeclRefExpr *DRE);
|
const DeclRefExpr *DRE);
|
||||||
|
|
||||||
|
bool NeedsVTTParameter(GlobalDecl GD);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ARMCXXABI : public ItaniumCXXABI {
|
class ARMCXXABI : public ItaniumCXXABI {
|
||||||
|
@ -810,7 +812,7 @@ void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
|
||||||
assert(MD->isInstance());
|
assert(MD->isInstance());
|
||||||
|
|
||||||
// Check if we need a VTT parameter as well.
|
// Check if we need a VTT parameter as well.
|
||||||
if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) {
|
if (NeedsVTTParameter(CGF.CurGD)) {
|
||||||
ASTContext &Context = getContext();
|
ASTContext &Context = getContext();
|
||||||
|
|
||||||
// FIXME: avoid the fake decl
|
// FIXME: avoid the fake decl
|
||||||
|
@ -1417,3 +1419,23 @@ LValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||||
// FIXME: need setObjCGCLValueClass?
|
// FIXME: need setObjCGCLValueClass?
|
||||||
return LV;
|
return LV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return whether the given global decl needs a VTT parameter, which it does
|
||||||
|
/// if it's a base constructor or destructor with virtual bases.
|
||||||
|
bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
|
||||||
|
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
|
||||||
|
|
||||||
|
// We don't have any virtual bases, just return early.
|
||||||
|
if (!MD->getParent()->getNumVBases())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if we have a base constructor.
|
||||||
|
if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Check if we have a base destructor.
|
||||||
|
if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -o %t
|
||||||
|
|
||||||
|
struct A {};
|
||||||
|
struct B : virtual A {
|
||||||
|
virtual ~B();
|
||||||
|
};
|
||||||
|
struct C : B {
|
||||||
|
C();
|
||||||
|
};
|
||||||
|
|
||||||
|
C::C() {}
|
Loading…
Reference in New Issue