Author: Amr Hesham
Date: 2025-08-20T10:33:08+02:00
New Revision: 018c5ba161ead9b98c081bb91d54d59c4741f6db

URL: 
https://github.com/llvm/llvm-project/commit/018c5ba161ead9b98c081bb91d54d59c4741f6db
DIFF: 
https://github.com/llvm/llvm-project/commit/018c5ba161ead9b98c081bb91d54d59c4741f6db.diff

LOG: [CIR] Implement MemberExpr with VarDecl for ComplexType (#154307)

This change adds support for MemberExpr with VarDecl ComplexType

Issue: https://github.com/llvm/llvm-project/issues/141365

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExpr.cpp
    clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
    clang/test/CIR/CodeGen/complex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 2b248bb65b241..057b518cb39c6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1046,10 +1046,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();
@@ -2102,18 +2114,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