[libclang] Fix indexing of C++ bases in a C++ class.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146068 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index fb41d13..18a0a6b 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1699,6 +1699,15 @@
   printf(" | USR: %s", info->USR);
 }
 
+static void printBaseClassInfo(CXClientData client_data,
+                               const CXIdxBaseClassInfo *info) {
+  printEntityInfo("     <base>", client_data, info->base);
+  printf(" | cursor: ");
+  PrintCursor(info->cursor);
+  printf(" | loc: ");
+  printCXIndexLoc(info->loc);
+}
+
 static void printProtocolList(const CXIdxObjCProtocolRefListInfo *ProtoInfo,
                               CXClientData client_data) {
   unsigned i;
@@ -1783,6 +1792,7 @@
   const CXIdxObjCCategoryDeclInfo *CatInfo;
   const CXIdxObjCInterfaceDeclInfo *InterInfo;
   const CXIdxObjCProtocolRefListInfo *ProtoInfo;
+  const CXIdxCXXClassDeclInfo *CXXClassInfo;
   unsigned i;
   index_data = (IndexData *)client_data;
 
@@ -1832,12 +1842,7 @@
 
   if ((InterInfo = clang_index_getObjCInterfaceDeclInfo(info))) {
     if (InterInfo->superInfo) {
-      printEntityInfo("     <base>", client_data,
-                      InterInfo->superInfo->base);
-      printf(" | cursor: ");
-      PrintCursor(InterInfo->superInfo->cursor);
-      printf(" | loc: ");
-      printCXIndexLoc(InterInfo->superInfo->loc);
+      printBaseClassInfo(client_data, InterInfo->superInfo);
       printf("\n");
     }
   }
@@ -1846,6 +1851,13 @@
     printProtocolList(ProtoInfo, client_data);
   }
 
+  if ((CXXClassInfo = clang_index_getCXXClassDeclInfo(info))) {
+    for (i = 0; i != CXXClassInfo->numBases; ++i) {
+      printBaseClassInfo(client_data, CXXClassInfo->bases[i]);
+      printf("\n");
+    }
+  }
+
   if (info->declAsContainer)
     clang_index_setClientContainer(info->declAsContainer,
                               makeClientContainer(info->entityInfo, info->loc));
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index bb00acf..0ec8619 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -100,15 +100,23 @@
     const CXXBaseSpecifier &Base = *I;
     BaseEntities.push_back(EntityInfo());
     const NamedDecl *BaseD = 0;
-    if (const RecordType *RT = Base.getType()->getAs<RecordType>())
-      BaseD = RT->getDecl();
-    else if (const TypedefType *TDT = Base.getType()->getAs<TypedefType>())
+    QualType T = Base.getType();
+    SourceLocation Loc = getBaseLoc(Base);
+
+    if (const TypedefType *TDT = T->getAs<TypedefType>()) {
       BaseD = TDT->getDecl();
+    } else if (const TemplateSpecializationType *
+          TST = T->getAs<TemplateSpecializationType>()) {
+      BaseD = TST->getTemplateName().getAsTemplateDecl();
+    } else if (const RecordType *RT = T->getAs<RecordType>()) {
+      BaseD = RT->getDecl();
+    }
+
     if (BaseD)
       IdxCtx.getEntityInfo(BaseD, BaseEntities.back(), SA);
     CXIdxBaseClassInfo BaseInfo = { 0,
                          MakeCursorCXXBaseSpecifier(&Base, IdxCtx.CXTU),
-                         IdxCtx.getIndexLoc(Base.getSourceRange().getBegin()) };
+                         IdxCtx.getIndexLoc(Loc) };
     BaseInfos.push_back(BaseInfo);
   }
 
@@ -121,6 +129,29 @@
     CXBases.push_back(&BaseInfos[i]);
 }
 
+SourceLocation IndexingContext::CXXBasesListInfo::getBaseLoc(
+                                           const CXXBaseSpecifier &Base) const {
+  SourceLocation Loc = Base.getSourceRange().getBegin();
+  TypeLoc TL;
+  if (Base.getTypeSourceInfo())
+    TL = Base.getTypeSourceInfo()->getTypeLoc();
+  if (TL.isNull())
+    return Loc;
+
+  if (const QualifiedTypeLoc *QL = dyn_cast<QualifiedTypeLoc>(&TL))
+    TL = QL->getUnqualifiedLoc();
+
+  if (const ElaboratedTypeLoc *EL = dyn_cast<ElaboratedTypeLoc>(&TL))
+    return EL->getNamedTypeLoc().getBeginLoc();
+  if (const DependentNameTypeLoc *DL = dyn_cast<DependentNameTypeLoc>(&TL))
+    return DL->getNameLoc();
+  if (const DependentTemplateSpecializationTypeLoc *
+        DTL = dyn_cast<DependentTemplateSpecializationTypeLoc>(&TL))
+    return DTL->getNameLoc();
+
+  return Loc;
+}
+
 const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
   if (Str.empty())
     return "";
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index a8a8edb..ff5ca1b 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -293,6 +293,9 @@
 
     CXXBasesListInfo(const CXXRecordDecl *D,
                      IndexingContext &IdxCtx, IndexingContext::StrAdapter &SA);
+
+  private:
+    SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const;
   };
 
 public: