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 <am...@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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to