https://github.com/patrykstefanski created 
https://github.com/llvm/llvm-project/pull/212387

Backport 912128312f026605bce4ff11ef8a37d56a1a03f8

>From bbc60e843872b3a4c03ff4c6842c99f8d99b09fa Mon Sep 17 00:00:00 2001
From: Patryk Stefanski <[email protected]>
Date: Mon, 27 Jul 2026 16:51:06 -0700
Subject: [PATCH] [clang][Index][USR] Generate USRs for class-type non-type
 template arguments (#212356)

A class-type non-type template parameter is represented in the AST by a
TemplateParamObjectDecl, which has an empty DeclarationName.
USRGenerator had no visitor for it, so it fell through to
VisitNamedDecl, where EmitDeclName fails on the empty name and sets
IgnoreResults. That discarded the USR of the enclosing declaration.

Add a visitor that encodes the parameter object's type and value, so
specializations on distinct values get distinct USRs and equal values
agree.

Fixes #212351

(cherry picked from commit 912128312f026605bce4ff11ef8a37d56a1a03f8)
---
 clang/docs/ReleaseNotes.md                    |  2 ++
 .../UnifiedSymbolResolution/USRGeneration.cpp | 10 +++++++
 clang/test/Index/USR/class-type-tpl-arg.cpp   | 27 +++++++++++++++++++
 3 files changed, 39 insertions(+)
 create mode 100644 clang/test/Index/USR/class-type-tpl-arg.cpp

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 2ea954b442678..501a421896636 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -835,6 +835,8 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 - Fixed a case where function effect analysis (`nonblocking` etc.) did not 
visit a destructor invoked from a `delete` expression. (#GH184460)
 - Clang now defines the GCC-compatible predefined macros `__WCHAR_MIN__`, 
`__WINT_MIN__`, and `__SIG_ATOMIC_MIN__`. (#GH199678)
 - Fix a crash in addUnsizedArray due assert not verifying we have a Base 
before doing checks on it. (#GH44212)
+- Fixed USR generation for declarations whose signature mentions a class-type
+  non-type template parameter. (#GH212351)
 
 #### Bug Fixes to Compiler Builtins
 
diff --git a/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp 
b/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp
index 5f689ad32159b..f167302aca74b 100644
--- a/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp
+++ b/clang/lib/UnifiedSymbolResolution/USRGeneration.cpp
@@ -193,6 +193,7 @@ class USRGenerator : public ConstDeclVisitor<USRGenerator> {
   void VisitTemplateArgument(const TemplateArgument &Arg);
 
   void VisitMSGuidDecl(const MSGuidDecl *D);
+  void VisitTemplateParamObjectDecl(const TemplateParamObjectDecl *D);
 
   /// Emit a Decl's name using NamedDecl::printName() and return true if
   ///  the decl had no name.
@@ -1212,6 +1213,15 @@ void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
   D->NamedDecl::printName(Out);
 }
 
+void USRGenerator::VisitTemplateParamObjectDecl(
+    const TemplateParamObjectDecl *D) {
+  Out << "@TPO@";
+  VisitType(D->getType());
+  ODRHash Hash{};
+  Hash.AddStructuralValue(D->getValue());
+  Out << Hash.CalculateHash();
+}
+
 
//===----------------------------------------------------------------------===//
 // USR generation functions.
 
//===----------------------------------------------------------------------===//
diff --git a/clang/test/Index/USR/class-type-tpl-arg.cpp 
b/clang/test/Index/USR/class-type-tpl-arg.cpp
new file mode 100644
index 0000000000000..2ef0d02ece14b
--- /dev/null
+++ b/clang/test/Index/USR/class-type-tpl-arg.cpp
@@ -0,0 +1,27 @@
+// RUN: c-index-test core -print-source-symbols -- -std=c++20 %s | FileCheck %s
+
+// Check USRs of template specializations with class-type NTTP values.
+
+struct R {
+  int a;
+};
+
+template <R> struct L {};
+
+// Equal parameter object values must produce equal USRs, and distinct values
+// must produce distinct ones.
+
+// CHECK: | f | c:@F@f#$@S@L>#@TPO@1$@S@R[[#HASH0:]]#
+void f(L<R{0}>);
+
+// CHECK: | g | c:@F@g#$@S@L>#@TPO@1$@S@R[[#HASH0]]#
+void g(L<R{0}>);
+
+// CHECK: | h | c:@F@h#$@S@L>#@TPO@1$@S@R[[#HASH1:]]#
+// CHECK-NOT: | h | c:@F@h#$@S@L>#@TPO@1$@S@R[[#HASH0]]#
+void h(L<R{1}>);
+
+struct S {
+  // CHECK: | set | c:@S@S@F@set#&&$@S@L>#@TPO@1$@S@R[[#HASH0]]#
+  void set(L<R{0}> &&);
+};

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to