]> granicus.if.org Git - clang/commitdiff
Collect function definitions in the Indexer when indexing through the ASTs.
authorZhongxing Xu <xuzhongxing@gmail.com>
Tue, 6 Jul 2010 05:55:13 +0000 (05:55 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Tue, 6 Jul 2010 05:55:13 +0000 (05:55 +0000)
Add an API to get an Entity associated with a name in the global namespace.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107642 91177308-0d34-0410-b5e6-96231b3b80d8

examples/wpa/clang-wpa.cpp
include/clang/Index/Entity.h
include/clang/Index/Indexer.h
lib/Index/Entity.cpp
lib/Index/EntityImpl.h
lib/Index/Indexer.cpp

index 4f103b2a8da516c16b35ba3094821e3a7e78d851..bfac398532a2603bca572e6ee63bd977ca1b90dd 100644 (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;
 }
index c2aab62e23f2a8847800bfbdbb662e4da295f2f0..9863963ff217254dea25f9541ced8558b2b416de 100644 (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!");
index 361e729feab2da9317009a2e9cdad7f30c10b19e..96c585df2478c6211ab21701fb7ee8e95c344bb1 100644 (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;
 };
index b6fb17fc2b143dde3c8dcefc5c8e45b9aec76ca5..7a247191bee6914b45be33084b7454129d18d350 100644 (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());
index cbce934bf7777709efca6ac3f007fff5a1510ae4..da52ccfc099e1d580cbdbd1d365eada85919421a 100644 (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();
 
index 57bfc5b4fbfd2afa6386a668d1f4039f283786eb..7f21c4f3035a07086b48a3364f8f0ab333a35299 100644 (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;
+}