[clang] [llvm] improve update_cc_test_checks.py for template (PR #102505)
Yaxun Liu via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 29 18:29:27 PDT 2026
https://github.com/yxsamliu updated https://github.com/llvm/llvm-project/pull/102505
>From 51c8dc82f6eb4e77f9d2216ee4263ab08083b958 Mon Sep 17 00:00:00 2001
From: "Yaxun (Sam) Liu" <yaxun.liu at amd.com>
Date: Tue, 29 Sep 2026 21:27:12 -0400
Subject: [PATCH] [utils] Generate checks for function template instantiations
Clang's JSON AST nests instantiated functions under FunctionTemplateDecl.
Visit the mangled declarations to generate checks at the template definition.
Add a script test with two instantiations and an unused template. Check the
generated IR and verify that a second run leaves the output unchanged.
---
.../function-template-instantiation.cpp | 7 +++++
...nction-template-instantiation.cpp.expected | 26 +++++++++++++++++++
.../function-template-instantiation.test | 8 ++++++
llvm/utils/update_cc_test_checks.py | 6 +++++
4 files changed, 47 insertions(+)
create mode 100644 clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp
create mode 100644 clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp.expected
create mode 100644 clang/test/utils/update_cc_test_checks/function-template-instantiation.test
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp b/clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp
new file mode 100644
index 00000000000000..24415112cc94ad
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+template <typename T> T twice(T x) { return x + x; }
+template int twice<int>(int);
+template long twice<long>(long);
+
+template <typename T> T unused(T x) { return x; }
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp.expected b/clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp.expected
new file mode 100644
index 00000000000000..efca1a14ac5fd6
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/function-template-instantiation.cpp.expected
@@ -0,0 +1,26 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @_Z5twiceIiET_S0_(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT: store i32 [[X:%.*]], ptr [[X_ADDR]], align 4
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[X_ADDR]], align 4
+// CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: ret i32 [[ADD]]
+//
+// CHECK-LABEL: @_Z5twiceIlET_S0_(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[X_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT: store i64 [[X:%.*]], ptr [[X_ADDR]], align 8
+// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[X_ADDR]], align 8
+// CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[X_ADDR]], align 8
+// CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: ret i64 [[ADD]]
+//
+template <typename T> T twice(T x) { return x + x; }
+template int twice<int>(int);
+template long twice<long>(long);
+
+template <typename T> T unused(T x) { return x; }
diff --git a/clang/test/utils/update_cc_test_checks/function-template-instantiation.test b/clang/test/utils/update_cc_test_checks/function-template-instantiation.test
new file mode 100644
index 00000000000000..a05a04102c311d
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/function-template-instantiation.test
@@ -0,0 +1,8 @@
+## Test CHECK generation for instantiated function templates.
+
+# RUN: cp %S/Inputs/function-template-instantiation.cpp %t.cpp && %update_cc_test_checks %t.cpp
+# RUN: diff -u %S/Inputs/function-template-instantiation.cpp.expected %t.cpp
+# RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %t.cpp | FileCheck %t.cpp
+## Re-running the script must not change the generated checks.
+# RUN: %update_cc_test_checks %t.cpp
+# RUN: diff -u %S/Inputs/function-template-instantiation.cpp.expected %t.cpp
diff --git a/llvm/utils/update_cc_test_checks.py b/llvm/utils/update_cc_test_checks.py
index 97b446d5659734..16ab4741065054 100755
--- a/llvm/utils/update_cc_test_checks.py
+++ b/llvm/utils/update_cc_test_checks.py
@@ -64,6 +64,12 @@ def get_line2func_list(args, clang_args, globals_name_prefix):
# TODO: Should we add checks for global variables being emitted?
def parse_clang_ast_json(node, loc, search):
node_kind = node["kind"]
+ if node_kind == "FunctionTemplateDecl":
+ # The template pattern has no mangled name; its instantiations do.
+ for inner in node.get("inner", []):
+ if inner.get("kind") == "FunctionDecl" and inner.get("mangledName"):
+ parse_clang_ast_json(inner, node["loc"], search)
+ return
# Recurse for the following nodes that can contain nested function decls:
if node_kind in (
"NamespaceDecl",
More information about the cfe-commits
mailing list