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" <[email protected]> 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", _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
