From 5bf767c54848baeeb37cc4afec1647871223828a Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Tue, 25 Apr 2017 14:22:29 +0000 Subject: [PATCH] [index] Record the 'SpecializationOf' relation for function specializations rdar://31603531 llvm-svn: 301310 --- clang/lib/Index/IndexDecl.cpp | 4 +++ clang/test/Index/Core/index-source.cpp | 35 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index ba65889a6f90..a60d2f699fec 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -206,6 +206,10 @@ public: } } gatherTemplatePseudoOverrides(D, Relations); + if (const auto *Base = D->getPrimaryTemplate()) + Relations.push_back( + SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf), + Base->getTemplatedDecl())); TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations)); handleDeclarator(D); diff --git a/clang/test/Index/Core/index-source.cpp b/clang/test/Index/Core/index-source.cpp index 76b8a150edba..f83c3d33e99e 100644 --- a/clang/test/Index/Core/index-source.cpp +++ b/clang/test/Index/Core/index-source.cpp @@ -220,3 +220,38 @@ class ConflictingPseudoOverridesInSpecialization { // CHECK-NEXT: RelOver,RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.0# // CHECK-NEXT: RelOver,RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.1# }; + +template +void functionSpecialization(); + +template +void functionSpecialization() { } +// CHECK: [[@LINE-1]]:6 | function/C | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v# | | Def | rel: 0 + +template<> +void functionSpecialization(); +// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSpecialization | c:@F@functionSpecialization<#I#I#VI0># | __Z22functionSpecializationIiiLi0EEvv | Decl,RelSpecialization | rel: 1 +// CHECK-NEXT: RelSpecialization | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v# + +template<> +void functionSpecialization() { } +// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSpecialization | c:@F@functionSpecialization<#I#I#VI0># | __Z22functionSpecializationIiiLi0EEvv | Def,RelSpecialization | rel: 1 +// CHECK-NEXT: RelSpecialization | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v# + +struct ContainsSpecializedMemberFunction { + template + void memberSpecialization(); +}; + +template +void ContainsSpecializedMemberFunction::memberSpecialization() { +// CHECK: [[@LINE-1]]:41 | instance-method/C++ | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@FT@>1#TmemberSpecialization#v# | | Def,RelChild | rel: 1 +// CHECK-NEXT: RelChild +} + +template<> +void ContainsSpecializedMemberFunction::memberSpecialization() { +// CHECK: [[@LINE-1]]:41 | instance-method(Gen,TS)/C++ | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@F@memberSpecialization<#I># | __ZN33ContainsSpecializedMemberFunction20memberSpecializationIiEEvv | Def,RelChild,RelSpecialization | rel: 2 +// CHECK-NEXT: RelChild +// CHECK-NEXT: RelSpecialization | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@FT@>1#TmemberSpecialization#v# +}