forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			547 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			547 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
//===- 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;
 | 
						|
 | 
						|
IndexingContext::ObjCProtocolListInfo::ObjCProtocolListInfo(
 | 
						|
                                    const ObjCProtocolList &ProtList,
 | 
						|
                                    IndexingContext &IdxCtx,
 | 
						|
                                    StrAdapter &SA) {
 | 
						|
  ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
 | 
						|
  for (ObjCInterfaceDecl::protocol_iterator
 | 
						|
         I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
 | 
						|
    SourceLocation Loc = *LI;
 | 
						|
    ObjCProtocolDecl *PD = *I;
 | 
						|
    ProtEntities.push_back(CXIdxEntityInfo());
 | 
						|
    IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
 | 
						|
    CXIdxObjCProtocolRefInfo ProtInfo = { 0,
 | 
						|
                                MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
 | 
						|
                                IdxCtx.getIndexLoc(Loc) };
 | 
						|
    ProtInfos.push_back(ProtInfo);
 | 
						|
  }
 | 
						|
 | 
						|
  for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
 | 
						|
    ProtInfos[i].protocol = &ProtEntities[i];
 | 
						|
 | 
						|
  for (unsigned i = 0, e = ProtInfos.size(); i != e; ++i)
 | 
						|
    Prots.push_back(&ProtInfos[i]);
 | 
						|
}
 | 
						|
 | 
						|
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::enteredMainFile(const FileEntry *File) {
 | 
						|
  if (File && CB.enteredMainFile) {
 | 
						|
    CXIdxClientFile idxFile = CB.enteredMainFile(ClientData, (CXFile)File, 0);
 | 
						|
    FileMap[File] = idxFile;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
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),
 | 
						|
                                 (CXFile)File,
 | 
						|
                                 isImport, isAngled };
 | 
						|
  CXIdxClientFile idxFile = CB.ppIncludedFile(ClientData, &Info);
 | 
						|
  FileMap[File] = idxFile;
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::startedTranslationUnit() {
 | 
						|
  CXIdxClientContainer idxCont = 0;
 | 
						|
  if (CB.startedTranslationUnit)
 | 
						|
    idxCont = CB.startedTranslationUnit(ClientData, 0);
 | 
						|
  addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag) {
 | 
						|
  if (!CB.diagnostic)
 | 
						|
    return;
 | 
						|
 | 
						|
  CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions());
 | 
						|
  CB.diagnostic(ClientData, &CXDiag, 0);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleDiagnostic(CXDiagnostic CXDiag) {
 | 
						|
  if (!CB.diagnostic)
 | 
						|
    return;
 | 
						|
 | 
						|
  CB.diagnostic(ClientData, CXDiag, 0);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleDecl(const NamedDecl *D,
 | 
						|
                                 SourceLocation Loc, CXCursor Cursor,
 | 
						|
                                 DeclInfo &DInfo) {
 | 
						|
  if (!CB.indexDeclaration)
 | 
						|
    return;
 | 
						|
 | 
						|
  StrAdapter SA(*this);
 | 
						|
  getEntityInfo(D, DInfo.CXEntInfo, SA);
 | 
						|
  DInfo.entityInfo = &DInfo.CXEntInfo;
 | 
						|
  DInfo.cursor = Cursor;
 | 
						|
  DInfo.loc = getIndexLoc(Loc);
 | 
						|
  DInfo.container = getIndexContainer(D);
 | 
						|
  DInfo.isImplicit = D->isImplicit();
 | 
						|
 | 
						|
  CXIdxClientContainer clientCont = 0;
 | 
						|
  CXIdxDeclOut DeclOut = { DInfo.isContainer ? &clientCont : 0 };
 | 
						|
  CB.indexDeclaration(ClientData, &DInfo, &DeclOut);
 | 
						|
 | 
						|
  if (DInfo.isContainer)
 | 
						|
    addContainerInMap(cast<DeclContext>(D), clientCont);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCContainer(const ObjCContainerDecl *D,
 | 
						|
                                          SourceLocation Loc, CXCursor Cursor,
 | 
						|
                                          ObjCContainerDeclInfo &ContDInfo) {
 | 
						|
  ContDInfo.ObjCContDeclInfo.declInfo = &ContDInfo;
 | 
						|
  handleDecl(D, Loc, Cursor, ContDInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleFunction(const FunctionDecl *D) {
 | 
						|
  DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
 | 
						|
                 D->isThisDeclarationADefinition());
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleVar(const VarDecl *D) {
 | 
						|
  DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
 | 
						|
                 /*isContainer=*/false);
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleField(const FieldDecl *D) {
 | 
						|
  DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
 | 
						|
                 /*isContainer=*/false);
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
 | 
						|
  DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/true,
 | 
						|
                 /*isContainer=*/false);
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleTagDecl(const TagDecl *D) {
 | 
						|
  DeclInfo DInfo(!D->isFirstDeclaration(), D->isThisDeclarationADefinition(),
 | 
						|
                 D->isThisDeclarationADefinition());
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleTypedef(const TypedefDecl *D) {
 | 
						|
  DeclInfo DInfo(!D->isFirstDeclaration(), /*isDefinition=*/true,
 | 
						|
                 /*isContainer=*/false);
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCClass(const ObjCClassDecl *D) {
 | 
						|
  const ObjCClassDecl::ObjCClassRef *Ref = D->getForwardDecl();
 | 
						|
  ObjCInterfaceDecl *IFaceD = Ref->getInterface();
 | 
						|
  SourceLocation Loc = Ref->getLocation();
 | 
						|
  bool isRedeclaration = IFaceD->getLocation() != Loc;
 | 
						|
 
 | 
						|
  ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true, isRedeclaration,
 | 
						|
                                  /*isImplementation=*/false);
 | 
						|
  handleObjCContainer(IFaceD, Loc, MakeCursorObjCClassRef(IFaceD, Loc, CXTU),
 | 
						|
                      ContDInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
 | 
						|
  StrAdapter SA(*this);
 | 
						|
 | 
						|
  CXIdxBaseClassInfo BaseClass;
 | 
						|
  CXIdxEntityInfo BaseEntity;
 | 
						|
  BaseClass.cursor = clang_getNullCursor();
 | 
						|
  if (ObjCInterfaceDecl *SuperD = D->getSuperClass()) {
 | 
						|
    getEntityInfo(SuperD, BaseEntity, SA);
 | 
						|
    SourceLocation SuperLoc = D->getSuperClassLoc();
 | 
						|
    BaseClass.base = &BaseEntity;
 | 
						|
    BaseClass.cursor = MakeCursorObjCSuperClassRef(SuperD, SuperLoc, CXTU);
 | 
						|
    BaseClass.loc = getIndexLoc(SuperLoc);
 | 
						|
  }
 | 
						|
  
 | 
						|
  ObjCProtocolListInfo ProtInfo(D->getReferencedProtocols(), *this, SA);
 | 
						|
  
 | 
						|
  ObjCInterfaceDeclInfo InterInfo(D);
 | 
						|
  InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
 | 
						|
  InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
 | 
						|
  InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
 | 
						|
  InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
 | 
						|
 | 
						|
  handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCImplementation(
 | 
						|
                                              const ObjCImplementationDecl *D) {
 | 
						|
  ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/false,
 | 
						|
                      /*isRedeclaration=*/true,
 | 
						|
                      /*isImplementation=*/true);
 | 
						|
  handleObjCContainer(D, D->getLocation(), getCursor(D), ContDInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCForwardProtocol(const ObjCProtocolDecl *D,
 | 
						|
                                                SourceLocation Loc,
 | 
						|
                                                bool isRedeclaration) {
 | 
						|
  ObjCContainerDeclInfo ContDInfo(/*isForwardRef=*/true,
 | 
						|
                                  isRedeclaration,
 | 
						|
                                  /*isImplementation=*/false);
 | 
						|
  handleObjCContainer(D, Loc, MakeCursorObjCProtocolRef(D, Loc, CXTU),
 | 
						|
                      ContDInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
 | 
						|
  StrAdapter SA(*this);
 | 
						|
  ObjCProtocolListInfo ProtListInfo(D->getReferencedProtocols(), *this, SA);
 | 
						|
  
 | 
						|
  ObjCProtocolDeclInfo ProtInfo(D);
 | 
						|
  ProtInfo.ObjCProtoRefListInfo = ProtListInfo.getListInfo();
 | 
						|
 | 
						|
  handleObjCContainer(D, D->getLocation(), getCursor(D), ProtInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
 | 
						|
  ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
 | 
						|
  CXIdxEntityInfo ClassEntity;
 | 
						|
  StrAdapter SA(*this);
 | 
						|
  const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
 | 
						|
  SourceLocation ClassLoc = D->getLocation();
 | 
						|
  SourceLocation CategoryLoc = D->getCategoryNameLoc();
 | 
						|
  getEntityInfo(IFaceD, ClassEntity, SA);
 | 
						|
 | 
						|
  CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
 | 
						|
  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);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
 | 
						|
  const ObjCCategoryDecl *CatD = D->getCategoryDecl();
 | 
						|
  ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
 | 
						|
  CXIdxEntityInfo ClassEntity;
 | 
						|
  StrAdapter SA(*this);
 | 
						|
  getEntityInfo(CatD->getClassInterface(), ClassEntity, SA);
 | 
						|
 | 
						|
  CatDInfo.ObjCCatDeclInfo.containerInfo = &CatDInfo.ObjCContDeclInfo;
 | 
						|
  CatDInfo.ObjCCatDeclInfo.objcClass = &ClassEntity;
 | 
						|
  handleObjCContainer(D, D->getLocation(), getCursor(D), CatDInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
 | 
						|
  DeclInfo DInfo(!D->isCanonicalDecl(), D->isThisDeclarationADefinition(),
 | 
						|
                 D->isThisDeclarationADefinition());
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
 | 
						|
  DeclInfo DInfo(/*isRedeclaration=*/false, /*isDefinition=*/false,
 | 
						|
                 /*isContainer=*/false);
 | 
						|
  handleDecl(D, D->getLocation(), getCursor(D), DInfo);
 | 
						|
}
 | 
						|
 | 
						|
void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
 | 
						|
                                      const NamedDecl *Parent,
 | 
						|
                                      const DeclContext *DC,
 | 
						|
                                      const Expr *E,
 | 
						|
                                      CXIdxEntityRefKind Kind) {
 | 
						|
  if (Loc.isInvalid())
 | 
						|
    return;
 | 
						|
  if (!CB.indexEntityReference)
 | 
						|
    return;
 | 
						|
  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)
 | 
						|
                      : getRefCursor(D, Loc);
 | 
						|
 | 
						|
  CXIdxEntityInfo RefEntity, ParentEntity;
 | 
						|
  getEntityInfo(D, RefEntity, SA);
 | 
						|
  getEntityInfo(Parent, ParentEntity, SA);
 | 
						|
  CXIdxEntityRefInfo Info = { Cursor,
 | 
						|
                              getIndexLoc(Loc),
 | 
						|
                              &RefEntity,
 | 
						|
                              Parent ? &ParentEntity : 0,
 | 
						|
                              getIndexContainerForDC(DC),
 | 
						|
                              Kind };
 | 
						|
  CB.indexEntityReference(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,
 | 
						|
                                        CXIdxClientContainer 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);
 | 
						|
}
 | 
						|
 | 
						|
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();
 | 
						|
}
 | 
						|
 | 
						|
CXIdxClientContainer
 | 
						|
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;
 | 
						|
}
 | 
						|
 | 
						|
CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
 | 
						|
  if (!File)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  FileMapTy::iterator FI = FileMap.find(File);
 | 
						|
  if (FI != FileMap.end())
 | 
						|
    return FI->second;
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
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,
 | 
						|
                                   CXIdxClientFile *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::getEntityInfo(const NamedDecl *D,
 | 
						|
                                     CXIdxEntityInfo &EntityInfo,
 | 
						|
                                     StrAdapter &SA) {
 | 
						|
  if (!D)
 | 
						|
    return;
 | 
						|
  D = getEntityDecl(D);
 | 
						|
  EntityInfo.kind = CXIdxEntity_Unexposed;
 | 
						|
 | 
						|
  if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
 | 
						|
    switch (TD->getTagKind()) {
 | 
						|
    case TTK_Struct:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Struct; break;
 | 
						|
    case TTK_Union:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Union; break;
 | 
						|
    case TTK_Class:
 | 
						|
      EntityInfo.kind = CXIdxEntity_CXXClass; break;
 | 
						|
    case TTK_Enum:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Enum; break;
 | 
						|
    }
 | 
						|
 | 
						|
  } else {
 | 
						|
    switch (D->getKind()) {
 | 
						|
    case Decl::Typedef:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Typedef; break;
 | 
						|
    case Decl::Function:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Function; break;
 | 
						|
    case Decl::Var:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Variable; break;
 | 
						|
    case Decl::Field:
 | 
						|
      EntityInfo.kind = CXIdxEntity_Field; break;
 | 
						|
    case Decl::EnumConstant:
 | 
						|
      EntityInfo.kind = CXIdxEntity_EnumConstant; break;
 | 
						|
    case Decl::ObjCInterface:
 | 
						|
      EntityInfo.kind = CXIdxEntity_ObjCClass; break;
 | 
						|
    case Decl::ObjCProtocol:
 | 
						|
      EntityInfo.kind = CXIdxEntity_ObjCProtocol; break;
 | 
						|
    case Decl::ObjCCategory:
 | 
						|
      EntityInfo.kind = CXIdxEntity_ObjCCategory; break;
 | 
						|
    case Decl::ObjCMethod:
 | 
						|
      if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
 | 
						|
        EntityInfo.kind = CXIdxEntity_ObjCInstanceMethod;
 | 
						|
      else
 | 
						|
        EntityInfo.kind = CXIdxEntity_ObjCClassMethod;
 | 
						|
      break;
 | 
						|
    case Decl::ObjCProperty:
 | 
						|
      EntityInfo.kind = CXIdxEntity_ObjCProperty; break;
 | 
						|
    case Decl::ObjCIvar:
 | 
						|
      EntityInfo.kind = CXIdxEntity_ObjCIvar; break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (IdentifierInfo *II = D->getIdentifier()) {
 | 
						|
    EntityInfo.name = SA.toCStr(II->getName());
 | 
						|
 | 
						|
  } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
 | 
						|
    EntityInfo.name = 0; // anonymous record/namespace.
 | 
						|
 | 
						|
  } 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();
 | 
						|
}
 |