[libclang] Introduce a new high level API for indexing clients that assumes
more of the work involved in indexing a translation unit and simplifies client
implementations.
Only C/ObjC for now, C++ (and comments) to come.
llvm-svn: 142233
diff --git a/clang/tools/libclang/IndexingContext.cpp b/clang/tools/libclang/IndexingContext.cpp
new file mode 100644
index 0000000..7c0ceaf
--- /dev/null
+++ b/clang/tools/libclang/IndexingContext.cpp
@@ -0,0 +1,695 @@
+//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IndexingContext.h"
+#include "CXTranslationUnit.h"
+#include "CIndexDiagnostic.h"
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace clang;
+using namespace cxindex;
+using namespace cxcursor;
+
+const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
+ if (Str.empty())
+ return "";
+ if (Str.data()[Str.size()] == '\0')
+ return Str.data();
+ Scratch += Str;
+ Scratch.push_back('\0');
+ return Scratch.data() + (Scratch.size() - Str.size() - 1);
+}
+
+void IndexingContext::setASTContext(ASTContext &ctx) {
+ Ctx = &ctx;
+ static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
+}
+
+void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
+ StringRef filename,
+ const FileEntry *File,
+ bool isImport, bool isAngled) {
+ if (!CB.ppIncludedFile)
+ return;
+
+ StrAdapter SA(this);
+ CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
+ SA.toCStr(filename),
+ getIndexFile(File),
+ isImport, isAngled };
+ CB.ppIncludedFile(ClientData, &Info);
+}
+
+void IndexingContext::ppMacroDefined(SourceLocation Loc, StringRef Name,
+ SourceLocation DefBegin, unsigned Length,
+ const void *OpaqueMacro) {
+ if (!CB.ppMacroDefined)
+ return;
+
+ StrAdapter SA(this);
+ CXIdxMacroInfo MacroInfo = { getIndexLoc(Loc), SA.toCStr(Name) };
+ CXIdxMacroDefinedInfo Info = { &MacroInfo,
+ getIndexLoc(DefBegin), Length };
+ CXIdxMacro idxMacro = CB.ppMacroDefined(ClientData, &Info);
+ MacroMap[OpaqueMacro] = idxMacro;
+}
+
+void IndexingContext::ppMacroUndefined(SourceLocation Loc, StringRef Name,
+ const void *OpaqueMacro) {
+ if (!CB.ppMacroUndefined)
+ return;
+
+ StrAdapter SA(this);
+ CXIdxMacroUndefinedInfo Info = { getIndexLoc(Loc),
+ SA.toCStr(Name), 0 };
+ CB.ppMacroUndefined(ClientData, &Info);
+}
+
+void IndexingContext::ppMacroExpanded(SourceLocation Loc, StringRef Name,
+ const void *OpaqueMacro) {
+ if (!CB.ppMacroExpanded)
+ return;
+
+ StrAdapter SA(this);
+ CXIdxMacroExpandedInfo Info = { getIndexLoc(Loc),
+ SA.toCStr(Name), 0 };
+ CB.ppMacroExpanded(ClientData, &Info);
+}
+
+void IndexingContext::invokeStartedTranslationUnit() {
+ CXIdxContainer idxCont = 0;
+ if (CB.startedTranslationUnit)
+ idxCont = CB.startedTranslationUnit(ClientData, 0);
+ addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
+}
+
+void IndexingContext::invokeFinishedTranslationUnit() {
+ invokeEndedContainer(Ctx->getTranslationUnitDecl());
+}
+
+void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag) {
+ if (!CB.diagnostic)
+ return;
+
+ CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions());
+ CB.diagnostic(ClientData, &CXDiag, 0);
+}
+
+void IndexingContext::handleFunction(const FunctionDecl *D) {
+ StrAdapter SA(this);
+
+ if (D->isFirstDeclaration()) {
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexFunction) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxFunctionInfo Info = { &IdxEntityInfo,
+ D->isThisDeclarationADefinition() };
+
+ idxEntity = CB.indexFunction(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+
+ } else {
+ if (CB.indexFunctionRedeclaration) {
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedRedeclInfo RedeclInfo;
+ getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+ CXIdxFunctionRedeclInfo Info = { &RedeclInfo,
+ D->isThisDeclarationADefinition() };
+
+ CB.indexFunctionRedeclaration(ClientData, &Info);
+ }
+ }
+}
+
+void IndexingContext::handleVar(const VarDecl *D) {
+ StrAdapter SA(this);
+
+ if (D->isFirstDeclaration()) {
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexVariable) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxVariableInfo Info = { &IdxEntityInfo,
+ D->isThisDeclarationADefinition() };
+
+ idxEntity = CB.indexVariable(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+
+ } else {
+ if (CB.indexVariableRedeclaration) {
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedRedeclInfo RedeclInfo;
+ getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+ CXIdxVariableRedeclInfo Info = { &RedeclInfo,
+ D->isThisDeclarationADefinition() };
+
+ CB.indexVariableRedeclaration(ClientData, &Info);
+ }
+ }
+}
+
+void IndexingContext::handleField(const FieldDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexTypedef) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxFieldInfo Info = { &IdxEntityInfo };
+
+ idxEntity = CB.indexField(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexTypedef) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxEnumeratorInfo Info = { &IdxEntityInfo };
+
+ idxEntity = CB.indexEnumerator(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleTagDecl(const TagDecl *D) {
+ StrAdapter SA(this);
+
+ if (D->isFirstDeclaration()) {
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexTagType) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxTagTypeInfo Info = { &IdxEntityInfo,
+ D->isThisDeclarationADefinition(),
+ D->getIdentifier() == 0};
+
+ idxEntity = CB.indexTagType(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+
+ } else {
+ if (CB.indexTagTypeRedeclaration) {
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedRedeclInfo RedeclInfo;
+ getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+ CXIdxTagTypeRedeclInfo Info = { &RedeclInfo,
+ D->isThisDeclarationADefinition() };
+
+ CB.indexTagTypeRedeclaration(ClientData, &Info);
+ }
+ }
+}
+
+void IndexingContext::handleTypedef(const TypedefDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexTypedef) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxTypedefInfo Info = { &IdxEntityInfo };
+
+ idxEntity = CB.indexTypedef(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexObjCClass) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxObjCClassInfo Info = { &IdxEntityInfo,
+ D->isForwardDecl() };
+
+ idxEntity = CB.indexObjCClass(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::defineObjCInterface(const ObjCInterfaceDecl *D) {
+ if (!CB.defineObjCClass)
+ return;
+
+ CXIdxObjCBaseClassInfo BaseClass = { getIndexEntity(D->getSuperClass()),
+ getIndexLoc(D->getSuperClassLoc()) };
+ if (D->getSuperClass()) {
+ BaseClass.objcClass = getIndexEntity(D->getSuperClass());
+ BaseClass.loc = getIndexLoc(D->getSuperClassLoc());
+ }
+
+ SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
+ ObjCInterfaceDecl::protocol_loc_iterator LI = D->protocol_loc_begin();
+ for (ObjCInterfaceDecl::protocol_iterator
+ I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) {
+ SourceLocation Loc = *LI;
+ ObjCProtocolDecl *PD = *I;
+ CXIdxObjCProtocolRefInfo ProtInfo = { getIndexEntity(PD),
+ getIndexLoc(Loc) };
+ ProtInfos.push_back(ProtInfo);
+ }
+
+ SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
+ for (unsigned i = 0, e = Prots.size(); i != e; ++i)
+ Prots.push_back(&ProtInfos[i]);
+
+ CXIdxObjCClassDefineInfo Info = { getCursor(D),
+ getIndexEntity(D),
+ getIndexContainerForDC(D),
+ D->getSuperClass() ? &BaseClass : 0,
+ Prots.data(),
+ Prots.size() };
+ CB.defineObjCClass(ClientData, &Info);
+}
+
+void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexObjCProtocol) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxObjCProtocolInfo Info = { &IdxEntityInfo,
+ D->isForwardDecl() };
+
+ idxEntity = CB.indexObjCProtocol(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexObjCCategory) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxObjCCategoryInfo Info = { &IdxEntityInfo,
+ getIndexEntity(D->getClassInterface()) };
+
+ idxEntity = CB.indexObjCCategory(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
+ StrAdapter SA(this);
+
+ if (D->isCanonicalDecl()) {
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexObjCMethod) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxObjCMethodInfo Info = { &IdxEntityInfo,
+ D->isThisDeclarationADefinition() };
+
+ idxEntity = CB.indexObjCMethod(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+
+ } else {
+ if (CB.indexObjCMethodRedeclaration) {
+ CXIdxIndexedRedeclInfo RedeclInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
+ CXIdxObjCMethodRedeclInfo Info = { &RedeclInfo,
+ D->isThisDeclarationADefinition() };
+
+ CB.indexObjCMethodRedeclaration(ClientData, &Info);
+ }
+ }
+}
+
+void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.indexObjCProperty) {
+ CXIdxEntityInfo EntityInfo;
+ CXIdxIndexedDeclInfo DeclInfo;
+ CXIdxIndexedEntityInfo IdxEntityInfo;
+ getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
+ CXIdxObjCPropertyInfo Info = { &IdxEntityInfo };
+
+ idxEntity = CB.indexObjCProperty(ClientData, &Info);
+ }
+
+ addEntityInMap(D, idxEntity);
+}
+
+void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
+ const NamedDecl *Parent,
+ const DeclContext *DC,
+ const Expr *E) {
+ if (Loc.isInvalid())
+ return;
+ if (!CB.indexEntityReference)
+ return;
+ if (isNotFromSourceFile(D->getLocation()))
+ return;
+
+ CXIdxEntityRefInfo Info = { E ? MakeCXCursor((Stmt*)E,
+ (Decl*)cast<Decl>(DC), CXTU)
+ : getRefCursor(D, Loc),
+ getIndexLoc(Loc),
+ getIndexEntity(D),
+ getIndexEntity(Parent),
+ getIndexContainerForDC(DC) };
+ CB.indexEntityReference(ClientData, &Info);
+}
+
+void IndexingContext::invokeStartedStatementBody(const NamedDecl *D,
+ const DeclContext *DC) {
+ const Stmt *Body = cast<Decl>(DC)->getBody();
+ assert(Body);
+
+ CXIdxContainer idxCont = 0;
+ if (CB.startedStatementBody) {
+ CXIdxContainerInfo ContainerInfo;
+ getContainerInfo(D, ContainerInfo);
+ CXIdxStmtBodyInfo Info = { &ContainerInfo,
+ getIndexLoc(Body->getLocStart()) };
+
+ idxCont = CB.startedStatementBody(ClientData, &Info);
+ }
+ addContainerInMap(DC, idxCont);
+}
+
+void IndexingContext::invokeStartedTagTypeDefinition(const TagDecl *D) {
+ CXIdxContainer idxCont = 0;
+ if (CB.startedTagTypeDefinition) {
+ CXIdxContainerInfo ContainerInfo;
+ getContainerInfo(D, ContainerInfo);
+ CXIdxTagTypeDefinitionInfo Info = { &ContainerInfo };
+
+ idxCont = CB.startedTagTypeDefinition(ClientData, &Info);
+ }
+ addContainerInMap(D, idxCont);
+}
+
+void IndexingContext::invokeStartedObjCContainer(const ObjCContainerDecl *D) {
+ CXIdxContainer idxCont = 0;
+ if (CB.startedObjCContainer) {
+ CXIdxContainerInfo ContainerInfo;
+ getContainerInfo(D, ContainerInfo);
+ CXIdxObjCContainerInfo Info = { &ContainerInfo };
+
+ idxCont = CB.startedObjCContainer(ClientData, &Info);
+ }
+ addContainerInMap(D, idxCont);
+}
+
+void IndexingContext::invokeEndedContainer(const DeclContext *DC) {
+ if (CB.endedContainer) {
+ CXIdxEndContainerInfo Info = { getIndexContainerForDC(DC),
+ getIndexLoc(cast<Decl>(DC)->getLocEnd()) };
+ CB.endedContainer(ClientData, &Info);
+ }
+}
+
+bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
+ if (Loc.isInvalid())
+ return true;
+ SourceManager &SM = Ctx->getSourceManager();
+ SourceLocation FileLoc = SM.getFileLoc(Loc);
+ FileID FID = SM.getFileID(FileLoc);
+ return SM.getFileEntryForID(FID) == 0;
+}
+
+void IndexingContext::addContainerInMap(const DeclContext *DC,
+ CXIdxContainer container) {
+ assert(getScopedContext(DC) == DC);
+ ContainerMapTy::iterator I = ContainerMap.find(DC);
+ if (I == ContainerMap.end()) {
+ if (container)
+ ContainerMap[DC] = container;
+ return;
+ }
+ // Allow changing the container of a previously seen DeclContext so we
+ // can handle invalid user code, like a function re-definition.
+ if (container)
+ I->second = container;
+ else
+ ContainerMap.erase(I);
+}
+
+void IndexingContext::addEntityInMap(const NamedDecl *D, CXIdxEntity entity) {
+ assert(getEntityDecl(D) == D &&
+ "Tried to add a non-entity (canonical) decl");
+ assert(EntityMap.find(D) == EntityMap.end());
+ if (entity || D->isFromASTFile())
+ EntityMap[D] = entity;
+}
+
+CXIdxEntity IndexingContext::getIndexEntity(const NamedDecl *D) {
+ if (!D)
+ return 0;
+ D = getEntityDecl(D);
+ EntityMapTy::const_iterator I = EntityMap.find(D);
+ if (I != EntityMap.end())
+ return I->second;
+
+ if (!D->isFromASTFile()) {
+ //assert(0 && "Entity not in map");
+ return 0;
+ }
+
+ StrAdapter SA(this);
+
+ CXIdxEntity idxEntity = 0;
+ if (CB.importedEntity) {
+ CXIdxEntityInfo EntityInfo;
+ getEntityInfo(D, EntityInfo, SA);
+ CXIdxImportedEntityInfo Info = { &EntityInfo,
+ getCursor(D),
+ getIndexLoc(D->getLocation()),
+ /*CXIdxASTFile*/0 };
+ idxEntity = CB.importedEntity(ClientData, &Info);
+ }
+ addEntityInMap(D, idxEntity);
+ return idxEntity;
+}
+
+const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
+ assert(D);
+ D = cast<NamedDecl>(D->getCanonicalDecl());
+
+ if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) {
+ if (Cat->IsClassExtension())
+ return getEntityDecl(Cat->getClassInterface());
+
+ } else if (const ObjCImplementationDecl *
+ ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
+ return getEntityDecl(ImplD->getClassInterface());
+
+ } else if (const ObjCCategoryImplDecl *
+ CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
+ return getEntityDecl(CatImplD->getCategoryDecl());
+ }
+
+ return D;
+}
+
+const DeclContext *
+IndexingContext::getScopedContext(const DeclContext *DC) const {
+ // Local contexts are ignored for indexing.
+ const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
+ if (FuncCtx)
+ return FuncCtx;
+
+ // We consider enums always scoped for indexing.
+ if (isa<TagDecl>(DC))
+ return DC;
+
+ if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+ if (NS->isAnonymousNamespace())
+ return getScopedContext(NS->getParent());
+ return NS;
+ }
+
+ return DC->getRedeclContext();
+}
+
+CXIdxContainer
+IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
+ DC = getScopedContext(DC);
+ ContainerMapTy::const_iterator I = ContainerMap.find(DC);
+// assert(I != ContainerMap.end() &&
+// "Failed to include a scoped context in the container map");
+ return I->second;
+}
+
+CXIdxFile IndexingContext::getIndexFile(const FileEntry *File) {
+ if (!File)
+ return 0;
+ if (!CB.recordFile)
+ return 0;
+
+ FileMapTy::iterator FI = FileMap.find(File);
+ if (FI != FileMap.end())
+ return FI->second;
+
+ CXIdxFile idxFile = CB.recordFile(ClientData, (CXFile)File, 0);
+ FileMap[File] = idxFile;
+ return idxFile;
+}
+
+CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
+ CXIdxLoc idxLoc = { {0, 0}, 0 };
+ if (Loc.isInvalid())
+ return idxLoc;
+
+ idxLoc.ptr_data[0] = (void*)this;
+ idxLoc.int_data = Loc.getRawEncoding();
+ return idxLoc;
+}
+
+void IndexingContext::translateLoc(SourceLocation Loc,
+ CXIdxFile *indexFile, CXFile *file,
+ unsigned *line, unsigned *column,
+ unsigned *offset) {
+ if (Loc.isInvalid())
+ return;
+
+ SourceManager &SM = Ctx->getSourceManager();
+ Loc = SM.getFileLoc(Loc);
+
+ std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+ FileID FID = LocInfo.first;
+ unsigned FileOffset = LocInfo.second;
+
+ if (FID.isInvalid())
+ return;
+
+ const FileEntry *FE = SM.getFileEntryForID(FID);
+ if (indexFile)
+ *indexFile = getIndexFile(FE);
+ if (file)
+ *file = (void *)FE;
+ if (line)
+ *line = SM.getLineNumber(FID, FileOffset);
+ if (column)
+ *column = SM.getColumnNumber(FID, FileOffset);
+ if (offset)
+ *offset = FileOffset;
+}
+
+void IndexingContext::getIndexedEntityInfo(const NamedDecl *D,
+ CXIdxIndexedEntityInfo &IdxEntityInfo,
+ CXIdxEntityInfo &EntityInfo,
+ CXIdxIndexedDeclInfo &IdxDeclInfo,
+ StrAdapter &SA) {
+ getEntityInfo(D, EntityInfo, SA);
+ getIndexedDeclInfo(D, IdxDeclInfo);
+ IdxEntityInfo.entityInfo = &EntityInfo;
+ IdxEntityInfo.declInfo = &IdxDeclInfo;
+}
+
+void IndexingContext::getIndexedDeclInfo(const NamedDecl *D,
+ CXIdxIndexedDeclInfo &IdxDeclInfo) {
+ IdxDeclInfo.cursor = getCursor(D);
+ IdxDeclInfo.loc = getIndexLoc(D->getLocation());
+ IdxDeclInfo.container = getIndexContainer(D);
+}
+
+void IndexingContext::getIndexedRedeclInfo(const NamedDecl *D,
+ CXIdxIndexedRedeclInfo &RedeclInfo,
+ CXIdxIndexedDeclInfo &IdxDeclInfo) {
+ getIndexedDeclInfo(D, IdxDeclInfo);
+ RedeclInfo.declInfo = &IdxDeclInfo;
+ RedeclInfo.entity = getIndexEntity(D);
+}
+
+void IndexingContext::getContainerInfo(const NamedDecl *D,
+ CXIdxContainerInfo &ContainerInfo) {
+ ContainerInfo.cursor = getCursor(D);
+ ContainerInfo.loc = getIndexLoc(D->getLocation());
+ ContainerInfo.entity = getIndexEntity(D);
+}
+
+void IndexingContext::getEntityInfo(const NamedDecl *D,
+ CXIdxEntityInfo &EntityInfo,
+ StrAdapter &SA) {
+ if (IdentifierInfo *II = D->getIdentifier()) {
+ EntityInfo.name = SA.toCStr(II->getName());
+
+ } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
+ EntityInfo.name = 0;
+
+ } else {
+ unsigned Begin = SA.getCurSize();
+ {
+ llvm::raw_svector_ostream OS(SA.getBuffer());
+ D->printName(OS);
+ }
+ EntityInfo.name = SA.getCStr(Begin);
+ }
+
+ unsigned Begin = SA.getCurSize();
+ bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
+ if (Ignore) {
+ EntityInfo.USR = "";
+ } else {
+ EntityInfo.USR = SA.getCStr(Begin);
+ }
+}
+
+CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
+ if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
+ return MakeCursorTypeRef(TD, Loc, CXTU);
+ if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+ return MakeCursorObjCClassRef(ID, Loc, CXTU);
+ if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+ return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
+
+ //assert(0 && "not yet");
+ return clang_getNullCursor();
+}