forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			122 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- 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 ⤅
 | |
|   Indexer::DefMapTy &DefMap;
 | |
| 
 | |
| public:
 | |
|   EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map, 
 | |
|                 Indexer::DefMapTy &defmap) 
 | |
|     : TU(tu), Map(map), DefMap(defmap) { }
 | |
| 
 | |
|   virtual void Handle(Entity Ent) {
 | |
|     if (Ent.isInternalToTU())
 | |
|       return;
 | |
|     Map[Ent].insert(TU);
 | |
| 
 | |
|     Decl *D = Ent.getDecl(TU->getASTContext());
 | |
|     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
 | |
|       if (FD->isThisDeclarationADefinition())
 | |
|         DefMap[Ent] = std::make_pair(FD, TU);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class SelectorIndexer : public ASTVisitor<SelectorIndexer> {
 | |
|   Program &Prog;
 | |
|   TranslationUnit *TU;
 | |
|   Indexer::SelMapTy ⤅
 | |
| 
 | |
| 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, DefMap);
 | |
|   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);
 | |
| }
 | |
| 
 | |
| std::pair<FunctionDecl *, TranslationUnit *> 
 | |
| Indexer::getDefinitionFor(Entity Ent) {
 | |
|   DefMapTy::iterator I = DefMap.find(Ent);
 | |
|   if (I == DefMap.end())
 | |
|     return std::make_pair((FunctionDecl *)0, (TranslationUnit *)0);
 | |
|   else
 | |
|     return I->second;
 | |
| }
 |