-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[CIR] Add CIRGen for pseudo destructor calls #153014
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clangir Author: Sirui Mu (Lancern) ChangesThis patch adds CIRGen support for C++ pseudo destructor call expressions. Full diff: https://github.com/llvm/llvm-project/pull/153014.diff 7 Files Affected:
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index fcc8ce7caf111..f410be4293aef 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -87,7 +87,6 @@ struct MissingFeatures {
static bool setFunctionAttributes() { return false; }
// CallOp handling
- static bool opCallPseudoDtor() { return false; }
static bool opCallAggregateArgs() { return false; }
static bool opCallPaddingArgs() { return false; }
static bool opCallABIExtendArg() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.h b/clang/lib/CIR/CodeGen/CIRGenCall.h
index 28576a15068fa..47d998ae25838 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.h
@@ -46,6 +46,7 @@ class CIRGenCallee {
enum class SpecialKind : uintptr_t {
Invalid,
Builtin,
+ PseudoDestructor,
Last = Builtin,
};
@@ -54,12 +55,16 @@ class CIRGenCallee {
const clang::FunctionDecl *decl;
unsigned id;
};
+ struct PseudoDestructorInfoStorage {
+ const clang::CXXPseudoDestructorExpr *expr;
+ };
SpecialKind kindOrFunctionPtr;
union {
CIRGenCalleeInfo abstractInfo;
BuiltinInfoStorage builtinInfo;
+ PseudoDestructorInfoStorage pseudoDestructorInfo;
};
explicit CIRGenCallee(SpecialKind kind) : kindOrFunctionPtr(kind) {}
@@ -98,6 +103,22 @@ class CIRGenCallee {
return result;
}
+ static CIRGenCallee
+ forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr) {
+ CIRGenCallee result(SpecialKind::PseudoDestructor);
+ result.pseudoDestructorInfo.expr = expr;
+ return result;
+ }
+
+ bool isPseudoDestructor() const {
+ return kindOrFunctionPtr == SpecialKind::PseudoDestructor;
+ }
+
+ const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
+ assert(isPseudoDestructor());
+ return pseudoDestructorInfo.expr;
+ }
+
bool isOrdinary() const {
return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c437b14dd8d1c..54f8cd8859b7b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1543,10 +1543,10 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
cgm.errorNYI(e->getSourceRange(),
"emitCallee: call to member function is NYI");
return {};
+ } else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
+ return CIRGenCallee::forPseudoDestructor(pde);
}
- assert(!cir::MissingFeatures::opCallPseudoDtor());
-
// Otherwise, we have an indirect reference.
mlir::Value calleePtr;
QualType functionType;
@@ -1598,10 +1598,8 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,
returnValue);
- if (isa<CXXPseudoDestructorExpr>(e->getCallee())) {
- cgm.errorNYI(e->getSourceRange(), "call to pseudo destructor");
- }
- assert(!cir::MissingFeatures::opCallPseudoDtor());
+ if (callee.isPseudoDestructor())
+ return emitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());
return emitCall(e->getCallee()->getType(), callee, e, returnValue);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
new file mode 100644
index 0000000000000..55847da7c9493
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
@@ -0,0 +1,34 @@
+//===--- CIRGenExprCXX.cpp - Emit CIR Code for C++ expressions ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with code generation of C++ expressions
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenFunction.h"
+#include "clang/AST/ExprCXX.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+RValue CIRGenFunction::emitCXXPseudoDestructorExpr(
+ const CXXPseudoDestructorExpr *expr) {
+ QualType destroyedType = expr->getDestroyedType();
+ if (destroyedType.hasStrongOrWeakObjCLifetime()) {
+ assert(!cir::MissingFeatures::objCLifetime());
+ } else {
+ // C++ [expr.pseudo]p1:
+ // The result shall only be used as the operand for the function call
+ // operator (), and the result of such a call has type void. The only
+ // effect is the evaluation of the postfix-expression before the dot or
+ // arrow.
+ emitIgnoredExpr(expr->getBase());
+ }
+
+ return RValue::get(nullptr);
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 065039ec041e0..a6cb958de4130 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1032,6 +1032,8 @@ class CIRGenFunction : public CIRGenTypeCache {
const CXXMethodDecl *md,
ReturnValueSlot returnValue);
+ RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
+
void emitCtorPrologue(const clang::CXXConstructorDecl *ctor,
clang::CXXCtorType ctorType, FunctionArgList &args);
@@ -1197,7 +1199,7 @@ class CIRGenFunction : public CIRGenTypeCache {
/// reasonable to just ignore the returned alignment when it isn't from an
/// explicit source.
Address emitPointerWithAlignment(const clang::Expr *expr,
- LValueBaseInfo *baseInfo);
+ LValueBaseInfo *baseInfo = nullptr);
/// Emits a reference binding to the passed in expression.
RValue emitReferenceBindingToExpr(const Expr *e);
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index ca3a329d0c56d..a095b896cb0a8 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -22,6 +22,7 @@ add_clang_library(clangCIR
CIRGenExprAggregate.cpp
CIRGenExprComplex.cpp
CIRGenExprConstant.cpp
+ CIRGenExprCXX.cpp
CIRGenExprScalar.cpp
CIRGenFunction.cpp
CIRGenItaniumCXXABI.cpp
diff --git a/clang/test/CIR/CodeGen/call.cpp b/clang/test/CIR/CodeGen/call.cpp
index 43e5d150a949f..3e8cfc1cceb51 100644
--- a/clang/test/CIR/CodeGen/call.cpp
+++ b/clang/test/CIR/CodeGen/call.cpp
@@ -116,4 +116,18 @@ void f14() {
// LLVM: call void @_Z3f13v() #[[LLVM_ATTR_0:.+]]
// LLVM: }
-// LLLVM: attributes #[[LLVM_ATTR_0]] = { nounwind }
+int f15();
+void f16() {
+ using T = int;
+ f15().~T();
+}
+
+// CIR-LABEL: @_Z3f16v
+// CIR-NEXT: %{{.+}} = cir.call @_Z3f15v() : () -> !s32i
+// CIR: }
+
+// LLVM-LABEL: define{{.+}} void @_Z3f16v() {
+// LLVM-NEXT: %{{.+}} = call i32 @_Z3f15v()
+// LLVM: }
+
+// LLVM: attributes #[[LLVM_ATTR_0]] = { nounwind }
|
andykaylor
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. Just a couple of nits.
bcardosolopes
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once comments are applied
8d567b7 to
e582ab5
Compare
e582ab5 to
3758e9d
Compare
This patch adds CIRGen support for C++ pseudo destructor call expressions.