Improve libclang indexing support for class template specializations
in a few related ways:

  - Don't recurse into instantiations of templates.
  - Recurse into explicit specializations.
  - Visit the template arguments of an explicit specialization or
    explicit instantiation.
  - Include template specialization arguments in the USRs for class
    template specializations.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112720 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index af521e9..3c4211e 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -290,6 +290,7 @@
   bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
   bool VisitTypedefDecl(TypedefDecl *D);
   bool VisitTagDecl(TagDecl *D);
+  bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
   bool VisitClassTemplatePartialSpecializationDecl(
                                      ClassTemplatePartialSpecializationDecl *D);
   bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
@@ -605,6 +606,41 @@
   return VisitDeclContext(D);
 }
 
+bool CursorVisitor::VisitClassTemplateSpecializationDecl(
+                                          ClassTemplateSpecializationDecl *D) {
+  bool ShouldVisitBody = false;
+  switch (D->getSpecializationKind()) {
+  case TSK_Undeclared:
+  case TSK_ImplicitInstantiation:
+    // Nothing to visit
+    return false;
+      
+  case TSK_ExplicitInstantiationDeclaration:
+  case TSK_ExplicitInstantiationDefinition:
+    break;
+      
+  case TSK_ExplicitSpecialization:
+    ShouldVisitBody = true;
+    break;
+  }
+  
+  // Visit the template arguments used in the specialization.
+  if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
+    TypeLoc TL = SpecType->getTypeLoc();
+    if (TemplateSpecializationTypeLoc *TSTLoc
+          = dyn_cast<TemplateSpecializationTypeLoc>(&TL)) {
+      for (unsigned I = 0, N = TSTLoc->getNumArgs(); I != N; ++I)
+        if (VisitTemplateArgumentLoc(TSTLoc->getArgLoc(I)))
+          return true;
+    }
+  }
+  
+  if (ShouldVisitBody && VisitCXXRecordDecl(D))
+    return true;
+  
+  return false;
+}
+
 bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
                                    ClassTemplatePartialSpecializationDecl *D) {
   // FIXME: Visit the "outer" template parameter lists on the TagDecl