Skip to content
22 changes: 21 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,27 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr(
"Destructor shouldn't have explicit parameters");
assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
if (useVirtualCall) {
llvm_unreachable("NYI");
GlobalDecl globalDecl(dtor, Dtor_Complete);

const CIRGenFunctionInfo &funcInfo =
CGM.getTypes().arrangeCXXStructorDeclaration(globalDecl);
cir::FuncType funcTy = CGM.getTypes().GetFunctionType(funcInfo);

CIRGenCallee callee =
CIRGenCallee::forVirtual(CE, globalDecl, This.getAddress(), funcTy);

if (dtor->isVirtual()) {
Address newThisAddr =
CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
*this, globalDecl, This.getAddress(), true);
This.setAddress(newThisAddr);
}

QualType thisTy =
IsArrow ? Base->getType()->getPointeeType() : Base->getType();
emitCXXDestructorCall(globalDecl, callee, This.getPointer(), thisTy,
/*ImplicitParam=*/nullptr,
/*ImplicitParamTy=*/QualType(), CE);
} else {
GlobalDecl globalDecl(dtor, Dtor_Complete);
CIRGenCallee Callee;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s


class A {
virtual ~A();
A B(A);
};
A A::B(A) {
// CIR-LABEL: cir.func dso_local @_ZN1A1BES_(
// CIR-SAME: %[[THIS_ARG:.*]]: !cir.ptr<!rec_A>
// CIR-NEXT: %[[THIS_VAR:.*]] = cir.alloca !cir.ptr<!rec_A>, !cir.ptr<!cir.ptr<!rec_A>>
// CIR: %[[THIS:.*]] = cir.load %[[THIS_VAR]] : !cir.ptr<!cir.ptr<!rec_A>>, !cir.ptr<!rec_A>
// CIR-NEXT: %[[VPTR_PTR:.*]] = cir.vtable.get_vptr %[[THIS]] : !cir.ptr<!rec_A> -> !cir.ptr<!cir.vptr>
// CIR-NEXT: %[[VPTR:.*]] = cir.load align(8) %[[VPTR_PTR]] : !cir.ptr<!cir.vptr>, !cir.vptr
// CIR-NEXT: %[[DTOR_PTR:.*]] = cir.vtable.get_virtual_fn_addr %[[VPTR]][0] : !cir.vptr -> !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>>
// CIR-NEXT: %[[DTOR:.*]] = cir.load align(8) %[[DTOR_PTR]] : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>>, !cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>
// CIR-NEXT: cir.call %[[DTOR]](%[[THIS]]) : (!cir.ptr<!cir.func<(!cir.ptr<!rec_A>)>>, !cir.ptr<!rec_A>) -> ()
// CIR-NEXT: cir.trap
// CIR-NEXT: }

this->~A();
}
Loading