Introduce a new libclang function,
clang_getSpecializedCursorTemplate(), which determines the template
(or member thereof) that the given cursor specializes or from which it
was instantiated. This routine can be used to establish a link between
templates and their instantiations/specializations.

llvm-svn: 112780
diff --git a/clang/tools/libclang/CIndexCXX.cpp b/clang/tools/libclang/CIndexCXX.cpp
index ee83f98..3ade519 100644
--- a/clang/tools/libclang/CIndexCXX.cpp
+++ b/clang/tools/libclang/CIndexCXX.cpp
@@ -19,6 +19,7 @@
 
 using namespace clang;
 using namespace clang::cxstring;
+using namespace clang::cxcursor;
 
 extern "C" {
 
@@ -26,7 +27,7 @@
   if (C.kind != CXCursor_CXXBaseSpecifier)
     return 0;
   
-  CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+  CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
   return B->isVirtual();
 }
 
@@ -34,7 +35,7 @@
   if (C.kind != CXCursor_CXXBaseSpecifier)
     return CX_CXXInvalidAccessSpecifier;
   
-  CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
+  CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
   switch (B->getAccessSpecifier()) {
     case AS_public: return CX_CXXPublic;
     case AS_protected: return CX_CXXProtected;
@@ -78,4 +79,46 @@
   return CXCursor_NoDeclFound;
 }
 
+CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return clang_getNullCursor();
+    
+  Decl *D = getCursorDecl(C);
+  if (!D)
+    return clang_getNullCursor();
+  
+  Decl *Template = 0;
+  if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
+    if (ClassTemplatePartialSpecializationDecl *PartialSpec
+          = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
+      Template = PartialSpec->getSpecializedTemplate();
+    else if (ClassTemplateSpecializationDecl *ClassSpec 
+               = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
+      llvm::PointerUnion<ClassTemplateDecl *,
+                         ClassTemplatePartialSpecializationDecl *> Result
+        = ClassSpec->getSpecializedTemplateOrPartial();
+      if (Result.is<ClassTemplateDecl *>())
+        Template = Result.get<ClassTemplateDecl *>();
+      else
+        Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
+      
+    } else 
+      Template = CXXRecord->getInstantiatedFromMemberClass();
+  } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
+    Template = Function->getPrimaryTemplate();
+    if (!Template)
+      Template = Function->getInstantiatedFromMemberFunction();
+  } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    if (Var->isStaticDataMember())
+      Template = Var->getInstantiatedFromStaticDataMember();
+  } else if (RedeclarableTemplateDecl *Tmpl
+                                        = dyn_cast<RedeclarableTemplateDecl>(D))
+    Template = Tmpl->getInstantiatedFromMemberTemplate();
+  
+  if (!Template)
+    return clang_getNullCursor();
+  
+  return MakeCXCursor(Template, getCursorASTUnit(C));
+}
+  
 } // end extern "C"