1 //===--- Indexer.cpp - IndexProvider implementation -------------*- C++ -*-===// 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 // IndexProvider implementation. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Index/Indexer.h" 15 #include "clang/Index/Program.h" 16 #include "clang/Index/Handlers.h" 17 #include "clang/Index/TranslationUnit.h" 18 #include "ASTVisitor.h" 19 #include "clang/AST/DeclBase.h" 20 using namespace clang; 21 using namespace idx; 22 23 namespace { 24 25 class EntityIndexer : public EntityHandler { 26 TranslationUnit *TU; 27 Indexer::MapTy ⤅ 28 Indexer::DefMapTy &DefMap; 29 30 public: 31 EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map, 32 Indexer::DefMapTy &defmap) 33 : TU(tu), Map(map), DefMap(defmap) { } 34 35 virtual void Handle(Entity Ent) { 36 if (Ent.isInternalToTU()) 37 return; 38 Map[Ent].insert(TU); 39 40 Decl *D = Ent.getDecl(TU->getASTContext()); 41 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 42 if (FD->doesThisDeclarationHaveABody()) 43 DefMap[Ent] = std::make_pair(FD, TU); 44 } 45 }; 46 47 class SelectorIndexer : public ASTVisitor<SelectorIndexer> { 48 Program &Prog; 49 TranslationUnit *TU; 50 Indexer::SelMapTy ⤅ 51 52 public: 53 SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map) 54 : Prog(prog), TU(tu), Map(map) { } 55 56 void VisitObjCMethodDecl(ObjCMethodDecl *D) { 57 Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU); 58 Base::VisitObjCMethodDecl(D); 59 } 60 61 void VisitObjCMessageExpr(ObjCMessageExpr *Node) { 62 Map[GlobalSelector::get(Node->getSelector(), Prog)].insert(TU); 63 Base::VisitObjCMessageExpr(Node); 64 } 65 }; 66 67 } // anonymous namespace 68 69 void Indexer::IndexAST(TranslationUnit *TU) { 70 assert(TU && "Passed null TranslationUnit"); 71 ASTContext &Ctx = TU->getASTContext(); 72 CtxTUMap[&Ctx] = TU; 73 EntityIndexer Idx(TU, Map, DefMap); 74 Prog.FindEntities(Ctx, Idx); 75 76 SelectorIndexer SelIdx(Prog, TU, SelMap); 77 SelIdx.Visit(Ctx.getTranslationUnitDecl()); 78 } 79 80 void Indexer::GetTranslationUnitsFor(Entity Ent, 81 TranslationUnitHandler &Handler) { 82 assert(Ent.isValid() && "Expected valid Entity"); 83 84 if (Ent.isInternalToTU()) { 85 Decl *D = Ent.getInternalDecl(); 86 CtxTUMapTy::iterator I = CtxTUMap.find(&D->getASTContext()); 87 if (I != CtxTUMap.end()) 88 Handler.Handle(I->second); 89 return; 90 } 91 92 MapTy::iterator I = Map.find(Ent); 93 if (I == Map.end()) 94 return; 95 96 TUSetTy &Set = I->second; 97 for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I) 98 Handler.Handle(*I); 99 } 100 101 void Indexer::GetTranslationUnitsFor(GlobalSelector Sel, 102 TranslationUnitHandler &Handler) { 103 assert(Sel.isValid() && "Expected valid GlobalSelector"); 104 105 SelMapTy::iterator I = SelMap.find(Sel); 106 if (I == SelMap.end()) 107 return; 108 109 TUSetTy &Set = I->second; 110 for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I) 111 Handler.Handle(*I); 112 } 113 114 std::pair<FunctionDecl *, TranslationUnit *> 115 Indexer::getDefinitionFor(Entity Ent) { 116 DefMapTy::iterator I = DefMap.find(Ent); 117 if (I == DefMap.end()) 118 return std::make_pair((FunctionDecl *)0, (TranslationUnit *)0); 119 else 120 return I->second; 121 } 122