]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/lib/Index/Indexer.cpp
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / lib / Index / Indexer.cpp
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 }