diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-11-16 02:34:59 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-11-16 02:34:59 +0000 |
commit | c6b4a5099588fd21b49c80f730a596a64b2766c6 (patch) | |
tree | 10db8d9ef00e48879206fc21dfccdb418e54cc06 | |
parent | 220b45c95edc0ea86cd157426e0edc7f6a288620 (diff) |
[libclang] Indexing API: if the CXIndexOpt_OneRefPerFile option is set, only report one reference
per file.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144763 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | tools/c-index-test/c-index-test.c | 11 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.cpp | 38 | ||||
-rw-r--r-- | tools/libclang/IndexingContext.h | 44 |
3 files changed, 85 insertions, 8 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index ed58fd28fb..56b555213a 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -1645,6 +1645,11 @@ static void printEntityInfo(const char *cb, index_data = (IndexData *)client_data; printCheck(index_data); + if (!info) { + printf("%s: <<NULL>>", cb); + return; + } + name = info->name; if (!name) name = "<anon-tag>"; @@ -1848,7 +1853,8 @@ static int index_file(int argc, const char **argv) { result = clang_indexSourceFile(CIdx, &index_data, &IndexCB,sizeof(IndexCB), - 0, 0, argv, argc, 0, 0, 0, 0); + CXIndexOpt_OneRefPerFile, + 0, argv, argc, 0, 0, 0, 0); if (index_data.fail_for_error) return -1; @@ -1890,7 +1896,8 @@ static int index_tu(int argc, const char **argv) { index_data.fail_for_error = 0; result = clang_indexTranslationUnit(TU, &index_data, - &IndexCB,sizeof(IndexCB), 0); + &IndexCB,sizeof(IndexCB), + CXIndexOpt_OneRefPerFile); if (index_data.fail_for_error) return -1; diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp index a6e968b8fe..15fcde174d 100644 --- a/tools/libclang/IndexingContext.cpp +++ b/tools/libclang/IndexingContext.cpp @@ -239,12 +239,17 @@ void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) { const ObjCInterfaceDecl *IFaceD = D->getClassInterface(); SourceLocation ClassLoc = D->getLocation(); SourceLocation CategoryLoc = D->getCategoryNameLoc(); - getEntityInfo(D->getClassInterface(), ClassEntity, SA); + getEntityInfo(IFaceD, ClassEntity, SA); CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo; - CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity; - CatDInfo.ObjCCatDeclInfo.classCursor = - MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU); + if (IFaceD) { + CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity; + CatDInfo.ObjCCatDeclInfo.classCursor = + MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU); + } else { + CatDInfo.ObjCCatDeclInfo.objcClass = 0; + CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor(); + } CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc); handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo); } @@ -285,6 +290,27 @@ void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, if (isNotFromSourceFile(D->getLocation())) return; + D = getEntityDecl(D); + + if (onlyOneRefPerFile()) { + SourceManager &SM = Ctx->getSourceManager(); + SourceLocation FileLoc = SM.getFileLoc(Loc); + + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); + FileID FID = LocInfo.first; + if (FID.isInvalid()) + return; + + const FileEntry *FE = SM.getFileEntryForID(FID); + if (!FE) + return; + RefFileOccurence RefOccur(FE, D); + std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool> + res = RefFileOccurences.insert(RefOccur); + if (!res.second) + return; // already in map. + } + StrAdapter SA(*this); CXCursor Cursor = E ? MakeCXCursor(const_cast<Expr*>(E), const_cast<Decl*>(cast<Decl>(DC)), CXTU) @@ -296,7 +322,7 @@ void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc, CXIdxEntityRefInfo Info = { Cursor, getIndexLoc(Loc), &RefEntity, - &ParentEntity, + Parent ? &ParentEntity : 0, getIndexContainerForDC(DC), Kind }; CB.indexEntityReference(ClientData, &Info); @@ -431,6 +457,8 @@ void IndexingContext::translateLoc(SourceLocation Loc, void IndexingContext::getEntityInfo(const NamedDecl *D, CXIdxEntityInfo &EntityInfo, StrAdapter &SA) { + if (!D) + return; D = getEntityDecl(D); EntityInfo.kind = CXIdxEntity_Unexposed; diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h index fa43a55ecc..35545d281f 100644 --- a/tools/libclang/IndexingContext.h +++ b/tools/libclang/IndexingContext.h @@ -12,7 +12,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclGroup.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" namespace clang { class FileEntry; @@ -133,6 +133,14 @@ struct ObjCCategoryDeclInfo : public ObjCContainerDeclInfo { static bool classof(const ObjCCategoryDeclInfo *D) { return true; } }; +struct RefFileOccurence { + const FileEntry *File; + const Decl *Dcl; + + RefFileOccurence(const FileEntry *File, const Decl *Dcl) + : File(File), Dcl(Dcl) { } +}; + class IndexingContext { ASTContext *Ctx; CXClientData ClientData; @@ -145,6 +153,8 @@ class IndexingContext { FileMapTy FileMap; ContainerMapTy ContainerMap; + llvm::DenseSet<RefFileOccurence> RefFileOccurences; + SmallVector<DeclGroupRef, 8> TUDeclsInObjCContainer; llvm::SmallString<256> StrScratch; @@ -204,6 +214,10 @@ public: void setASTContext(ASTContext &ctx); + bool onlyOneRefPerFile() const { + return IndexOptions & CXIndexOpt_OneRefPerFile; + } + void enteredMainFile(const FileEntry *File); void ppIncludedFile(SourceLocation hashLoc, @@ -313,3 +327,31 @@ private: }; }} // end clang::cxindex + +namespace llvm { + /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and + /// DenseSets. + template <> + struct DenseMapInfo<clang::cxindex::RefFileOccurence> { + static inline clang::cxindex::RefFileOccurence getEmptyKey() { + return clang::cxindex::RefFileOccurence(0, 0); + } + + static inline clang::cxindex::RefFileOccurence getTombstoneKey() { + return clang::cxindex::RefFileOccurence((const clang::FileEntry *)~0, + (const clang::Decl *)~0); + } + + static unsigned getHashValue(clang::cxindex::RefFileOccurence S) { + llvm::FoldingSetNodeID ID; + ID.AddPointer(S.File); + ID.AddPointer(S.Dcl); + return ID.ComputeHash(); + } + + static bool isEqual(clang::cxindex::RefFileOccurence LHS, + clang::cxindex::RefFileOccurence RHS) { + return LHS.File == RHS.File && LHS.Dcl == RHS.Dcl; + } + }; +} |