forked from OSchip/llvm-project
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:
parent
8f06b4a294
commit
b525bce698
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -25,14 +25,22 @@ namespace {
|
|||
class EntityIndexer : public EntityHandler {
|
||||
TranslationUnit *TU;
|
||||
Indexer::MapTy ⤅
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue