Skip to content

[Clang][Index] Add support for dependent class scope explicit specializations of function templates to USRGenerator #98027

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged

Conversation

sdkrystian
Copy link
Member

Given the following:

template<typename T>
struct A
{
    void f(int); // #1
    
    template<typename U>
    void f(U); // #2
    
    template<>
    void f<int>(int); // #3
};

Clang will generate the same USR for #1 and #2. This patch fixes the issue by including the template arguments of dependent class scope explicit specializations in their USRs.

…izations of function templates to USRGenerator
@sdkrystian sdkrystian requested a review from mizvekov July 8, 2024 14:22
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Jul 8, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 8, 2024

@llvm/pr-subscribers-clang

Author: Krystian Stasiowski (sdkrystian)

Changes

Given the following:

template&lt;typename T&gt;
struct A
{
    void f(int); // #<!-- -->1
    
    template&lt;typename U&gt;
    void f(U); // #<!-- -->2
    
    template&lt;&gt;
    void f&lt;int&gt;(int); // #<!-- -->3
};

Clang will generate the same USR for #<!-- -->1 and #<!-- -->2. This patch fixes the issue by including the template arguments of dependent class scope explicit specializations in their USRs.


Full diff: https://github.com/llvm/llvm-project/pull/98027.diff

2 Files Affected:

  • (modified) clang/lib/Index/USRGeneration.cpp (+13-5)
  • (added) clang/test/Index/USR/func-template.cpp (+15)
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 5036ddee35fd12..ad7870309c5df1 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -257,12 +257,20 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
       !D->hasAttr<OverloadableAttr>())
     return;
 
-  if (const TemplateArgumentList *
-        SpecArgs = D->getTemplateSpecializationArgs()) {
+  if (D->isFunctionTemplateSpecialization()) {
     Out << '<';
-    for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
-      Out << '#';
-      VisitTemplateArgument(SpecArgs->get(I));
+    if (const TemplateArgumentList *SpecArgs =
+            D->getTemplateSpecializationArgs()) {
+      for (const auto &Arg : SpecArgs->asArray()) {
+        Out << '#';
+        VisitTemplateArgument(Arg);
+      }
+    } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
+                   D->getTemplateSpecializationArgsAsWritten()) {
+      for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
+        Out << '#';
+        VisitTemplateArgument(ArgLoc.getArgument());
+      }
     }
     Out << '>';
   }
diff --git a/clang/test/Index/USR/func-template.cpp b/clang/test/Index/USR/func-template.cpp
new file mode 100644
index 00000000000000..c9c82f5e30a751
--- /dev/null
+++ b/clang/test/Index/USR/func-template.cpp
@@ -0,0 +1,15 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+template<typename T>
+struct A {
+  void f(int);
+  // CHECK: {{[0-9]+}}:8 | instance-method/C++ | f | c:@ST>1#T@A@F@f#I# |
+  
+  template<typename U>
+  void f(U);
+  // CHECK: {{[0-9]+}}:8 | instance-method/C++ | f | c:@ST>1#T@A@FT@>1#Tf#t1.0#v# |
+  
+  template<>
+  void f<int>(int);
+  // CHECK: {{[0-9]+}}:8 | instance-method/C++ | f | c:@ST>1#T@A@F@f<#I>#I# |
+};

@sdkrystian sdkrystian merged commit d528537 into llvm:main Jul 8, 2024
9 checks passed
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants