[libclang] Indexing API: if the CXIndexOpt_OneRefPerFile option is set, only report one reference

per file.

llvm-svn: 144763
This commit is contained in:
Argyrios Kyrtzidis 2011-11-16 02:34:59 +00:00
parent f03e734876
commit e4acd23f0b
3 changed files with 85 additions and 8 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
};
}