summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorMarco Antognini <marco.antognini@arm.com>2019-07-22 09:39:13 +0000
committerMarco Antognini <marco.antognini@arm.com>2019-07-22 09:39:13 +0000
commit88559637641e993895337e1047a0bd787fecc647 (patch)
tree639b057daba633db68b8fa4d34a957913786c64f /clang/lib/CodeGen
parent6771a89fa01ffb1ea8702d7b07e259750ae62f1c (diff)
downloadbcm5719-llvm-88559637641e993895337e1047a0bd787fecc647.tar.gz
bcm5719-llvm-88559637641e993895337e1047a0bd787fecc647.zip
[OpenCL] Improve destructor support in C++ for OpenCL
This re-applies r366422 with a fix for Bug PR42665 and a new regression test. llvm-svn: 366670
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCXXABI.h14
-rw-r--r--clang/lib/CodeGen/CGCall.cpp2
-rw-r--r--clang/lib/CodeGen/CGClass.cpp40
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp21
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp31
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h13
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp32
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp30
8 files changed, 118 insertions, 65 deletions
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index 511bcd00d42..3a9c3b34743 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -378,7 +378,7 @@ public:
virtual void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD, CXXDtorType Type,
bool ForVirtualBase, bool Delegating,
- Address This) = 0;
+ Address This, QualType ThisTy) = 0;
/// Emits the VTable definitions required for the given record type.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT,
@@ -421,11 +421,15 @@ public:
llvm::Type *Ty,
SourceLocation Loc) = 0;
+ using DeleteOrMemberCallExpr =
+ llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr *>;
+
/// Emit the ABI-specific virtual destructor call.
- virtual llvm::Value *
- EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor,
- CXXDtorType DtorType, Address This,
- const CXXMemberCallExpr *CE) = 0;
+ virtual llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
+ const CXXDestructorDecl *Dtor,
+ CXXDtorType DtorType,
+ Address This,
+ DeleteOrMemberCallExpr E) = 0;
virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF,
GlobalDecl GD,
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 890bf2ba772..9c18d69fb6c 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -3505,7 +3505,7 @@ struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
assert(!Dtor->isTrivial());
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*for vbase*/ false,
- /*Delegating=*/false, Addr);
+ /*Delegating=*/false, Addr, Ty);
} else {
CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Ty));
}
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 9a9dd88810e..c8bb63c5c4b 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -491,12 +491,15 @@ namespace {
cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
const CXXDestructorDecl *D = BaseClass->getDestructor();
+ // We are already inside a destructor, so presumably the object being
+ // destroyed should have the expected type.
+ QualType ThisTy = D->getThisObjectType();
Address Addr =
CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(),
DerivedClass, BaseClass,
BaseIsVirtual);
CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual,
- /*Delegating=*/false, Addr);
+ /*Delegating=*/false, Addr, ThisTy);
}
};
@@ -1440,9 +1443,11 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
if (DtorType == Dtor_Deleting) {
RunCleanupsScope DtorEpilogue(*this);
EnterDtorCleanups(Dtor, Dtor_Deleting);
- if (HaveInsertPoint())
+ if (HaveInsertPoint()) {
+ QualType ThisTy = Dtor->getThisObjectType();
EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
- /*Delegating=*/false, LoadCXXThisAddress());
+ /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
+ }
return;
}
@@ -1473,8 +1478,9 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
EnterDtorCleanups(Dtor, Dtor_Complete);
if (!isTryBody) {
+ QualType ThisTy = Dtor->getThisObjectType();
EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
- /*Delegating=*/false, LoadCXXThisAddress());
+ /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
break;
}
@@ -2013,7 +2019,7 @@ void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
const CXXDestructorDecl *dtor = record->getDestructor();
assert(!dtor->isTrivial());
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
- /*Delegating=*/false, addr);
+ /*Delegating=*/false, addr, type);
}
void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
@@ -2363,8 +2369,11 @@ namespace {
: Dtor(D), Addr(Addr), Type(Type) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
+ // We are calling the destructor from within the constructor.
+ // Therefore, "this" should have the expected type.
+ QualType ThisTy = Dtor->getThisObjectType();
CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
- /*Delegating=*/true, Addr);
+ /*Delegating=*/true, Addr, ThisTy);
}
};
} // end anonymous namespace
@@ -2402,31 +2411,32 @@ CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor
void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
CXXDtorType Type,
bool ForVirtualBase,
- bool Delegating,
- Address This) {
+ bool Delegating, Address This,
+ QualType ThisTy) {
CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase,
- Delegating, This);
+ Delegating, This, ThisTy);
}
namespace {
struct CallLocalDtor final : EHScopeStack::Cleanup {
const CXXDestructorDecl *Dtor;
Address Addr;
+ QualType Ty;
- CallLocalDtor(const CXXDestructorDecl *D, Address Addr)
- : Dtor(D), Addr(Addr) {}
+ CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty)
+ : Dtor(D), Addr(Addr), Ty(Ty) {}
void Emit(CodeGenFunction &CGF, Flags flags) override {
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
/*ForVirtualBase=*/false,
- /*Delegating=*/false, Addr);
+ /*Delegating=*/false, Addr, Ty);
}
};
} // end anonymous namespace
void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D,
- Address Addr) {
- EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr);
+ QualType T, Address Addr) {
+ EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T);
}
void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
@@ -2436,7 +2446,7 @@ void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
const CXXDestructorDecl *D = ClassDecl->getDestructor();
assert(D && D->isUsed() && "destructor not marked as used!");
- PushDestructorCleanup(D, Addr);
+ PushDestructorCleanup(D, T, Addr);
}
void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 19a9e75cc5a..6ad43cefc4d 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -480,11 +480,12 @@ namespace {
template <class Derived>
struct DestroyNRVOVariable : EHScopeStack::Cleanup {
- DestroyNRVOVariable(Address addr, llvm::Value *NRVOFlag)
- : NRVOFlag(NRVOFlag), Loc(addr) {}
+ DestroyNRVOVariable(Address addr, QualType type, llvm::Value *NRVOFlag)
+ : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {}
llvm::Value *NRVOFlag;
Address Loc;
+ QualType Ty;
void Emit(CodeGenFunction &CGF, Flags flags) override {
// Along the exceptions path we always execute the dtor.
@@ -511,26 +512,24 @@ namespace {
struct DestroyNRVOVariableCXX final
: DestroyNRVOVariable<DestroyNRVOVariableCXX> {
- DestroyNRVOVariableCXX(Address addr, const CXXDestructorDecl *Dtor,
- llvm::Value *NRVOFlag)
- : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, NRVOFlag),
- Dtor(Dtor) {}
+ DestroyNRVOVariableCXX(Address addr, QualType type,
+ const CXXDestructorDecl *Dtor, llvm::Value *NRVOFlag)
+ : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type, NRVOFlag),
+ Dtor(Dtor) {}
const CXXDestructorDecl *Dtor;
void emitDestructorCall(CodeGenFunction &CGF) {
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
/*ForVirtualBase=*/false,
- /*Delegating=*/false, Loc);
+ /*Delegating=*/false, Loc, Ty);
}
};
struct DestroyNRVOVariableC final
: DestroyNRVOVariable<DestroyNRVOVariableC> {
DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
- : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, NRVOFlag), Ty(Ty) {}
-
- QualType Ty;
+ : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
void emitDestructorCall(CodeGenFunction &CGF) {
CGF.destroyNonTrivialCStruct(CGF, Loc, Ty);
@@ -1940,7 +1939,7 @@ void CodeGenFunction::emitAutoVarTypeCleanup(
if (emission.NRVOFlag) {
assert(!type->isArrayType());
CXXDestructorDecl *dtor = type->getAsCXXRecordDecl()->getDestructor();
- EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, dtor,
+ EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, type, dtor,
emission.NRVOFlag);
return;
}
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 8ad229fc0c3..5476d13b7c4 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -10,12 +10,13 @@
//
//===----------------------------------------------------------------------===//
-#include "CodeGenFunction.h"
#include "CGCUDARuntime.h"
#include "CGCXXABI.h"
#include "CGDebugInfo.h"
#include "CGObjCRuntime.h"
+#include "CodeGenFunction.h"
#include "ConstantEmitter.h"
+#include "TargetInfo.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "llvm/IR/Intrinsics.h"
@@ -90,12 +91,26 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
}
RValue CodeGenFunction::EmitCXXDestructorCall(
- GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This,
+ GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This, QualType ThisTy,
llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE) {
+ const CXXMethodDecl *DtorDecl = cast<CXXMethodDecl>(Dtor.getDecl());
+
+ assert(!ThisTy.isNull());
+ assert(ThisTy->getAsCXXRecordDecl() == DtorDecl->getParent() &&
+ "Pointer/Object mixup");
+
+ LangAS SrcAS = ThisTy.getAddressSpace();
+ LangAS DstAS = DtorDecl->getMethodQualifiers().getAddressSpace();
+ if (SrcAS != DstAS) {
+ QualType DstTy = DtorDecl->getThisType();
+ llvm::Type *NewType = CGM.getTypes().ConvertType(DstTy);
+ This = getTargetHooks().performAddrSpaceCast(*this, This, SrcAS, DstAS,
+ NewType);
+ }
+
CallArgList Args;
- commonEmitCXXMemberOrOperatorCall(*this, cast<CXXMethodDecl>(Dtor.getDecl()),
- This, ImplicitParam, ImplicitParamTy, CE,
- Args, nullptr);
+ commonEmitCXXMemberOrOperatorCall(*this, DtorDecl, This, ImplicitParam,
+ ImplicitParamTy, CE, Args, nullptr);
return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
ReturnValueSlot(), Args);
}
@@ -345,7 +360,9 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
Callee = CGCallee::forDirect(CGM.GetAddrOfFunction(GD, Ty), GD);
}
- EmitCXXDestructorCall(GD, Callee, This.getPointer(),
+ QualType ThisTy =
+ IsArrow ? Base->getType()->getPointeeType() : Base->getType();
+ EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
/*ImplicitParam=*/nullptr,
/*ImplicitParamTy=*/QualType(), nullptr);
}
@@ -1883,7 +1900,7 @@ static void EmitObjectDelete(CodeGenFunction &CGF,
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
/*ForVirtualBase=*/false,
/*Delegating=*/false,
- Ptr);
+ Ptr, ElementType);
else if (auto Lifetime = ElementType.getObjCLifetime()) {
switch (Lifetime) {
case Qualifiers::OCL_None:
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 06ef2dff7e9..c3060d1fb35 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -675,7 +675,8 @@ public:
/// PushDestructorCleanup - Push a cleanup to call the
/// complete-object variant of the given destructor on the object at
/// the given address.
- void PushDestructorCleanup(const CXXDestructorDecl *Dtor, Address Addr);
+ void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T,
+ Address Addr);
/// PopCleanupBlock - Will pop the cleanup entry on the stack and
/// process all branch fixups.
@@ -2554,8 +2555,8 @@ public:
static Destroyer destroyCXXObject;
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
- bool ForVirtualBase, bool Delegating,
- Address This);
+ bool ForVirtualBase, bool Delegating, Address This,
+ QualType ThisTy);
void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
llvm::Type *ElementTy, Address NewPtr,
@@ -3677,9 +3678,9 @@ public:
llvm::Value *ImplicitParam,
QualType ImplicitParamTy, const CallExpr *E,
CallArgList *RtlArgs);
- RValue EmitCXXDestructorCall(GlobalDecl Dtor,
- const CGCallee &Callee,
- llvm::Value *This, llvm::Value *ImplicitParam,
+ RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee,
+ llvm::Value *This, QualType ThisTy,
+ llvm::Value *ImplicitParam,
QualType ImplicitParamTy, const CallExpr *E);
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
ReturnValueSlot ReturnValue);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 7216e1daefd..826d98151d9 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -224,7 +224,8 @@ public:
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
- bool Delegating, Address This) override;
+ bool Delegating, Address This,
+ QualType ThisTy) override;
void emitVTableDefinitions(CodeGenVTables &CGVT,
const CXXRecordDecl *RD) override;
@@ -261,9 +262,8 @@ public:
llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
- CXXDtorType DtorType,
- Address This,
- const CXXMemberCallExpr *CE) override;
+ CXXDtorType DtorType, Address This,
+ DeleteOrMemberCallExpr E) override;
void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
@@ -1127,7 +1127,7 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
// FIXME: Provide a source location here even though there's no
// CXXMemberCallExpr for dtor call.
CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
- EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr);
+ EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
if (UseGlobalDelete)
CGF.PopCleanupBlock();
@@ -1538,7 +1538,8 @@ CGCXXABI::AddedStructorArgs ItaniumCXXABI::addImplicitConstructorArgs(
void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
- bool Delegating, Address This) {
+ bool Delegating, Address This,
+ QualType ThisTy) {
GlobalDecl GD(DD, Type);
llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);
QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
@@ -1550,7 +1551,8 @@ void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
else
Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
- CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), VTT, VTTTy, nullptr);
+ CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, VTT, VTTTy,
+ nullptr);
}
void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
@@ -1738,7 +1740,10 @@ CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
- Address This, const CXXMemberCallExpr *CE) {
+ Address This, DeleteOrMemberCallExpr E) {
+ auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
+ auto *D = E.dyn_cast<const CXXDeleteExpr *>();
+ assert((CE != nullptr) ^ (D != nullptr));
assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
@@ -1748,8 +1753,15 @@ llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
- CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), nullptr, QualType(),
- nullptr);
+ QualType ThisTy;
+ if (CE) {
+ ThisTy = CE->getObjectType();
+ } else {
+ ThisTy = D->getDestroyedType();
+ }
+
+ CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, nullptr,
+ QualType(), nullptr);
return nullptr;
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index a91a949d024..ca06ad3f042 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -258,7 +258,8 @@ public:
void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
- bool Delegating, Address This) override;
+ bool Delegating, Address This,
+ QualType ThisTy) override;
void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl *RD,
llvm::GlobalVariable *VTable);
@@ -296,9 +297,8 @@ public:
llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
- CXXDtorType DtorType,
- Address This,
- const CXXMemberCallExpr *CE) override;
+ CXXDtorType DtorType, Address This,
+ DeleteOrMemberCallExpr E) override;
void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
CallArgList &CallArgs) override {
@@ -844,8 +844,7 @@ void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
// CXXMemberCallExpr for dtor call.
bool UseGlobalDelete = DE->isGlobalDelete();
CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
- llvm::Value *MDThis =
- EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr);
+ llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
if (UseGlobalDelete)
CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType);
}
@@ -1569,7 +1568,8 @@ CGCXXABI::AddedStructorArgs MicrosoftCXXABI::addImplicitConstructorArgs(
void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
CXXDtorType Type, bool ForVirtualBase,
- bool Delegating, Address This) {
+ bool Delegating, Address This,
+ QualType ThisTy) {
// Use the base destructor variant in place of the complete destructor variant
// if the class has no virtual bases. This effectively implements some of the
// -mconstructor-aliases optimization, but as part of the MS C++ ABI.
@@ -1591,7 +1591,7 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
}
- CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
+ CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
/*ImplicitParam=*/nullptr,
/*ImplicitParamTy=*/QualType(), nullptr);
if (BaseDtorEndBB) {
@@ -1900,7 +1900,10 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
- Address This, const CXXMemberCallExpr *CE) {
+ Address This, DeleteOrMemberCallExpr E) {
+ auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
+ auto *D = E.dyn_cast<const CXXDeleteExpr *>();
+ assert((CE != nullptr) ^ (D != nullptr));
assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
@@ -1917,8 +1920,15 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
DtorType == Dtor_Deleting);
+ QualType ThisTy;
+ if (CE) {
+ ThisTy = CE->getObjectType();
+ } else {
+ ThisTy = D->getDestroyedType();
+ }
+
This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
- RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
+ RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
ImplicitParam, Context.IntTy, CE);
return RV.getScalarVal();
}
OpenPOWER on IntegriCloud