[clang] [CIR] Implement MemberExpr with VarDecl for COmplexType (PR #154307)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 19 03:54:41 PDT 2025
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/154307
This change adds support for MemberExpr with VarDecl ComplexType
Issue: https://github.com/llvm/llvm-project/issues/141365
>From dd84b6ff8ec1d695887ffe4168f5dd59ff9dbce2 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <amr96 at programmer.net>
Date: Tue, 19 Aug 2025 12:53:19 +0200
Subject: [PATCH] [CIR] Implement MemberExpr with VarDecl for COmplexType
---
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 30 ++++++++++-----------
clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 +--
clang/test/CIR/CodeGen/complex.cpp | 24 +++++++++++++++++
3 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 554e60b2f3903..fd68c97308bbb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1045,10 +1045,22 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {
llvm_unreachable("Invalid cast kind");
}
+static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf,
+ const MemberExpr *me) {
+ if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {
+ // Try to emit static variable member expressions as DREs.
+ return DeclRefExpr::Create(
+ cgf.getContext(), NestedNameSpecifierLoc(), SourceLocation(), vd,
+ /*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),
+ me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());
+ }
+ return nullptr;
+}
+
LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
- if (isa<VarDecl>(e->getMemberDecl())) {
- cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: VarDecl");
- return LValue();
+ if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, e)) {
+ emitIgnoredExpr(e->getBase());
+ return emitDeclRefLValue(dre);
}
Expr *baseExpr = e->getBase();
@@ -2101,18 +2113,6 @@ CIRGenFunction::tryEmitAsConstant(const DeclRefExpr *refExpr) {
return ConstantEmission::forValue(cstToEmit);
}
-static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf,
- const MemberExpr *me) {
- if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {
- // Try to emit static variable member expressions as DREs.
- return DeclRefExpr::Create(
- cgf.getContext(), NestedNameSpecifierLoc(), SourceLocation(), vd,
- /*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),
- me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());
- }
- return nullptr;
-}
-
CIRGenFunction::ConstantEmission
CIRGenFunction::tryEmitAsConstant(const MemberExpr *me) {
if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, me))
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 6cabcb8d04e71..98310e63daaf4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -64,8 +64,8 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
mlir::Value VisitMemberExpr(MemberExpr *me) {
if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(me)) {
- cgf.cgm.errorNYI("VisitMemberExpr tryEmitAsConstant");
- return {};
+ cgf.emitIgnoredExpr(me->getBase());
+ return emitConstant(constant, me);
}
return emitLoadOfLValue(me);
}
diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp
index 90504bee3549f..e435a5e6ed010 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -829,3 +829,27 @@ void foo31() {
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ELEM_PTR]], i32 0, i32 0
// OGCG: %[[REAL:.*]] = load i32, ptr %[[REAL_PTR]], align 4
// OGCG: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
+
+struct Container {
+ static int _Complex c;
+};
+
+void foo32() {
+ Container con;
+ int r = __real__ con.c;
+}
+
+// CIR: %[[REAL_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init]
+// CIR: %[[ELEM_PTR:.*]] = cir.get_global @_ZN9Container1cE : !cir.ptr<!cir.complex<!s32i>>
+// CIR: %[[ELEM:.*]] = cir.load{{.*}} %[[ELEM_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
+// CIR: %[[REAL:.*]] = cir.complex.real %[[ELEM]] : !cir.complex<!s32i> -> !s32i
+// CIR: cir.store{{.*}} %[[REAL]], %[[REAL_ADDR]] : !s32i, !cir.ptr<!s32i>
+
+// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[ELEM:.*]] = load { i32, i32 }, ptr @_ZN9Container1cE, align 4
+// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[ELEM]], 0
+// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
+
+// OGCG: %[[REAL_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[REAL:.*]] = load i32, ptr @_ZN9Container1cE, align 4
+// OGCG: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
More information about the cfe-commits
mailing list