[index] Record class template specializations using a new 'SpecializationOf'
relationship

rdar://31603531

Differential Revision: https://reviews.llvm.org/D32010

llvm-svn: 300832
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp
index dae0cdc..0e89350 100644
--- a/clang/lib/Index/IndexDecl.cpp
+++ b/clang/lib/Index/IndexDecl.cpp
@@ -495,8 +495,18 @@
                                            ClassTemplateSpecializationDecl *D) {
     // FIXME: Notify subsequent callbacks if info comes from implicit
     // instantiation.
-    if (D->isThisDeclarationADefinition())
-      IndexCtx.indexTagDecl(D);
+    if (D->isThisDeclarationADefinition()) {
+      llvm::PointerUnion<ClassTemplateDecl *,
+                         ClassTemplatePartialSpecializationDecl *>
+          Template = D->getSpecializedTemplateOrPartial();
+      const Decl *SpecializationOf =
+          Template.is<ClassTemplateDecl *>()
+              ? (Decl *)Template.get<ClassTemplateDecl *>()
+              : Template.get<ClassTemplatePartialSpecializationDecl *>();
+      IndexCtx.indexTagDecl(
+          D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
+                            SpecializationOf));
+    }
     return true;
   }
 
diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp
index fe3c178..ea66b70 100644
--- a/clang/lib/Index/IndexSymbol.cpp
+++ b/clang/lib/Index/IndexSymbol.cpp
@@ -346,6 +346,7 @@
   APPLY_FOR_ROLE(RelationAccessorOf);
   APPLY_FOR_ROLE(RelationContainedBy);
   APPLY_FOR_ROLE(RelationIBTypeOf);
+  APPLY_FOR_ROLE(RelationSpecializationOf);
 
 #undef APPLY_FOR_ROLE
 
@@ -386,6 +387,7 @@
     case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
     case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
     case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
+    case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
     }
   });
 }
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 0645d5b..a3566a9 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -208,11 +208,12 @@
   }
 }
 
-void IndexingContext::indexTagDecl(const TagDecl *D) {
+void IndexingContext::indexTagDecl(const TagDecl *D,
+                                   ArrayRef<SymbolRelation> Relations) {
   if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
     return;
 
-  if (handleDecl(D)) {
+  if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) {
     if (D->isThisDeclarationADefinition()) {
       indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
       if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
diff --git a/clang/lib/Index/IndexingContext.cpp b/clang/lib/Index/IndexingContext.cpp
index f393b11..85574d0 100644
--- a/clang/lib/Index/IndexingContext.cpp
+++ b/clang/lib/Index/IndexingContext.cpp
@@ -233,6 +233,7 @@
       case SymbolRole::RelationReceivedBy:
       case SymbolRole::RelationCalledBy:
       case SymbolRole::RelationContainedBy:
+      case SymbolRole::RelationSpecializationOf:
         return true;
       }
       llvm_unreachable("Unsupported SymbolRole value!");
diff --git a/clang/lib/Index/IndexingContext.h b/clang/lib/Index/IndexingContext.h
index 933b0a2cd..1ebf6f9 100644
--- a/clang/lib/Index/IndexingContext.h
+++ b/clang/lib/Index/IndexingContext.h
@@ -80,7 +80,8 @@
 
   bool indexDecl(const Decl *D);
 
-  void indexTagDecl(const TagDecl *D);
+  void indexTagDecl(const TagDecl *D,
+                    ArrayRef<SymbolRelation> Relations = None);
 
   void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
                            const DeclContext *DC = nullptr,