clang API Documentation
00001 //===--- Indexer.cpp - IndexProvider implementation -------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // IndexProvider implementation. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Index/Indexer.h" 00015 #include "clang/Index/Program.h" 00016 #include "clang/Index/Handlers.h" 00017 #include "clang/Index/TranslationUnit.h" 00018 #include "ASTVisitor.h" 00019 #include "clang/AST/DeclBase.h" 00020 using namespace clang; 00021 using namespace idx; 00022 00023 namespace { 00024 00025 class EntityIndexer : public EntityHandler { 00026 TranslationUnit *TU; 00027 Indexer::MapTy ⤅ 00028 Indexer::DefMapTy &DefMap; 00029 00030 public: 00031 EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map, 00032 Indexer::DefMapTy &defmap) 00033 : TU(tu), Map(map), DefMap(defmap) { } 00034 00035 virtual void Handle(Entity Ent) { 00036 if (Ent.isInternalToTU()) 00037 return; 00038 Map[Ent].insert(TU); 00039 00040 Decl *D = Ent.getDecl(TU->getASTContext()); 00041 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 00042 if (FD->doesThisDeclarationHaveABody()) 00043 DefMap[Ent] = std::make_pair(FD, TU); 00044 } 00045 }; 00046 00047 class SelectorIndexer : public ASTVisitor<SelectorIndexer> { 00048 Program &Prog; 00049 TranslationUnit *TU; 00050 Indexer::SelMapTy ⤅ 00051 00052 public: 00053 SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map) 00054 : Prog(prog), TU(tu), Map(map) { } 00055 00056 void VisitObjCMethodDecl(ObjCMethodDecl *D) { 00057 Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU); 00058 Base::VisitObjCMethodDecl(D); 00059 } 00060 00061 void VisitObjCMessageExpr(ObjCMessageExpr *Node) { 00062 Map[GlobalSelector::get(Node->getSelector(), Prog)].insert(TU); 00063 Base::VisitObjCMessageExpr(Node); 00064 } 00065 }; 00066 00067 } // anonymous namespace 00068 00069 void Indexer::IndexAST(TranslationUnit *TU) { 00070 assert(TU && "Passed null TranslationUnit"); 00071 ASTContext &Ctx = TU->getASTContext(); 00072 CtxTUMap[&Ctx] = TU; 00073 EntityIndexer Idx(TU, Map, DefMap); 00074 Prog.FindEntities(Ctx, Idx); 00075 00076 SelectorIndexer SelIdx(Prog, TU, SelMap); 00077 SelIdx.Visit(Ctx.getTranslationUnitDecl()); 00078 } 00079 00080 void Indexer::GetTranslationUnitsFor(Entity Ent, 00081 TranslationUnitHandler &Handler) { 00082 assert(Ent.isValid() && "Expected valid Entity"); 00083 00084 if (Ent.isInternalToTU()) { 00085 Decl *D = Ent.getInternalDecl(); 00086 CtxTUMapTy::iterator I = CtxTUMap.find(&D->getASTContext()); 00087 if (I != CtxTUMap.end()) 00088 Handler.Handle(I->second); 00089 return; 00090 } 00091 00092 MapTy::iterator I = Map.find(Ent); 00093 if (I == Map.end()) 00094 return; 00095 00096 TUSetTy &Set = I->second; 00097 for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I) 00098 Handler.Handle(*I); 00099 } 00100 00101 void Indexer::GetTranslationUnitsFor(GlobalSelector Sel, 00102 TranslationUnitHandler &Handler) { 00103 assert(Sel.isValid() && "Expected valid GlobalSelector"); 00104 00105 SelMapTy::iterator I = SelMap.find(Sel); 00106 if (I == SelMap.end()) 00107 return; 00108 00109 TUSetTy &Set = I->second; 00110 for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I) 00111 Handler.Handle(*I); 00112 } 00113 00114 std::pair<FunctionDecl *, TranslationUnit *> 00115 Indexer::getDefinitionFor(Entity Ent) { 00116 DefMapTy::iterator I = DefMap.find(Ent); 00117 if (I == DefMap.end()) 00118 return std::make_pair((FunctionDecl *)0, (TranslationUnit *)0); 00119 else 00120 return I->second; 00121 }