diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 8eea5c7a68ac..6699a54386e3 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -3272,7 +3272,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 1dbfc1866609..6dd541e196a6 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 480d44d6a00b..f0cf7df1b15a 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -102,6 +102,29 @@ int _Complex complex_real_operator_on_rvalue() { // 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 + int _Complex complex_imag_operator_on_rvalue() { int imag = __imag__ complex_imag_operator_on_rvalue(); return {};