diff options
-rw-r--r-- | examples/wpa/clang-wpa.cpp | 7 | ||||
-rw-r--r-- | include/clang/Index/Entity.h | 4 | ||||
-rw-r--r-- | include/clang/Index/Indexer.h | 7 | ||||
-rw-r--r-- | lib/Index/Entity.cpp | 59 | ||||
-rw-r--r-- | lib/Index/EntityImpl.h | 1 | ||||
-rw-r--r-- | lib/Index/Indexer.cpp | 21 |
6 files changed, 82 insertions, 17 deletions
diff --git a/examples/wpa/clang-wpa.cpp b/examples/wpa/clang-wpa.cpp index 4f103b2a8d..bfac398532 100644 --- a/examples/wpa/clang-wpa.cpp +++ b/examples/wpa/clang-wpa.cpp @@ -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; } diff --git a/include/clang/Index/Entity.h b/include/clang/Index/Entity.h index c2aab62e23..9863963ff2 100644 --- a/include/clang/Index/Entity.h +++ b/include/clang/Index/Entity.h @@ -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!"); diff --git a/include/clang/Index/Indexer.h b/include/clang/Index/Indexer.h index 361e729fea..96c585df24 100644 --- a/include/clang/Index/Indexer.h +++ b/include/clang/Index/Indexer.h @@ -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; }; diff --git a/lib/Index/Entity.cpp b/lib/Index/Entity.cpp index b6fb17fc2b..7a247191be 100644 --- a/lib/Index/Entity.cpp +++ b/lib/Index/Entity.cpp @@ -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()); diff --git a/lib/Index/EntityImpl.h b/lib/Index/EntityImpl.h index cbce934bf7..da52ccfc09 100644 --- a/lib/Index/EntityImpl.h +++ b/lib/Index/EntityImpl.h @@ -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(); diff --git a/lib/Index/Indexer.cpp b/lib/Index/Indexer.cpp index 57bfc5b4fb..7f21c4f303 100644 --- a/lib/Index/Indexer.cpp +++ b/lib/Index/Indexer.cpp @@ -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; +} |