From beeb8510aed8205484b668b418d4fbb93af960c1 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Tue, 19 Aug 2025 11:23:10 +0200 Subject: [PATCH] [CIR] Backport MemberExpr support for ComplexType --- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 4 +++- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 9 +++++++- clang/test/CIR/CodeGen/complex.cpp | 23 +++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index a7d82534383b..a46f1252180c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -3270,7 +3270,9 @@ CIRGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) { CIRGenFunction::ConstantEmission CIRGenFunction::tryEmitAsConstant(const MemberExpr *ME) { - llvm_unreachable("NYI"); + if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, ME)) + return tryEmitAsConstant(dre); + return ConstantEmission(); } mlir::Value CIRGenFunction::emitScalarConstant( diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index c9b4ac21be2d..891dd456ba2f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -109,7 +109,14 @@ class ComplexExprEmitter : public StmtVisitor { llvm_unreachable("NYI"); } mlir::Value VisitArraySubscriptExpr(Expr *E) { return emitLoadOfLValue(E); } - mlir::Value VisitMemberExpr(MemberExpr *ME) { llvm_unreachable("NYI"); } + + mlir::Value VisitMemberExpr(MemberExpr *ME) { + if (CIRGenFunction::ConstantEmission constant = CGF.tryEmitAsConstant(ME)) { + llvm_unreachable("VisitMemberExpr tryEmitAsConstant"); + } + return emitLoadOfLValue(ME); + } + mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *E) { llvm_unreachable("NYI"); } diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 8f639b8248ad..2b8fd573245f 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -85,3 +85,26 @@ int _Complex complex_real_operator_on_rvalue() { // LLVM: store { i32, i32 } zeroinitializer, ptr %[[RET_ADDR]], align 4 // LLVM: %[[TMP_RET:.*]] = load { i32, i32 }, ptr %[[RET_ADDR]], align 4 // LLVM: ret { i32, i32 } %[[TMP_RET]] + +void complex_member_expr() { + struct Wrapper { + int _Complex c; + }; + + Wrapper w; + int r = __real__ w.c; +} + +// CIR: %[[W_ADDR:.*]] = cir.alloca !rec_Wrapper, !cir.ptr, ["w"] +// CIR: %[[REAL_ADDR:.*]] = cir.alloca !s32i, !cir.ptr, ["r", init] +// CIR: %[[ELEM_PTR:.*]] = cir.get_member %[[W_ADDR]][0] {name = "c"} : !cir.ptr -> !cir.ptr> +// CIR: %[[TMP_ELEM_PTR:.*]] = cir.load{{.*}} %[[ELEM_PTR]] : !cir.ptr>, !cir.complex +// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP_ELEM_PTR]] : !cir.complex -> !s32i +// CIR: cir.store{{.*}} %[[REAL]], %[[REAL_ADDR]] : !s32i, !cir.ptr + +// LLVM: %[[W_ADDR:.*]] = alloca %struct.Wrapper, i64 1, align 4 +// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[ELEM_PTR:.*]] = getelementptr %struct.Wrapper, ptr %[[W_ADDR]], i32 0, i32 0 +// LLVM: %[[TMP_ELEM_PTR:.*]] = load { i32, i32 }, ptr %[[ELEM_PTR]], align 4 +// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[TMP_ELEM_PTR]], 0 +// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4