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 ⤅
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