Home | History | Annotate | Download | only in Index
      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 &Map;
     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