blob: 7f21c4f3035a07086b48a3364f8f0ab333a35299 [file] [log] [blame]
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +00001//===--- 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"
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000016#include "clang/Index/Handlers.h"
17#include "clang/Index/TranslationUnit.h"
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +000018#include "ASTVisitor.h"
Argyrios Kyrtzidis52f1d472009-07-29 23:39:52 +000019#include "clang/AST/DeclBase.h"
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000020using namespace clang;
21using namespace idx;
22
23namespace {
24
25class EntityIndexer : public EntityHandler {
26 TranslationUnit *TU;
27 Indexer::MapTy ⤅
Zhongxing Xudc01a152010-07-06 05:55:13 +000028 Indexer::DefMapTy &DefMap;
Mike Stump1eb44332009-09-09 15:08:12 +000029
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000030public:
Zhongxing Xudc01a152010-07-06 05:55:13 +000031 EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map,
32 Indexer::DefMapTy &defmap)
33 : TU(tu), Map(map), DefMap(defmap) { }
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000034
Argyrios Kyrtzidis77b4a792009-07-29 23:38:35 +000035 virtual void Handle(Entity Ent) {
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000036 if (Ent.isInternalToTU())
37 return;
38 Map[Ent].insert(TU);
Zhongxing Xudc01a152010-07-06 05:55:13 +000039
40 Decl *D = Ent.getDecl(TU->getASTContext());
41 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
42 if (FD->isThisDeclarationADefinition())
43 DefMap[Ent] = std::make_pair(FD, TU);
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000044 }
45};
46
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +000047class SelectorIndexer : public ASTVisitor<SelectorIndexer> {
48 Program &Prog;
49 TranslationUnit *TU;
50 Indexer::SelMapTy &Map;
51
52public:
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
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000067} // anonymous namespace
68
69void Indexer::IndexAST(TranslationUnit *TU) {
Argyrios Kyrtzidisdaf253d2009-07-29 23:38:51 +000070 assert(TU && "Passed null TranslationUnit");
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +000071 ASTContext &Ctx = TU->getASTContext();
72 CtxTUMap[&Ctx] = TU;
Zhongxing Xudc01a152010-07-06 05:55:13 +000073 EntityIndexer Idx(TU, Map, DefMap);
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +000074 Prog.FindEntities(Ctx, Idx);
Mike Stump1eb44332009-09-09 15:08:12 +000075
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +000076 SelectorIndexer SelIdx(Prog, TU, SelMap);
77 SelIdx.Visit(Ctx.getTranslationUnitDecl());
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000078}
79
80void Indexer::GetTranslationUnitsFor(Entity Ent,
Argyrios Kyrtzidis16d8bcf2009-07-29 23:38:45 +000081 TranslationUnitHandler &Handler) {
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000082 assert(Ent.isValid() && "Expected valid Entity");
Argyrios Kyrtzidis52f1d472009-07-29 23:39:52 +000083
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 }
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000091
92 MapTy::iterator I = Map.find(Ent);
93 if (I == Map.end())
94 return;
Mike Stump1eb44332009-09-09 15:08:12 +000095
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000096 TUSetTy &Set = I->second;
97 for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
Argyrios Kyrtzidis16d8bcf2009-07-29 23:38:45 +000098 Handler.Handle(*I);
Argyrios Kyrtzidisb17dc462009-07-29 23:38:21 +000099}
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +0000100
101void 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;
Mike Stump1eb44332009-09-09 15:08:12 +0000108
Argyrios Kyrtzidisd88284b2009-07-29 23:41:18 +0000109 TUSetTy &Set = I->second;
110 for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
111 Handler.Handle(*I);
112}
Zhongxing Xudc01a152010-07-06 05:55:13 +0000113
114std::pair<FunctionDecl *, TranslationUnit *>
115Indexer::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}