blob: 57bfc5b4fbfd2afa6386a668d1f4039f283786eb [file] [log] [blame]
//===--- Indexer.cpp - IndexProvider implementation -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// IndexProvider implementation.
//
//===----------------------------------------------------------------------===//
#include "clang/Index/Indexer.h"
#include "clang/Index/Program.h"
#include "clang/Index/Handlers.h"
#include "clang/Index/TranslationUnit.h"
#include "ASTVisitor.h"
#include "clang/AST/DeclBase.h"
using namespace clang;
using namespace idx;
namespace {
class EntityIndexer : public EntityHandler {
TranslationUnit *TU;
Indexer::MapTy ⤅
public:
EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map) : TU(tu), Map(map) { }
virtual void Handle(Entity Ent) {
if (Ent.isInternalToTU())
return;
Map[Ent].insert(TU);
}
};
class SelectorIndexer : public ASTVisitor<SelectorIndexer> {
Program &Prog;
TranslationUnit *TU;
Indexer::SelMapTy &Map;
public:
SelectorIndexer(Program &prog, TranslationUnit *tu, Indexer::SelMapTy &map)
: Prog(prog), TU(tu), Map(map) { }
void VisitObjCMethodDecl(ObjCMethodDecl *D) {
Map[GlobalSelector::get(D->getSelector(), Prog)].insert(TU);
Base::VisitObjCMethodDecl(D);
}
void VisitObjCMessageExpr(ObjCMessageExpr *Node) {
Map[GlobalSelector::get(Node->getSelector(), Prog)].insert(TU);
Base::VisitObjCMessageExpr(Node);
}
};
} // anonymous namespace
void Indexer::IndexAST(TranslationUnit *TU) {
assert(TU && "Passed null TranslationUnit");
ASTContext &Ctx = TU->getASTContext();
CtxTUMap[&Ctx] = TU;
EntityIndexer Idx(TU, Map);
Prog.FindEntities(Ctx, Idx);
SelectorIndexer SelIdx(Prog, TU, SelMap);
SelIdx.Visit(Ctx.getTranslationUnitDecl());
}
void Indexer::GetTranslationUnitsFor(Entity Ent,
TranslationUnitHandler &Handler) {
assert(Ent.isValid() && "Expected valid Entity");
if (Ent.isInternalToTU()) {
Decl *D = Ent.getInternalDecl();
CtxTUMapTy::iterator I = CtxTUMap.find(&D->getASTContext());
if (I != CtxTUMap.end())
Handler.Handle(I->second);
return;
}
MapTy::iterator I = Map.find(Ent);
if (I == Map.end())
return;
TUSetTy &Set = I->second;
for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
Handler.Handle(*I);
}
void Indexer::GetTranslationUnitsFor(GlobalSelector Sel,
TranslationUnitHandler &Handler) {
assert(Sel.isValid() && "Expected valid GlobalSelector");
SelMapTy::iterator I = SelMap.find(Sel);
if (I == SelMap.end())
return;
TUSetTy &Set = I->second;
for (TUSetTy::iterator I = Set.begin(), E = Set.end(); I != E; ++I)
Handler.Handle(*I);
}