diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-07 20:44:15 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-12-07 20:44:15 +0000 |
commit | b526a871af40b84d9878eded54a181bf4003b376 (patch) | |
tree | b50df2f905bf7eedf76acc915b0ef9769fdacc2c | |
parent | 838d3c23204f52ae27a9f5e9a254238a7ac5d41b (diff) |
[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
-rw-r--r-- | tools/c-index-test/c-index-test.c | 24 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.cpp | 39 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.h | 3 |
3 files changed, 56 insertions, 10 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index fb41d13744..18a0a6b28d 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -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)); diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp index bb00acfea3..0ec8619bed 100644 --- a/tools/libclang/IndexingContext.cpp +++ b/tools/libclang/IndexingContext.cpp @@ -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 ""; diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h index a8a8edb362..ff5ca1b819 100644 --- a/tools/libclang/IndexingContext.h +++ b/tools/libclang/IndexingContext.h @@ -293,6 +293,9 @@ class IndexingContext { CXXBasesListInfo(const CXXRecordDecl *D, IndexingContext &IdxCtx, IndexingContext::StrAdapter &SA); + + private: + SourceLocation getBaseLoc(const CXXBaseSpecifier &Base) const; }; public: |