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