]> granicus.if.org Git - clang/commitdiff
[libclang] Fix indexing of C++ bases in a C++ class.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 7 Dec 2011 20:44:15 +0000 (20:44 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 7 Dec 2011 20:44:15 +0000 (20:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146068 91177308-0d34-0410-b5e6-96231b3b80d8

tools/c-index-test/c-index-test.c
tools/libclang/IndexingContext.cpp
tools/libclang/IndexingContext.h

index fb41d1374470a76cce8dd0026068ed4371af2e78..18a0a6b28ddbc4204c96e2e006ff4d3a0e4d0f7b 100644 (file)
@@ -1699,6 +1699,15 @@ static void printEntityInfo(const char *cb,
   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 @@ static void index_indexDeclaration(CXClientData client_data,
   const CXIdxObjCCategoryDeclInfo *CatInfo;
   const CXIdxObjCInterfaceDeclInfo *InterInfo;
   const CXIdxObjCProtocolRefListInfo *ProtoInfo;
+  const CXIdxCXXClassDeclInfo *CXXClassInfo;
   unsigned i;
   index_data = (IndexData *)client_data;
 
@@ -1832,12 +1842,7 @@ static void index_indexDeclaration(CXClientData client_data,
 
   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 @@ static void index_indexDeclaration(CXClientData client_data,
     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));
index bb00acfea372ce0c948a509d232bfd6a462cb38e..0ec8619bed2e49b74db84e9dbcc044f35beab67f 100644 (file)
@@ -100,15 +100,23 @@ IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
     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 @@ IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
     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 "";
index a8a8edb36299d279dfca828e76b47654f2baaafb..ff5ca1b819b3354938304ff828db81c5b349cecd 100644 (file)
@@ -293,6 +293,9 @@ class IndexingContext {
 
     CXXBasesListInfo(const CXXRecordDecl *D,
                      IndexingContext &IdxCtx, IndexingContext::StrAdapter &SA);
+
+  private:
+    SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const;
   };
 
 public: