Skip to content

Commit 7b8189a

Browse files
authored
[CIR] Add CIRGen for pseudo destructor calls (#153014)
1 parent 9df846b commit 7b8189a

File tree

7 files changed

+79
-8
lines changed

7 files changed

+79
-8
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ struct MissingFeatures {
8787
static bool setFunctionAttributes() { return false; }
8888

8989
// CallOp handling
90-
static bool opCallPseudoDtor() { return false; }
9190
static bool opCallAggregateArgs() { return false; }
9291
static bool opCallPaddingArgs() { return false; }
9392
static bool opCallABIExtendArg() { return false; }

clang/lib/CIR/CodeGen/CIRGenCall.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class CIRGenCallee {
4646
enum class SpecialKind : uintptr_t {
4747
Invalid,
4848
Builtin,
49+
PseudoDestructor,
4950

5051
Last = Builtin,
5152
};
@@ -54,12 +55,16 @@ class CIRGenCallee {
5455
const clang::FunctionDecl *decl;
5556
unsigned id;
5657
};
58+
struct PseudoDestructorInfoStorage {
59+
const clang::CXXPseudoDestructorExpr *expr;
60+
};
5761

5862
SpecialKind kindOrFunctionPtr;
5963

6064
union {
6165
CIRGenCalleeInfo abstractInfo;
6266
BuiltinInfoStorage builtinInfo;
67+
PseudoDestructorInfoStorage pseudoDestructorInfo;
6368
};
6469

6570
explicit CIRGenCallee(SpecialKind kind) : kindOrFunctionPtr(kind) {}
@@ -98,6 +103,22 @@ class CIRGenCallee {
98103
return result;
99104
}
100105

106+
static CIRGenCallee
107+
forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr) {
108+
CIRGenCallee result(SpecialKind::PseudoDestructor);
109+
result.pseudoDestructorInfo.expr = expr;
110+
return result;
111+
}
112+
113+
bool isPseudoDestructor() const {
114+
return kindOrFunctionPtr == SpecialKind::PseudoDestructor;
115+
}
116+
117+
const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
118+
assert(isPseudoDestructor());
119+
return pseudoDestructorInfo.expr;
120+
}
121+
101122
bool isOrdinary() const {
102123
return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last);
103124
}

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,10 +1544,10 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
15441544
cgm.errorNYI(e->getSourceRange(),
15451545
"emitCallee: call to member function is NYI");
15461546
return {};
1547+
} else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
1548+
return CIRGenCallee::forPseudoDestructor(pde);
15471549
}
15481550

1549-
assert(!cir::MissingFeatures::opCallPseudoDtor());
1550-
15511551
// Otherwise, we have an indirect reference.
15521552
mlir::Value calleePtr;
15531553
QualType functionType;
@@ -1599,10 +1599,8 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
15991599
return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,
16001600
returnValue);
16011601

1602-
if (isa<CXXPseudoDestructorExpr>(e->getCallee())) {
1603-
cgm.errorNYI(e->getSourceRange(), "call to pseudo destructor");
1604-
}
1605-
assert(!cir::MissingFeatures::opCallPseudoDtor());
1602+
if (callee.isPseudoDestructor())
1603+
return emitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());
16061604

16071605
return emitCall(e->getCallee()->getType(), callee, e, returnValue);
16081606
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===--- CIRGenExprCXX.cpp - Emit CIR Code for C++ expressions ------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This contains code dealing with code generation of C++ expressions
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "CIRGenFunction.h"
14+
#include "clang/AST/ExprCXX.h"
15+
16+
using namespace clang;
17+
using namespace clang::CIRGen;
18+
19+
RValue CIRGenFunction::emitCXXPseudoDestructorExpr(
20+
const CXXPseudoDestructorExpr *expr) {
21+
QualType destroyedType = expr->getDestroyedType();
22+
if (destroyedType.hasStrongOrWeakObjCLifetime()) {
23+
assert(!cir::MissingFeatures::objCLifetime());
24+
cgm.errorNYI(expr->getExprLoc(),
25+
"emitCXXPseudoDestructorExpr: Objective-C lifetime is NYI");
26+
} else {
27+
// C++ [expr.pseudo]p1:
28+
// The result shall only be used as the operand for the function call
29+
// operator (), and the result of such a call has type void. The only
30+
// effect is the evaluation of the postfix-expression before the dot or
31+
// arrow.
32+
emitIgnoredExpr(expr->getBase());
33+
}
34+
35+
return RValue::get(nullptr);
36+
}

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,8 @@ class CIRGenFunction : public CIRGenTypeCache {
10651065
const CXXMethodDecl *md,
10661066
ReturnValueSlot returnValue);
10671067

1068+
RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
1069+
10681070
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor,
10691071
clang::CXXCtorType ctorType, FunctionArgList &args);
10701072

clang/lib/CIR/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_clang_library(clangCIR
2222
CIRGenExprAggregate.cpp
2323
CIRGenExprComplex.cpp
2424
CIRGenExprConstant.cpp
25+
CIRGenExprCXX.cpp
2526
CIRGenExprScalar.cpp
2627
CIRGenFunction.cpp
2728
CIRGenItaniumCXXABI.cpp

clang/test/CIR/CodeGen/call.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,18 @@ void f14() {
116116
// LLVM: call void @_Z3f13v() #[[LLVM_ATTR_0:.+]]
117117
// LLVM: }
118118

119-
// LLLVM: attributes #[[LLVM_ATTR_0]] = { nounwind }
119+
int f15();
120+
void f16() {
121+
using T = int;
122+
f15().~T();
123+
}
124+
125+
// CIR-LABEL: @_Z3f16v
126+
// CIR-NEXT: %{{.+}} = cir.call @_Z3f15v() : () -> !s32i
127+
// CIR: }
128+
129+
// LLVM-LABEL: define{{.+}} void @_Z3f16v() {
130+
// LLVM-NEXT: %{{.+}} = call i32 @_Z3f15v()
131+
// LLVM: }
132+
133+
// LLVM: attributes #[[LLVM_ATTR_0]] = { nounwind }

0 commit comments

Comments
 (0)