summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-04-25 14:22:29 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-04-25 14:22:29 +0000
commit5bf767c54848baeeb37cc4afec1647871223828a (patch)
tree3f47c610d26d77d1676cbd9877eb63023157848b
parent178c369456a5ad187d6a08e3b269a81300825775 (diff)
downloadbcm5719-llvm-5bf767c54848baeeb37cc4afec1647871223828a.tar.gz
bcm5719-llvm-5bf767c54848baeeb37cc4afec1647871223828a.zip
[index] Record the 'SpecializationOf' relation for function specializations
rdar://31603531 llvm-svn: 301310
-rw-r--r--clang/lib/Index/IndexDecl.cpp4
-rw-r--r--clang/test/Index/Core/index-source.cpp35
2 files changed, 39 insertions, 0 deletions
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp
index ba65889a6f9..a60d2f699fe 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 76b8a150edb..f83c3d33e99 100644
--- a/clang/test/Index/Core/index-source.cpp
+++ b/clang/test/Index/Core/index-source.cpp
@@ -220,3 +220,38 @@ class ConflictingPseudoOverridesInSpecialization<int, T> {
// 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<typename T, typename U, int x>
+void functionSpecialization();
+
+template<typename T, typename U, int x>
+void functionSpecialization() { }
+// CHECK: [[@LINE-1]]:6 | function/C | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v# | <no-cgname> | Def | rel: 0
+
+template<>
+void functionSpecialization<int, int, 0>();
+// 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<int, int, 0>() { }
+// 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<typename T>
+ void memberSpecialization();
+};
+
+template<typename T>
+void ContainsSpecializedMemberFunction::memberSpecialization() {
+// CHECK: [[@LINE-1]]:41 | instance-method/C++ | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@FT@>1#TmemberSpecialization#v# | <no-cgname> | Def,RelChild | rel: 1
+// CHECK-NEXT: RelChild
+}
+
+template<>
+void ContainsSpecializedMemberFunction::memberSpecialization<int>() {
+// 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#
+}
OpenPOWER on IntegriCloud