Skip to content

Commit d528537

Browse files
authored
[Clang][Index] Add support for dependent class scope explicit specializations of function templates to USRGenerator (llvm#98027)
Given the following: ``` template<typename T> struct A { void f(int); // #1 template<typename U> void f(U); // llvm#2 template<> void f<int>(int); // llvm#3 }; ``` Clang will generate the same USR for `#1` and `llvm#2`. This patch fixes the issue by including the template arguments of dependent class scope explicit specializations in their USRs.
1 parent 359c64f commit d528537

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed

clang/lib/Index/USRGeneration.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,20 @@ void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
257257
!D->hasAttr<OverloadableAttr>())
258258
return;
259259

260-
if (const TemplateArgumentList *
261-
SpecArgs = D->getTemplateSpecializationArgs()) {
260+
if (D->isFunctionTemplateSpecialization()) {
262261
Out << '<';
263-
for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
264-
Out << '#';
265-
VisitTemplateArgument(SpecArgs->get(I));
262+
if (const TemplateArgumentList *SpecArgs =
263+
D->getTemplateSpecializationArgs()) {
264+
for (const auto &Arg : SpecArgs->asArray()) {
265+
Out << '#';
266+
VisitTemplateArgument(Arg);
267+
}
268+
} else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
269+
D->getTemplateSpecializationArgsAsWritten()) {
270+
for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
271+
Out << '#';
272+
VisitTemplateArgument(ArgLoc.getArgument());
273+
}
266274
}
267275
Out << '>';
268276
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
2+
3+
template<typename T>
4+
struct A {
5+
void f(int);
6+
// CHECK: {{[0-9]+}}:8 | instance-method/C++ | f | c:@ST>1#T@A@F@f#I# |
7+
8+
template<typename U>
9+
void f(U);
10+
// CHECK: {{[0-9]+}}:8 | instance-method/C++ | f | c:@ST>1#T@A@FT@>1#Tf#t1.0#v# |
11+
12+
template<>
13+
void f<int>(int);
14+
// CHECK: {{[0-9]+}}:8 | instance-method/C++ | f | c:@ST>1#T@A@F@f<#I>#I# |
15+
};

0 commit comments

Comments
 (0)