Skip to content

Commit d423af4

Browse files
authored
[CIR][CodeGen] Implemented CIR generation for CXXPseudoDestructorExpr (#1753)
Implemented CIR code generation for `CXXPseudoDestructorExpr`. Added a pseudo destructor test to `CIR/CodeGen/dtors.cpp`.
1 parent 1ea6ce8 commit d423af4

File tree

5 files changed

+81
-5
lines changed

5 files changed

+81
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenCall.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class CIRGenCallee {
5454
enum class SpecialKind : uintptr_t {
5555
Invalid,
5656
Builtin,
57-
PsuedoDestructor,
57+
PseudoDestructor,
5858
Virtual,
5959

6060
Last = Virtual
@@ -128,8 +128,20 @@ class CIRGenCallee {
128128
return result;
129129
}
130130

131-
bool isPsuedoDestructor() const {
132-
return KindOrFunctionPointer == SpecialKind::PsuedoDestructor;
131+
static CIRGenCallee
132+
forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr) {
133+
CIRGenCallee result(SpecialKind::PseudoDestructor);
134+
result.PseudoDestructorInfo.Expr = expr;
135+
return result;
136+
}
137+
138+
bool isPseudoDestructor() const {
139+
return KindOrFunctionPointer == SpecialKind::PseudoDestructor;
140+
}
141+
142+
const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
143+
assert(isPseudoDestructor());
144+
return PseudoDestructorInfo.Expr;
133145
}
134146

135147
bool isOrdinary() const {

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,10 +576,11 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *E) {
576576
emitIgnoredExpr(ME->getBase());
577577
return emitDirectCallee(CGM, FD);
578578
}
579+
} else if (auto *PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
580+
return CIRGenCallee::forPseudoDestructor(PDE);
579581
}
580582

581583
assert(!dyn_cast<SubstNonTypeTemplateParmExpr>(E) && "NYI");
582-
assert(!dyn_cast<CXXPseudoDestructorExpr>(E) && "NYI");
583584

584585
// Otherwise, we have an indirect reference.
585586
mlir::Value calleePtr;
@@ -1420,7 +1421,8 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *E,
14201421
return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), E,
14211422
ReturnValue);
14221423

1423-
assert(!callee.isPsuedoDestructor() && "NYI");
1424+
if (callee.isPseudoDestructor())
1425+
return emitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());
14241426

14251427
return emitCall(E->getCallee()->getType(), callee, E, ReturnValue);
14261428
}

clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,55 @@ RValue CIRGenFunction::emitCXXDestructorCall(GlobalDecl Dtor,
15781578
: getLoc(Dtor.getDecl()->getSourceRange()));
15791579
}
15801580

1581+
RValue CIRGenFunction::emitCXXPseudoDestructorExpr(
1582+
const CXXPseudoDestructorExpr *expr) {
1583+
QualType destroyedType = expr->getDestroyedType();
1584+
if (destroyedType.hasStrongOrWeakObjCLifetime()) {
1585+
// Automatic Reference Counting:
1586+
// If the pseudo-expression names a retainable object with weak or
1587+
// strong lifetime, the object shall be released.
1588+
Expr *baseExpr = expr->getBase();
1589+
Address baseValue = Address::invalid();
1590+
Qualifiers baseQuals;
1591+
1592+
// If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
1593+
if (expr->isArrow()) {
1594+
baseValue = emitPointerWithAlignment(baseExpr);
1595+
const auto *ptrTy = baseExpr->getType()->castAs<PointerType>();
1596+
baseQuals = ptrTy->getPointeeType().getQualifiers();
1597+
} else {
1598+
LValue baseLV = emitLValue(baseExpr);
1599+
baseValue = baseLV.getAddress();
1600+
QualType baseTy = baseExpr->getType();
1601+
baseQuals = baseTy.getQualifiers();
1602+
}
1603+
1604+
switch (destroyedType.getObjCLifetime()) {
1605+
case Qualifiers::OCL_None:
1606+
case Qualifiers::OCL_ExplicitNone:
1607+
case Qualifiers::OCL_Autoreleasing:
1608+
break;
1609+
1610+
case Qualifiers::OCL_Strong:
1611+
llvm_unreachable("NYI, emitArcRelease");
1612+
break;
1613+
1614+
case Qualifiers::OCL_Weak:
1615+
llvm_unreachable("NYI, emitARCDestroyWeak");
1616+
break;
1617+
}
1618+
} else {
1619+
// C++ [expr.pseudo]p1:
1620+
// The result shall only be used as the operand for the function call
1621+
// operator (), and the result of such a call has type void. The only
1622+
// effect is the evaluation of the postfix-expression before the dot or
1623+
// arrow.
1624+
emitIgnoredExpr(expr->getBase());
1625+
}
1626+
1627+
return RValue::get(nullptr);
1628+
}
1629+
15811630
/// Emit a call to an operator new or operator delete function, as implicitly
15821631
/// created by new-expressions and delete-expressions.
15831632
static RValue emitNewDeleteCall(CIRGenFunction &CGF,

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,8 @@ class CIRGenFunction : public CIRGenTypeCache {
20602060
const CXXMethodDecl *MD,
20612061
ReturnValueSlot ReturnValue);
20622062

2063+
RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
2064+
20632065
void emitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
20642066
Address Ptr);
20652067

clang/test/CIR/CodeGen/dtors.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ bool bar2() { return foo(1) && foo(2); }
105105
// CHECK: }) : (!cir.bool) -> !cir.bool
106106
// CHECK: cir.call @_ZN1XD2Ev
107107

108+
typedef int I;
109+
void pseudo_dtor() {
110+
I x = 10;
111+
x.I::~I();
112+
}
113+
// CHECK: cir.func dso_local @_Z11pseudo_dtorv()
114+
// CHECK: %[[INT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>
115+
// CHECK: %[[TEN:.*]] = cir.const #cir.int<10> : !s32i
116+
// CHECK: cir.store{{.*}} %[[TEN]], %[[INT]] : !s32i, !cir.ptr<!s32i>
117+
// CHECK: cir.return
118+
108119
// @B::~B() #1 definition call into base @A::~A()
109120
// CHECK: cir.func linkonce_odr @_ZN1BD2Ev{{.*}}{
110121
// CHECK: cir.call @_ZN1AD2Ev(

0 commit comments

Comments
 (0)