• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
EntityIndexer(TranslationUnit * tu,Indexer::MapTy & map,Indexer::DefMapTy & defmap)31   EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map,
32                 Indexer::DefMapTy &defmap)
33     : TU(tu), Map(map), DefMap(defmap) { }
34 
Handle(Entity Ent)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:
SelectorIndexer(Program & prog,TranslationUnit * tu,Indexer::SelMapTy & map)53   SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map)
54     : Prog(prog), TU(tu), Map(map) { }
55 
VisitObjCMethodDecl(ObjCMethodDecl * D)56   void VisitObjCMethodDecl(ObjCMethodDecl *D) {
57     Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU);
58     Base::VisitObjCMethodDecl(D);
59   }
60 
VisitObjCMessageExpr(ObjCMessageExpr * Node)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 
IndexAST(TranslationUnit * TU)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 
GetTranslationUnitsFor(Entity Ent,TranslationUnitHandler & Handler)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 
GetTranslationUnitsFor(GlobalSelector Sel,TranslationUnitHandler & Handler)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 *>
getDefinitionFor(Entity Ent)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