[clang] b2175ea - [CIR] Support SubstNonTypeTemplateParmExpr for aggregates (#223603)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 15 09:55:41 PDT 2026
Author: Aman Maurya
Date: 2026-09-15T09:55:35-07:00
New Revision: b2175ea5306fe59d8e82f8259d4d285ccd8644a3
URL: https://github.com/llvm/llvm-project/commit/b2175ea5306fe59d8e82f8259d4d285ccd8644a3
DIFF: https://github.com/llvm/llvm-project/commit/b2175ea5306fe59d8e82f8259d4d285ccd8644a3.diff
LOG: [CIR] Support SubstNonTypeTemplateParmExpr for aggregates (#223603)
Lower `SubstNonTypeTemplateParmExpr` in `AggExprEmitter` by visiting its
replacement expression, matching classic Clang codegen (`CGExprAgg.cpp`)
and existing scalar (#146751), complex (#146755), and lvalue (#182920)
implementations.
The missing aggregate NTTP gap was analyzed with LLM assistance.
Fixes #223533
Added:
Modified:
clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
clang/test/CIR/CodeGen/non-type-template-param.cpp
Removed:
################################################################################
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index afc32a3d24c42..2fb66232d806c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -402,8 +402,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
}
void VisitUnaryExtension(UnaryOperator *e) { Visit(e->getSubExpr()); }
void VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *e) {
- cgf.cgm.errorNYI(e->getSourceRange(),
- "AggExprEmitter: VisitSubstNonTypeTemplateParmExpr");
+ Visit(e->getReplacement());
}
void VisitConstantExpr(ConstantExpr *e) {
ensureDest(cgf.getLoc(e->getSourceRange()), e->getType());
diff --git a/clang/test/CIR/CodeGen/non-type-template-param.cpp b/clang/test/CIR/CodeGen/non-type-template-param.cpp
index 9edb7c0ae53d7..db792700363d4 100644
--- a/clang/test/CIR/CodeGen/non-type-template-param.cpp
+++ b/clang/test/CIR/CodeGen/non-type-template-param.cpp
@@ -1,27 +1,47 @@
-// RUN: %clang_cc1 -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 -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 -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
-
-template <const int N>
-void template_foo() {
- int a = N + 5;
-}
-
-// CIR: %[[INIT:.*]] = cir.alloca "a" {{.*}} init : !cir.ptr<!s32i>
-// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
-// CIR: %[[CONST_2:.*]] = cir.const #cir.int<5> : !s32i
-// CIR: %[[ADD:.*]] = cir.add nsw %[[CONST_1]], %[[CONST_2]] : !s32i
-// CIR: cir.store{{.*}} %[[ADD]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
-
-// LLVM: %[[INIT:.*]] = alloca i32, align 4
-// LLVM: store i32 6, ptr %[[INIT]], align 4
-
-// OGCG: %[[INIT:.*]] = alloca i32, align 4
-// OGCG: store i32 6, ptr %[[INIT]], align 4
-
-void foo() {
- template_foo<1>();
-}
+// 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=LLVM
+
+template <const int N>
+void template_foo() {
+ int a = N + 5;
+}
+
+// CIR: %[[INIT:.*]] = cir.alloca "a" {{.*}} init : !cir.ptr<!s32i>
+// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
+// CIR: %[[CONST_2:.*]] = cir.const #cir.int<5> : !s32i
+// CIR: %[[ADD:.*]] = cir.add nsw %[[CONST_1]], %[[CONST_2]] : !s32i
+// CIR: cir.store{{.*}} %[[ADD]], %[[INIT]] : !s32i, !cir.ptr<!s32i>
+
+// LLVM: %[[INIT:.*]] = alloca i32, align 4
+// LLVM: store i32 6, ptr %[[INIT]], align 4
+
+void foo() {
+ template_foo<1>();
+}
+
+struct Point {
+ int x;
+ int y;
+};
+
+template <Point P>
+void template_agg() {
+ Point a = P;
+}
+
+// CIR: %[[A:.*]] = cir.alloca {{.*}}
+// CIR: %[[GLOBAL:.*]] = cir.get_global @{{.*}}
+// CIR: cir.copy %[[GLOBAL]] to %[[A]] : !cir.ptr<{{.*}}>
+// CIR: cir.return
+
+// LLVM: %[[A:.*]] = alloca %struct.Point
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr align {{[0-9]+}} %[[A]], ptr align {{[0-9]+}} @{{.*}}, i64 8, i1 false)
+// LLVM: ret void
+
+void bar() {
+ template_agg<Point{1, 2}>();
+}
More information about the cfe-commits
mailing list