From: Peter Collingbourne Date: Fri, 28 Jun 2013 20:45:28 +0000 (+0000) Subject: [ms-cxxabi] Move CodeGenVTables::needsVTTParameter to ItaniumCXXABI. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e1e35f761970fd662696b803a839c1f4a56f61b2;p=clang [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185213 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp index 7f07344adf..ea4336c917 100644 --- a/lib/CodeGen/CGCXXABI.cpp +++ b/lib/CodeGen/CGCXXABI.cpp @@ -293,3 +293,7 @@ LValue CGCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF, ErrorUnsupportedABI(CGF, "odr-use of thread_local global"); return LValue(); } + +bool CGCXXABI::NeedsVTTParameter(GlobalDecl GD) { + return false; +} diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index 04bc54b6bf..e4d9e5fdc6 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -331,6 +331,9 @@ public: QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize); + /// Return whether the given global decl needs a VTT parameter. + virtual bool NeedsVTTParameter(GlobalDecl GD); + protected: /// Returns the extra size required in order to store the array /// cookie for the given type. Assumes that an array cookie is diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index a32c152fee..9b34ece5c9 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -286,7 +286,7 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value, llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating) { - if (!CodeGenVTables::needsVTTParameter(GD)) { + if (!CGM.getCXXABI().NeedsVTTParameter(GD)) { // This constructor/destructor does not need a VTT parameter. return 0; } @@ -304,7 +304,7 @@ llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, } else if (RD == Base) { // If the record matches the base, this is the complete ctor/dtor // 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?"); assert(!ForVirtualBase && "Can't have same class as virtual base!"); SubVTTIndex = 0; @@ -319,7 +319,7 @@ llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, 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. VTT = LoadCXXVTT(); VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex); @@ -1742,7 +1742,7 @@ CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, QualType VoidPP = getContext().getPointerType(getContext().VoidPtrTy); 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)->getType() == VoidPP && "skipping parameter not of vtt type"); ++I; @@ -1874,9 +1874,10 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, // Compute the address point. llvm::Value *VTableAddressPoint; + bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CurGD); + // Check if we need to use a vtable from the VTT. - if (CodeGenVTables::needsVTTParameter(CurGD) && - (RD->getNumVBases() || NearestVBase)) { + if (NeedsVTTParam && (RD->getNumVBases() || NearestVBase)) { // Get the secondary vpointer index. uint64_t VirtualPointerIndex = CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base); @@ -1899,7 +1900,7 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, llvm::Value *VirtualOffset = 0; 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 // might have a different offset in the most derived class. VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(*this, diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp index 98be872a55..a02292e4ae 100644 --- a/lib/CodeGen/CGVTT.cpp +++ b/lib/CodeGen/CGVTT.cpp @@ -120,24 +120,6 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) { return GV; } -bool CodeGenVTables::needsVTTParameter(GlobalDecl GD) { - const CXXMethodDecl *MD = cast(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(MD) && GD.getCtorType() == Ctor_Base) - return true; - - // Check if we have a base destructor. - if (isa(MD) && GD.getDtorType() == Dtor_Base) - return true; - - return false; -} - uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base) { BaseSubobjectPairTy ClassSubobjectPair(RD, Base); diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index bd3bdb1358..fe51d50070 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -77,11 +77,6 @@ public: 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 /// given record decl. uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base); diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 36b3da58b9..67174c073e 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -162,6 +162,8 @@ public: llvm::Function *InitFunc); LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF, const DeclRefExpr *DRE); + + bool NeedsVTTParameter(GlobalDecl GD); }; class ARMCXXABI : public ItaniumCXXABI { @@ -810,7 +812,7 @@ void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF, assert(MD->isInstance()); // Check if we need a VTT parameter as well. - if (CodeGenVTables::needsVTTParameter(CGF.CurGD)) { + if (NeedsVTTParameter(CGF.CurGD)) { ASTContext &Context = getContext(); // FIXME: avoid the fake decl @@ -1417,3 +1419,23 @@ LValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF, // FIXME: need setObjCGCLValueClass? 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(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(MD) && GD.getCtorType() == Ctor_Base) + return true; + + // Check if we have a base destructor. + if (isa(MD) && GD.getDtorType() == Dtor_Base) + return true; + + return false; +} diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp new file mode 100644 index 0000000000..7e631c1d78 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -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() {}