Home | History | Annotate | Download | only in libclang
      1 //===- CIndexHigh.cpp - Higher level API functions ------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "IndexingContext.h"
     11 #include "CXTranslationUnit.h"
     12 #include "CIndexDiagnostic.h"
     13 
     14 #include "clang/Frontend/ASTUnit.h"
     15 #include "clang/AST/DeclObjC.h"
     16 
     17 using namespace clang;
     18 using namespace cxindex;
     19 using namespace cxcursor;
     20 
     21 const char *IndexingContext::StrAdapter::toCStr(StringRef Str) {
     22   if (Str.empty())
     23     return "";
     24   if (Str.data()[Str.size()] == '\0')
     25     return Str.data();
     26   Scratch += Str;
     27   Scratch.push_back('\0');
     28   return Scratch.data() + (Scratch.size() - Str.size() - 1);
     29 }
     30 
     31 void IndexingContext::setASTContext(ASTContext &ctx) {
     32   Ctx = &ctx;
     33   static_cast<ASTUnit*>(CXTU->TUData)->setASTContext(&ctx);
     34 }
     35 
     36 void IndexingContext::ppIncludedFile(SourceLocation hashLoc,
     37                                      StringRef filename,
     38                                      const FileEntry *File,
     39                                      bool isImport, bool isAngled) {
     40   if (!CB.ppIncludedFile)
     41     return;
     42 
     43   StrAdapter SA(this);
     44   CXIdxIncludedFileInfo Info = { getIndexLoc(hashLoc),
     45                                  SA.toCStr(filename),
     46                                  getIndexFile(File),
     47                                  isImport, isAngled };
     48   CB.ppIncludedFile(ClientData, &Info);
     49 }
     50 
     51 void IndexingContext::ppMacroDefined(SourceLocation Loc, StringRef Name,
     52                                      SourceLocation DefBegin, unsigned Length,
     53                                      const void *OpaqueMacro) {
     54   if (!CB.ppMacroDefined)
     55     return;
     56 
     57   StrAdapter SA(this);
     58   CXIdxMacroInfo MacroInfo =  { getIndexLoc(Loc), SA.toCStr(Name) };
     59   CXIdxMacroDefinedInfo Info = { &MacroInfo,
     60                                  getIndexLoc(DefBegin), Length };
     61   CXIdxMacro idxMacro = CB.ppMacroDefined(ClientData, &Info);
     62   MacroMap[OpaqueMacro] = idxMacro;
     63 }
     64 
     65 void IndexingContext::ppMacroUndefined(SourceLocation Loc, StringRef Name,
     66                                        const void *OpaqueMacro) {
     67   if (!CB.ppMacroUndefined)
     68     return;
     69 
     70   StrAdapter SA(this);
     71   CXIdxMacroUndefinedInfo Info = { getIndexLoc(Loc),
     72                                    SA.toCStr(Name), 0 };
     73   CB.ppMacroUndefined(ClientData, &Info);
     74 }
     75 
     76 void IndexingContext::ppMacroExpanded(SourceLocation Loc, StringRef Name,
     77                                       const void *OpaqueMacro) {
     78   if (!CB.ppMacroExpanded)
     79     return;
     80 
     81   StrAdapter SA(this);
     82   CXIdxMacroExpandedInfo Info = { getIndexLoc(Loc),
     83                                    SA.toCStr(Name), 0 };
     84   CB.ppMacroExpanded(ClientData, &Info);
     85 }
     86 
     87 void IndexingContext::invokeStartedTranslationUnit() {
     88   CXIdxContainer idxCont = 0;
     89   if (CB.startedTranslationUnit)
     90     idxCont = CB.startedTranslationUnit(ClientData, 0);
     91   addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
     92 }
     93 
     94 void IndexingContext::invokeFinishedTranslationUnit() {
     95   invokeEndedContainer(Ctx->getTranslationUnitDecl());
     96 }
     97 
     98 void IndexingContext::handleDiagnostic(const StoredDiagnostic &StoredDiag) {
     99   if (!CB.diagnostic)
    100     return;
    101 
    102   CXStoredDiagnostic CXDiag(StoredDiag, Ctx->getLangOptions());
    103   CB.diagnostic(ClientData, &CXDiag, 0);
    104 }
    105 
    106 void IndexingContext::handleFunction(const FunctionDecl *D) {
    107   StrAdapter SA(this);
    108 
    109   if (D->isFirstDeclaration()) {
    110     CXIdxEntity idxEntity = 0;
    111     if (CB.indexFunction) {
    112       CXIdxEntityInfo EntityInfo;
    113       CXIdxIndexedDeclInfo DeclInfo;
    114       CXIdxIndexedEntityInfo IdxEntityInfo;
    115       getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    116       CXIdxFunctionInfo Info = { &IdxEntityInfo,
    117                                  D->isThisDeclarationADefinition() };
    118 
    119       idxEntity = CB.indexFunction(ClientData, &Info);
    120     }
    121 
    122     addEntityInMap(D, idxEntity);
    123 
    124   } else {
    125     if (CB.indexFunctionRedeclaration) {
    126       CXIdxIndexedDeclInfo DeclInfo;
    127       CXIdxIndexedRedeclInfo RedeclInfo;
    128       getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
    129       CXIdxFunctionRedeclInfo Info = { &RedeclInfo,
    130                                        D->isThisDeclarationADefinition() };
    131 
    132       CB.indexFunctionRedeclaration(ClientData, &Info);
    133     }
    134   }
    135 }
    136 
    137 void IndexingContext::handleVar(const VarDecl *D) {
    138   StrAdapter SA(this);
    139 
    140   if (D->isFirstDeclaration()) {
    141     CXIdxEntity idxEntity = 0;
    142     if (CB.indexVariable) {
    143       CXIdxEntityInfo EntityInfo;
    144       CXIdxIndexedDeclInfo DeclInfo;
    145       CXIdxIndexedEntityInfo IdxEntityInfo;
    146       getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    147       CXIdxVariableInfo Info = { &IdxEntityInfo,
    148                                  D->isThisDeclarationADefinition() };
    149 
    150       idxEntity = CB.indexVariable(ClientData, &Info);
    151     }
    152 
    153     addEntityInMap(D, idxEntity);
    154 
    155   } else {
    156     if (CB.indexVariableRedeclaration) {
    157       CXIdxIndexedDeclInfo DeclInfo;
    158       CXIdxIndexedRedeclInfo RedeclInfo;
    159       getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
    160       CXIdxVariableRedeclInfo Info = { &RedeclInfo,
    161                                        D->isThisDeclarationADefinition() };
    162 
    163       CB.indexVariableRedeclaration(ClientData, &Info);
    164     }
    165   }
    166 }
    167 
    168 void IndexingContext::handleField(const FieldDecl *D) {
    169   StrAdapter SA(this);
    170 
    171   CXIdxEntity idxEntity = 0;
    172   if (CB.indexTypedef) {
    173     CXIdxEntityInfo EntityInfo;
    174     CXIdxIndexedDeclInfo DeclInfo;
    175     CXIdxIndexedEntityInfo IdxEntityInfo;
    176     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    177     CXIdxFieldInfo Info = { &IdxEntityInfo };
    178 
    179     idxEntity = CB.indexField(ClientData, &Info);
    180   }
    181 
    182   addEntityInMap(D, idxEntity);
    183 }
    184 
    185 void IndexingContext::handleEnumerator(const EnumConstantDecl *D) {
    186   StrAdapter SA(this);
    187 
    188   CXIdxEntity idxEntity = 0;
    189   if (CB.indexTypedef) {
    190     CXIdxEntityInfo EntityInfo;
    191     CXIdxIndexedDeclInfo DeclInfo;
    192     CXIdxIndexedEntityInfo IdxEntityInfo;
    193     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    194     CXIdxEnumeratorInfo Info = { &IdxEntityInfo };
    195 
    196     idxEntity = CB.indexEnumerator(ClientData, &Info);
    197   }
    198 
    199   addEntityInMap(D, idxEntity);
    200 }
    201 
    202 void IndexingContext::handleTagDecl(const TagDecl *D) {
    203   StrAdapter SA(this);
    204 
    205   if (D->isFirstDeclaration()) {
    206     CXIdxEntity idxEntity = 0;
    207     if (CB.indexTagType) {
    208       CXIdxEntityInfo EntityInfo;
    209       CXIdxIndexedDeclInfo DeclInfo;
    210       CXIdxIndexedEntityInfo IdxEntityInfo;
    211       getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    212       CXIdxTagTypeInfo Info = { &IdxEntityInfo,
    213                                  D->isThisDeclarationADefinition(),
    214                                  D->getIdentifier() == 0};
    215 
    216       idxEntity = CB.indexTagType(ClientData, &Info);
    217     }
    218 
    219     addEntityInMap(D, idxEntity);
    220 
    221   } else {
    222     if (CB.indexTagTypeRedeclaration) {
    223       CXIdxIndexedDeclInfo DeclInfo;
    224       CXIdxIndexedRedeclInfo RedeclInfo;
    225       getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
    226       CXIdxTagTypeRedeclInfo Info = { &RedeclInfo,
    227                                       D->isThisDeclarationADefinition() };
    228 
    229       CB.indexTagTypeRedeclaration(ClientData, &Info);
    230     }
    231   }
    232 }
    233 
    234 void IndexingContext::handleTypedef(const TypedefDecl *D) {
    235   StrAdapter SA(this);
    236 
    237   CXIdxEntity idxEntity = 0;
    238   if (CB.indexTypedef) {
    239     CXIdxEntityInfo EntityInfo;
    240     CXIdxIndexedDeclInfo DeclInfo;
    241     CXIdxIndexedEntityInfo IdxEntityInfo;
    242     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    243     CXIdxTypedefInfo Info = { &IdxEntityInfo };
    244 
    245     idxEntity = CB.indexTypedef(ClientData, &Info);
    246   }
    247 
    248   addEntityInMap(D, idxEntity);
    249 }
    250 
    251 void IndexingContext::handleObjCInterface(const ObjCInterfaceDecl *D) {
    252   StrAdapter SA(this);
    253 
    254   CXIdxEntity idxEntity = 0;
    255   if (CB.indexObjCClass) {
    256     CXIdxEntityInfo EntityInfo;
    257     CXIdxIndexedDeclInfo DeclInfo;
    258     CXIdxIndexedEntityInfo IdxEntityInfo;
    259     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    260     CXIdxObjCClassInfo Info = { &IdxEntityInfo,
    261                                 D->isForwardDecl() };
    262 
    263     idxEntity = CB.indexObjCClass(ClientData, &Info);
    264   }
    265 
    266   addEntityInMap(D, idxEntity);
    267 }
    268 
    269 void IndexingContext::defineObjCInterface(const ObjCInterfaceDecl *D) {
    270   if (!CB.defineObjCClass)
    271     return;
    272 
    273   CXIdxObjCBaseClassInfo BaseClass = { getIndexEntity(D->getSuperClass()),
    274                                        getIndexLoc(D->getSuperClassLoc()) };
    275   if (D->getSuperClass()) {
    276     BaseClass.objcClass = getIndexEntity(D->getSuperClass());
    277     BaseClass.loc = getIndexLoc(D->getSuperClassLoc());
    278   }
    279 
    280   SmallVector<CXIdxObjCProtocolRefInfo, 4> ProtInfos;
    281   ObjCInterfaceDecl::protocol_loc_iterator LI = D->protocol_loc_begin();
    282   for (ObjCInterfaceDecl::protocol_iterator
    283          I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I, ++LI) {
    284     SourceLocation Loc = *LI;
    285     ObjCProtocolDecl *PD = *I;
    286     CXIdxObjCProtocolRefInfo ProtInfo = { getIndexEntity(PD),
    287                                           getIndexLoc(Loc) };
    288     ProtInfos.push_back(ProtInfo);
    289   }
    290 
    291   SmallVector<CXIdxObjCProtocolRefInfo *, 4> Prots;
    292   for (unsigned i = 0, e = Prots.size(); i != e; ++i)
    293     Prots.push_back(&ProtInfos[i]);
    294 
    295   CXIdxObjCClassDefineInfo Info = { getCursor(D),
    296                                     getIndexEntity(D),
    297                                     getIndexContainerForDC(D),
    298                                     D->getSuperClass() ? &BaseClass : 0,
    299                                     Prots.data(),
    300                                     static_cast<unsigned>(Prots.size()) };
    301   CB.defineObjCClass(ClientData, &Info);
    302 }
    303 
    304 void IndexingContext::handleObjCProtocol(const ObjCProtocolDecl *D) {
    305   StrAdapter SA(this);
    306 
    307   CXIdxEntity idxEntity = 0;
    308   if (CB.indexObjCProtocol) {
    309     CXIdxEntityInfo EntityInfo;
    310     CXIdxIndexedDeclInfo DeclInfo;
    311     CXIdxIndexedEntityInfo IdxEntityInfo;
    312     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    313     CXIdxObjCProtocolInfo Info = { &IdxEntityInfo,
    314                                 D->isForwardDecl() };
    315 
    316     idxEntity = CB.indexObjCProtocol(ClientData, &Info);
    317   }
    318 
    319   addEntityInMap(D, idxEntity);
    320 }
    321 
    322 void IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
    323   StrAdapter SA(this);
    324 
    325   CXIdxEntity idxEntity = 0;
    326   if (CB.indexObjCCategory) {
    327     CXIdxEntityInfo EntityInfo;
    328     CXIdxIndexedDeclInfo DeclInfo;
    329     CXIdxIndexedEntityInfo IdxEntityInfo;
    330     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    331     CXIdxObjCCategoryInfo Info = { &IdxEntityInfo,
    332                                    getIndexEntity(D->getClassInterface()) };
    333 
    334     idxEntity = CB.indexObjCCategory(ClientData, &Info);
    335   }
    336 
    337   addEntityInMap(D, idxEntity);
    338 }
    339 
    340 void IndexingContext::handleObjCMethod(const ObjCMethodDecl *D) {
    341   StrAdapter SA(this);
    342 
    343   if (D->isCanonicalDecl()) {
    344     CXIdxEntity idxEntity = 0;
    345     if (CB.indexObjCMethod) {
    346       CXIdxEntityInfo EntityInfo;
    347       CXIdxIndexedDeclInfo DeclInfo;
    348       CXIdxIndexedEntityInfo IdxEntityInfo;
    349       getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    350       CXIdxObjCMethodInfo Info = { &IdxEntityInfo,
    351                                    D->isThisDeclarationADefinition() };
    352 
    353       idxEntity = CB.indexObjCMethod(ClientData, &Info);
    354     }
    355 
    356     addEntityInMap(D, idxEntity);
    357 
    358   } else {
    359     if (CB.indexObjCMethodRedeclaration) {
    360       CXIdxIndexedRedeclInfo RedeclInfo;
    361       CXIdxIndexedDeclInfo DeclInfo;
    362       getIndexedRedeclInfo(D, RedeclInfo, DeclInfo);
    363       CXIdxObjCMethodRedeclInfo Info = { &RedeclInfo,
    364                                          D->isThisDeclarationADefinition() };
    365 
    366       CB.indexObjCMethodRedeclaration(ClientData, &Info);
    367     }
    368   }
    369 }
    370 
    371 void IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
    372   StrAdapter SA(this);
    373 
    374   CXIdxEntity idxEntity = 0;
    375   if (CB.indexObjCProperty) {
    376     CXIdxEntityInfo EntityInfo;
    377     CXIdxIndexedDeclInfo DeclInfo;
    378     CXIdxIndexedEntityInfo IdxEntityInfo;
    379     getIndexedEntityInfo(D, IdxEntityInfo, EntityInfo, DeclInfo, SA);
    380     CXIdxObjCPropertyInfo Info = { &IdxEntityInfo };
    381 
    382     idxEntity = CB.indexObjCProperty(ClientData, &Info);
    383   }
    384 
    385   addEntityInMap(D, idxEntity);
    386 }
    387 
    388 void IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
    389                                       const NamedDecl *Parent,
    390                                       const DeclContext *DC,
    391                                       const Expr *E,
    392                                       CXIdxEntityRefKind Kind) {
    393   if (Loc.isInvalid())
    394     return;
    395   if (!CB.indexEntityReference)
    396     return;
    397   if (isNotFromSourceFile(D->getLocation()))
    398     return;
    399 
    400   CXIdxEntityRefInfo Info = { E ? MakeCXCursor((Stmt*)E,
    401                                                (Decl*)cast<Decl>(DC), CXTU)
    402                                 : getRefCursor(D, Loc),
    403                               getIndexLoc(Loc),
    404                               getIndexEntity(D),
    405                               getIndexEntity(Parent),
    406                               getIndexContainerForDC(DC),
    407                               Kind };
    408   CB.indexEntityReference(ClientData, &Info);
    409 }
    410 
    411 void IndexingContext::invokeStartedStatementBody(const NamedDecl *D,
    412                                                  const DeclContext *DC) {
    413   const Stmt *Body = cast<Decl>(DC)->getBody();
    414   assert(Body);
    415 
    416   CXIdxContainer idxCont = 0;
    417   if (CB.startedStatementBody) {
    418     CXIdxContainerInfo ContainerInfo;
    419     getContainerInfo(D, ContainerInfo);
    420     CXIdxStmtBodyInfo Info = { &ContainerInfo,
    421                                getIndexLoc(Body->getLocStart()) };
    422 
    423     idxCont = CB.startedStatementBody(ClientData, &Info);
    424   }
    425   addContainerInMap(DC, idxCont);
    426 }
    427 
    428 void IndexingContext::invokeStartedTagTypeDefinition(const TagDecl *D) {
    429   CXIdxContainer idxCont = 0;
    430   if (CB.startedTagTypeDefinition) {
    431     CXIdxContainerInfo ContainerInfo;
    432     getContainerInfo(D, ContainerInfo);
    433     CXIdxTagTypeDefinitionInfo Info = { &ContainerInfo };
    434 
    435     idxCont = CB.startedTagTypeDefinition(ClientData, &Info);
    436   }
    437   addContainerInMap(D, idxCont);
    438 }
    439 
    440 void IndexingContext::invokeStartedObjCContainer(const ObjCContainerDecl *D) {
    441   CXIdxContainer idxCont = 0;
    442   if (CB.startedObjCContainer) {
    443     CXIdxContainerInfo ContainerInfo;
    444     getContainerInfo(D, ContainerInfo);
    445     CXIdxObjCContainerInfo Info = { &ContainerInfo };
    446 
    447     idxCont = CB.startedObjCContainer(ClientData, &Info);
    448   }
    449   addContainerInMap(D, idxCont);
    450 }
    451 
    452 void IndexingContext::invokeEndedContainer(const DeclContext *DC) {
    453   if (CB.endedContainer) {
    454     CXIdxEndContainerInfo Info = { getIndexContainerForDC(DC),
    455                                    getIndexLoc(cast<Decl>(DC)->getLocEnd()) };
    456     CB.endedContainer(ClientData, &Info);
    457   }
    458 }
    459 
    460 bool IndexingContext::isNotFromSourceFile(SourceLocation Loc) const {
    461   if (Loc.isInvalid())
    462     return true;
    463   SourceManager &SM = Ctx->getSourceManager();
    464   SourceLocation FileLoc = SM.getFileLoc(Loc);
    465   FileID FID = SM.getFileID(FileLoc);
    466   return SM.getFileEntryForID(FID) == 0;
    467 }
    468 
    469 void IndexingContext::addContainerInMap(const DeclContext *DC,
    470                                         CXIdxContainer container) {
    471   assert(getScopedContext(DC) == DC);
    472   ContainerMapTy::iterator I = ContainerMap.find(DC);
    473   if (I == ContainerMap.end()) {
    474     if (container)
    475       ContainerMap[DC] = container;
    476     return;
    477   }
    478   // Allow changing the container of a previously seen DeclContext so we
    479   // can handle invalid user code, like a function re-definition.
    480   if (container)
    481     I->second = container;
    482   else
    483     ContainerMap.erase(I);
    484 }
    485 
    486 void IndexingContext::addEntityInMap(const NamedDecl *D, CXIdxEntity entity) {
    487   assert(getEntityDecl(D) == D &&
    488          "Tried to add a non-entity (canonical) decl");
    489   assert(EntityMap.find(D) == EntityMap.end());
    490   if (entity || D->isFromASTFile())
    491     EntityMap[D] = entity;
    492 }
    493 
    494 CXIdxEntity IndexingContext::getIndexEntity(const NamedDecl *D) {
    495   if (!D)
    496     return 0;
    497   D = getEntityDecl(D);
    498   EntityMapTy::const_iterator I = EntityMap.find(D);
    499   if (I != EntityMap.end())
    500     return I->second;
    501 
    502   if (!D->isFromASTFile()) {
    503     //assert(0 && "Entity not in map");
    504     return 0;
    505   }
    506 
    507   StrAdapter SA(this);
    508 
    509   CXIdxEntity idxEntity = 0;
    510   if (CB.importedEntity) {
    511     CXIdxEntityInfo EntityInfo;
    512     getEntityInfo(D, EntityInfo, SA);
    513     CXIdxImportedEntityInfo Info = { &EntityInfo,
    514                                      getCursor(D),
    515                                      getIndexLoc(D->getLocation()),
    516                                      /*CXIdxASTFile*/0 };
    517     idxEntity = CB.importedEntity(ClientData, &Info);
    518   }
    519   addEntityInMap(D, idxEntity);
    520   return idxEntity;
    521 }
    522 
    523 const NamedDecl *IndexingContext::getEntityDecl(const NamedDecl *D) const {
    524   assert(D);
    525   D = cast<NamedDecl>(D->getCanonicalDecl());
    526 
    527   if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(D)) {
    528     if (Cat->IsClassExtension())
    529       return getEntityDecl(Cat->getClassInterface());
    530 
    531   } else if (const ObjCImplementationDecl *
    532                ImplD = dyn_cast<ObjCImplementationDecl>(D)) {
    533     return getEntityDecl(ImplD->getClassInterface());
    534 
    535   } else if (const ObjCCategoryImplDecl *
    536                CatImplD = dyn_cast<ObjCCategoryImplDecl>(D)) {
    537     return getEntityDecl(CatImplD->getCategoryDecl());
    538   }
    539 
    540   return D;
    541 }
    542 
    543 const DeclContext *
    544 IndexingContext::getScopedContext(const DeclContext *DC) const {
    545   // Local contexts are ignored for indexing.
    546   const DeclContext *FuncCtx = cast<Decl>(DC)->getParentFunctionOrMethod();
    547   if (FuncCtx)
    548     return FuncCtx;
    549 
    550   // We consider enums always scoped for indexing.
    551   if (isa<TagDecl>(DC))
    552     return DC;
    553 
    554   if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
    555     if (NS->isAnonymousNamespace())
    556       return getScopedContext(NS->getParent());
    557     return NS;
    558   }
    559 
    560   return DC->getRedeclContext();
    561 }
    562 
    563 CXIdxContainer
    564 IndexingContext::getIndexContainerForDC(const DeclContext *DC) const {
    565   DC = getScopedContext(DC);
    566   ContainerMapTy::const_iterator I = ContainerMap.find(DC);
    567 //  assert(I != ContainerMap.end() &&
    568 //         "Failed to include a scoped context in the container map");
    569   return I->second;
    570 }
    571 
    572 CXIdxFile IndexingContext::getIndexFile(const FileEntry *File) {
    573   if (!File)
    574     return 0;
    575   if (!CB.recordFile)
    576     return 0;
    577 
    578   FileMapTy::iterator FI = FileMap.find(File);
    579   if (FI != FileMap.end())
    580     return FI->second;
    581 
    582   CXIdxFile idxFile = CB.recordFile(ClientData, (CXFile)File, 0);
    583   FileMap[File] = idxFile;
    584   return idxFile;
    585 }
    586 
    587 CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
    588   CXIdxLoc idxLoc =  { {0, 0}, 0 };
    589   if (Loc.isInvalid())
    590     return idxLoc;
    591 
    592   idxLoc.ptr_data[0] = (void*)this;
    593   idxLoc.int_data = Loc.getRawEncoding();
    594   return idxLoc;
    595 }
    596 
    597 void IndexingContext::translateLoc(SourceLocation Loc,
    598                                    CXIdxFile *indexFile, CXFile *file,
    599                                    unsigned *line, unsigned *column,
    600                                    unsigned *offset) {
    601   if (Loc.isInvalid())
    602     return;
    603 
    604   SourceManager &SM = Ctx->getSourceManager();
    605   Loc = SM.getFileLoc(Loc);
    606 
    607   std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
    608   FileID FID = LocInfo.first;
    609   unsigned FileOffset = LocInfo.second;
    610 
    611   if (FID.isInvalid())
    612     return;
    613 
    614   const FileEntry *FE = SM.getFileEntryForID(FID);
    615   if (indexFile)
    616     *indexFile = getIndexFile(FE);
    617   if (file)
    618     *file = (void *)FE;
    619   if (line)
    620     *line = SM.getLineNumber(FID, FileOffset);
    621   if (column)
    622     *column = SM.getColumnNumber(FID, FileOffset);
    623   if (offset)
    624     *offset = FileOffset;
    625 }
    626 
    627 void IndexingContext::getIndexedEntityInfo(const NamedDecl *D,
    628                           CXIdxIndexedEntityInfo &IdxEntityInfo,
    629                           CXIdxEntityInfo &EntityInfo,
    630                           CXIdxIndexedDeclInfo &IdxDeclInfo,
    631                           StrAdapter &SA) {
    632   getEntityInfo(D, EntityInfo, SA);
    633   getIndexedDeclInfo(D, IdxDeclInfo);
    634   IdxEntityInfo.entityInfo = &EntityInfo;
    635   IdxEntityInfo.declInfo = &IdxDeclInfo;
    636 }
    637 
    638 void IndexingContext::getIndexedDeclInfo(const NamedDecl *D,
    639                                          CXIdxIndexedDeclInfo &IdxDeclInfo) {
    640   IdxDeclInfo.cursor = getCursor(D);
    641   IdxDeclInfo.loc = getIndexLoc(D->getLocation());
    642   IdxDeclInfo.container = getIndexContainer(D);
    643 }
    644 
    645 void IndexingContext::getIndexedRedeclInfo(const NamedDecl *D,
    646                           CXIdxIndexedRedeclInfo &RedeclInfo,
    647                           CXIdxIndexedDeclInfo &IdxDeclInfo) {
    648   getIndexedDeclInfo(D, IdxDeclInfo);
    649   RedeclInfo.declInfo = &IdxDeclInfo;
    650   RedeclInfo.entity = getIndexEntity(D);
    651 }
    652 
    653 void IndexingContext::getContainerInfo(const NamedDecl *D,
    654                           CXIdxContainerInfo &ContainerInfo) {
    655   ContainerInfo.cursor = getCursor(D);
    656   ContainerInfo.loc = getIndexLoc(D->getLocation());
    657   ContainerInfo.entity = getIndexEntity(D);
    658 }
    659 
    660 void IndexingContext::getEntityInfo(const NamedDecl *D,
    661                           CXIdxEntityInfo &EntityInfo,
    662                           StrAdapter &SA) {
    663   if (IdentifierInfo *II = D->getIdentifier()) {
    664     EntityInfo.name = SA.toCStr(II->getName());
    665 
    666   } else if (isa<RecordDecl>(D) || isa<NamespaceDecl>(D)) {
    667     EntityInfo.name = 0;
    668 
    669   } else {
    670     unsigned Begin = SA.getCurSize();
    671     {
    672       llvm::raw_svector_ostream OS(SA.getBuffer());
    673       D->printName(OS);
    674     }
    675     EntityInfo.name = SA.getCStr(Begin);
    676   }
    677 
    678   unsigned Begin = SA.getCurSize();
    679   bool Ignore = getDeclCursorUSR(D, SA.getBuffer());
    680   if (Ignore) {
    681     EntityInfo.USR = "";
    682   } else {
    683     EntityInfo.USR = SA.getCStr(Begin);
    684   }
    685 }
    686 
    687 CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) {
    688   if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
    689     return MakeCursorTypeRef(TD, Loc, CXTU);
    690   if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
    691     return MakeCursorObjCClassRef(ID, Loc, CXTU);
    692   if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
    693     return MakeCursorObjCProtocolRef(PD, Loc, CXTU);
    694 
    695   //assert(0 && "not yet");
    696   return clang_getNullCursor();
    697 }
    698