summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/MicrosoftCXXABI.cpp')
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 5947fd7ebf1..08921b9628c 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -165,6 +165,9 @@ public:
llvm::BasicBlock *
EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
const CXXRecordDecl *RD) override;
+
+ llvm::BasicBlock *
+ EmitDtorCompleteObjectHandler(CodeGenFunction &CGF);
void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
const CXXRecordDecl *RD) override;
@@ -1135,6 +1138,25 @@ MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
return SkipVbaseCtorsBB;
}
+llvm::BasicBlock *
+MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
+ llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
+ assert(IsMostDerivedClass &&
+ "ctor for a class with virtual bases must have an implicit parameter");
+ llvm::Value *IsCompleteObject =
+ CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
+
+ llvm::BasicBlock *CallVbaseDtorsBB = CGF.createBasicBlock("Dtor.dtor_vbases");
+ llvm::BasicBlock *SkipVbaseDtorsBB = CGF.createBasicBlock("Dtor.skip_vbases");
+ CGF.Builder.CreateCondBr(IsCompleteObject,
+ CallVbaseDtorsBB, SkipVbaseDtorsBB);
+
+ CGF.EmitBlock(CallVbaseDtorsBB);
+ // CGF will put the base dtor calls in this basic block for us later.
+
+ return SkipVbaseDtorsBB;
+}
+
void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
CodeGenFunction &CGF, const CXXRecordDecl *RD) {
// In most cases, an override for a vbase virtual method can adjust
@@ -1512,11 +1534,21 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD, Type),
This, false);
}
+
+ llvm::BasicBlock *BaseDtorEndBB = nullptr;
+ if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.CurCodeDecl)) {
+ BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
+ }
CGF.EmitCXXDestructorCall(DD, Callee, This.getPointer(),
/*ImplicitParam=*/nullptr,
/*ImplicitParamTy=*/QualType(), nullptr,
getFromDtorType(Type));
+ if (BaseDtorEndBB) {
+ // Complete object handler should continue to be the remaining
+ CGF.Builder.CreateBr(BaseDtorEndBB);
+ CGF.EmitBlock(BaseDtorEndBB);
+ }
}
void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info,
OpenPOWER on IntegriCloud