Collect function definitions in the Indexer when indexing through the ASTs.

Add an API to get an Entity associated with a name in the global namespace.

llvm-svn: 107642
This commit is contained in:
Zhongxing Xu 2010-07-06 05:55:13 +00:00
parent 8f06b4a294
commit b525bce698
6 changed files with 82 additions and 17 deletions

View File

@ -105,5 +105,12 @@ int main(int argc, char **argv) {
Idxer.IndexAST(&TU);
}
Entity Ent = Entity::get(AnalyzeFunction, Prog);
FunctionDecl *FD;
TranslationUnit *TU;
llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent);
if (!FD)
return 0;
return 0;
}

View File

@ -17,6 +17,7 @@
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include <string>
namespace clang {
@ -71,6 +72,9 @@ public:
/// \returns invalid Entity if an Entity cannot refer to this Decl.
static Entity get(Decl *D, Program &Prog);
/// \brief Get an Entity associated with a name in the global namespace.
static Entity get(llvm::StringRef Name, Program &Prog);
/// \brief true if the Entity is not visible outside the trasnlation unit.
bool isInternalToTU() const {
assert(isValid() && "This Entity is not valid!");

View File

@ -23,6 +23,7 @@
namespace clang {
class ASTContext;
class FunctionDecl;
namespace idx {
class Program;
@ -35,6 +36,7 @@ public:
typedef llvm::DenseMap<ASTContext *, TranslationUnit *> CtxTUMapTy;
typedef std::map<Entity, TUSetTy> MapTy;
typedef std::map<GlobalSelector, TUSetTy> SelMapTy;
typedef std::map<Entity, std::pair<FunctionDecl*,TranslationUnit*> > DefMapTy;
explicit Indexer(Program &prog) :
Prog(prog) { }
@ -49,10 +51,15 @@ public:
virtual void GetTranslationUnitsFor(GlobalSelector Sel,
TranslationUnitHandler &Handler);
std::pair<FunctionDecl*, TranslationUnit*> getDefinitionFor(Entity Ent);
private:
Program &Prog;
MapTy Map;
// Map a function Entity to the its definition.
DefMapTy DefMap;
CtxTUMapTy CtxTUMap;
SelMapTy SelMap;
};

View File

@ -42,6 +42,13 @@ public:
EntityGetter(Program &prog, ProgramImpl &progImpl)
: Prog(prog), ProgImpl(progImpl) { }
// Get an Entity.
Entity getEntity(Entity Parent, DeclarationName Name,
unsigned IdNS, bool isObjCInstanceMethod);
// Get an Entity associated with the name in the global namespace.
Entity getGlobalEntity(llvm::StringRef Name);
Entity VisitNamedDecl(NamedDecl *D);
Entity VisitVarDecl(VarDecl *D);
Entity VisitFieldDecl(FieldDecl *D);
@ -52,6 +59,31 @@ public:
}
}
Entity EntityGetter::getEntity(Entity Parent, DeclarationName Name,
unsigned IdNS, bool isObjCInstanceMethod) {
llvm::FoldingSetNodeID ID;
EntityImpl::Profile(ID, Parent, Name, IdNS, isObjCInstanceMethod);
ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities();
void *InsertPos = 0;
if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
return Entity(Ent);
void *Buf = ProgImpl.Allocate(sizeof(EntityImpl));
EntityImpl *New =
new (Buf) EntityImpl(Parent, Name, IdNS, isObjCInstanceMethod);
Entities.InsertNode(New, InsertPos);
return Entity(New);
}
Entity EntityGetter::getGlobalEntity(llvm::StringRef Name) {
IdentifierInfo *II = &ProgImpl.getIdents().get(Name);
DeclarationName GlobName(II);
unsigned IdNS = Decl::IDNS_Ordinary;
return getEntity(Entity(), GlobName, IdNS, false);
}
Entity EntityGetter::VisitNamedDecl(NamedDecl *D) {
Entity Parent;
if (!D->getDeclContext()->isTranslationUnit()) {
@ -93,21 +125,7 @@ Entity EntityGetter::VisitNamedDecl(NamedDecl *D) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
bool isObjCInstanceMethod = MD && MD->isInstanceMethod();
llvm::FoldingSetNodeID ID;
EntityImpl::Profile(ID, Parent, GlobName, IdNS, isObjCInstanceMethod);
ProgramImpl::EntitySetTy &Entities = ProgImpl.getEntities();
void *InsertPos = 0;
if (EntityImpl *Ent = Entities.FindNodeOrInsertPos(ID, InsertPos))
return Entity(Ent);
void *Buf = ProgImpl.Allocate(sizeof(EntityImpl));
EntityImpl *New =
new (Buf) EntityImpl(Parent, GlobName, IdNS, isObjCInstanceMethod);
Entities.InsertNode(New, InsertPos);
return Entity(New);
return getEntity(Parent, GlobName, IdNS, isObjCInstanceMethod);
}
Entity EntityGetter::VisitVarDecl(VarDecl *D) {
@ -190,6 +208,12 @@ Entity EntityImpl::get(Decl *D, Program &Prog, ProgramImpl &ProgImpl) {
return EntityGetter(Prog, ProgImpl).Visit(D);
}
/// \brief Get an Entity associated with a global name.
Entity EntityImpl::get(llvm::StringRef Name, Program &Prog,
ProgramImpl &ProgImpl) {
return EntityGetter(Prog, ProgImpl).getGlobalEntity(Name);
}
std::string EntityImpl::getPrintableName() {
return Name.getAsString();
}
@ -235,6 +259,11 @@ Entity Entity::get(Decl *D, Program &Prog) {
return EntityImpl::get(D, Prog, ProgImpl);
}
Entity Entity::get(llvm::StringRef Name, Program &Prog) {
ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
return EntityImpl::get(Name, Prog, ProgImpl);
}
unsigned
llvm::DenseMapInfo<Entity>::getHashValue(Entity E) {
return DenseMapInfo<void*>::getHashValue(E.getAsOpaquePtr());

View File

@ -47,6 +47,7 @@ public:
/// \brief Get an Entity associated with the given Decl.
/// \returns Null if an Entity cannot refer to this Decl.
static Entity get(Decl *D, Program &Prog, ProgramImpl &ProgImpl);
static Entity get(llvm::StringRef Name, Program &Prog, ProgramImpl &ProgImpl);
std::string getPrintableName();

View File

@ -25,14 +25,22 @@ namespace {
class EntityIndexer : public EntityHandler {
TranslationUnit *TU;
Indexer::MapTy &Map;
Indexer::DefMapTy &DefMap;
public:
EntityIndexer(TranslationUnit *tu, Indexer::MapTy &map) : TU(tu), Map(map) { }
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);
}
};
@ -62,7 +70,7 @@ void Indexer::IndexAST(TranslationUnit *TU) {
assert(TU && "Passed null TranslationUnit");
ASTContext &Ctx = TU->getASTContext();
CtxTUMap[&Ctx] = TU;
EntityIndexer Idx(TU, Map);
EntityIndexer Idx(TU, Map, DefMap);
Prog.FindEntities(Ctx, Idx);
SelectorIndexer SelIdx(Prog, TU, SelMap);
@ -102,3 +110,12 @@ void Indexer::GetTranslationUnitsFor(GlobalSelector Sel,
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;
}