From a4ab6638cd6c4c32db9e508afc1d5c163523e708 Mon Sep 17 00:00:00 2001 From: Amr Hesham Date: Fri, 19 Dec 2025 21:59:00 +0100 Subject: [PATCH] [CIR] Implement part of ConstantExpr support for ComplexType --- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 8 +++++- clang/test/CIR/CodeGen/constant-expr.cpp | 31 +++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 clang/test/CIR/CodeGen/constant-expr.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index d1124252e13cd..f85d98f279a1c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -1,4 +1,5 @@ #include "CIRGenBuilder.h" +#include "CIRGenConstantEmitter.h" #include "CIRGenFunction.h" #include "clang/AST/StmtVisitor.h" @@ -66,7 +67,12 @@ class ComplexExprEmitter : public StmtVisitor { mlir::Value VisitExpr(Expr *e); mlir::Value VisitConstantExpr(ConstantExpr *e) { - cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitConstantExpr"); + if (mlir::Attribute result = ConstantEmitter(cgf).tryEmitConstantExpr(e)) + return builder.getConstant(cgf.getLoc(e->getSourceRange()), + mlir::cast(result)); + + cgf.cgm.errorNYI(e->getExprLoc(), + "ComplexExprEmitter VisitConstantExpr non constantexpr"); return {}; } diff --git a/clang/test/CIR/CodeGen/constant-expr.cpp b/clang/test/CIR/CodeGen/constant-expr.cpp new file mode 100644 index 0000000000000..b6120ae73f3ea --- /dev/null +++ b/clang/test/CIR/CodeGen/constant-expr.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +struct StructWithConstEval { + consteval int _Complex consteval_ret_complex() { return {1, 2}; } +}; + +void calling_consteval_methods() { + StructWithConstEval a; + int _Complex c = a.consteval_ret_complex(); +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_StructWithConstEval, !cir.ptr, ["a"] +// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["c", init] +// CIR: %[[CONST_COMPLEX:.*]] = cir.const #cir.const_complex<#cir.int<1> : !s32i, #cir.int<2> : !s32i> : !cir.complex +// CIR: cir.store {{.*}} %[[CONST_COMPLEX]], %[[C_ADDR]] : !cir.complex, !cir.ptr> + +// LLVM: %[[A_ADDR:.*]] = alloca %struct.StructWithConstEval, i64 1, align 1 +// LLVM: %[[C_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: store { i32, i32 } { i32 1, i32 2 }, ptr %[[C_ADDR]], align 4 + +// OGCG: %[[A_ADDR:.*]] = alloca %struct.StructWithConstEval, align 1 +// OGCG: %[[C_ADDR:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 0 +// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[C_ADDR]], i32 0, i32 1 +// OGCG: store i32 1, ptr %[[C_REAL_PTR]], align 4 +// OGCG: store i32 2, ptr %[[C_IMAG_PTR]], align 4