]> granicus.if.org Git - clang/commitdiff
-Introduce the idx::Analyzer class used for getting indexing information, like finding
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 29 Jul 2009 23:40:14 +0000 (23:40 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 29 Jul 2009 23:40:14 +0000 (23:40 +0000)
references of a declaration across translation units.

-Modify the index-test tool to use it.

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

include/clang/Index/Analyzer.h [new file with mode: 0644]
lib/Index/Analyzer.cpp [new file with mode: 0644]
tools/index-test/index-test.cpp

diff --git a/include/clang/Index/Analyzer.h b/include/clang/Index/Analyzer.h
new file mode 100644 (file)
index 0000000..90118b5
--- /dev/null
@@ -0,0 +1,51 @@
+//===--- Analyzer.h - Analysis for indexing information ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Analyzer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_ANALYZER_H
+#define LLVM_CLANG_INDEX_ANALYZER_H
+
+namespace clang {
+  class Decl;
+
+namespace idx {
+  class Program;
+  class IndexProvider;
+  class TULocationHandler;
+
+/// \brief Provides indexing information, like finding all references of an
+/// Entity across translation units.
+class Analyzer {
+  Program &Prog;
+  IndexProvider &Idxer;
+
+  Analyzer(const Analyzer&); // do not implement
+  Analyzer &operator=(const Analyzer &); // do not implement
+
+public:
+  explicit Analyzer(Program &prog, IndexProvider &idxer)
+    : Prog(prog), Idxer(idxer) { }
+
+  /// \brief Find all TULocations for declarations of the given Decl and pass
+  /// them to Handler.
+  void FindDeclarations(Decl *D, TULocationHandler &Handler);
+
+  /// \brief Find all TULocations for references of the given Decl and pass
+  /// them to Handler.
+  void FindReferences(Decl *D, TULocationHandler &Handler);
+};
+
+} // namespace idx
+
+} // namespace clang
+
+#endif
diff --git a/lib/Index/Analyzer.cpp b/lib/Index/Analyzer.cpp
new file mode 100644 (file)
index 0000000..bd1d62c
--- /dev/null
@@ -0,0 +1,104 @@
+//===--- Analyzer.cpp - Analysis for indexing information -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Analyzer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/Analyzer.h"
+#include "clang/Index/Entity.h"
+#include "clang/Index/TranslationUnit.h"
+#include "clang/Index/Handlers.h"
+#include "clang/Index/ASTLocation.h"
+#include "clang/Index/DeclReferenceMap.h"
+#include "clang/Index/IndexProvider.h"
+#include "clang/AST/Decl.h"
+#include "llvm/Support/Compiler.h"
+using namespace clang;
+using namespace idx;
+
+namespace  {
+
+//===----------------------------------------------------------------------===//
+// DeclEntityAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+class VISIBILITY_HIDDEN DeclEntityAnalyzer : public TranslationUnitHandler {
+  Entity Ent;
+  TULocationHandler &TULocHandler;
+  
+public:
+  DeclEntityAnalyzer(Entity ent, TULocationHandler &handler)
+    : Ent(ent), TULocHandler(handler) { }
+  
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    assert(D && "Couldn't resolve Entity");
+
+    for (Decl::redecl_iterator I = D->redecls_begin(),
+                               E = D->redecls_end(); I != E; ++I)
+      TULocHandler.Handle(TULocation(TU, ASTLocation(*I)));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// RefEntityAnalyzer Implementation
+//===----------------------------------------------------------------------===//
+
+class VISIBILITY_HIDDEN RefEntityAnalyzer : public TranslationUnitHandler {
+  Entity Ent;
+  TULocationHandler &TULocHandler;
+  
+public:
+  RefEntityAnalyzer(Entity ent, TULocationHandler &handler)
+    : Ent(ent), TULocHandler(handler) { }
+  
+  virtual void Handle(TranslationUnit *TU) {
+    assert(TU && "Passed null translation unit");
+
+    Decl *D = Ent.getDecl(TU->getASTContext());
+    assert(D && "Couldn't resolve Entity");
+    NamedDecl *ND = dyn_cast<NamedDecl>(D);
+    if (!ND)
+      return;
+
+    DeclReferenceMap &RefMap = TU->getDeclReferenceMap();
+    for (DeclReferenceMap::astlocation_iterator
+           I = RefMap.refs_begin(ND), E = RefMap.refs_end(ND); I != E; ++I)
+      TULocHandler.Handle(TULocation(TU, ASTLocation(*I)));
+  }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// Analyzer Implementation
+//===----------------------------------------------------------------------===//
+
+void Analyzer::FindDeclarations(Decl *D, TULocationHandler &Handler) {
+  assert(D && "Passed null declaration");
+  Entity Ent = Entity::get(D, Prog);
+  if (Ent.isInvalid())
+    return;
+  
+  DeclEntityAnalyzer DEA(Ent, Handler);
+  Idxer.GetTranslationUnitsFor(Ent, DEA);
+}
+
+void Analyzer::FindReferences(Decl *D, TULocationHandler &Handler) {
+  assert(D && "Passed null declaration");
+  Entity Ent = Entity::get(D, Prog);
+  if (Ent.isInvalid())
+    return;
+  
+  RefEntityAnalyzer REA(Ent, Handler);
+  Idxer.GetTranslationUnitsFor(Ent, REA);
+}
index 5fc6269f7a8f0b043587fc59ca156d690e3ed449..a0d60f7b492238962a8f28cf87acd45acf35c9ff 100644 (file)
@@ -39,6 +39,7 @@
 #include "clang/Index/ASTLocation.h"
 #include "clang/Index/DeclReferenceMap.h"
 #include "clang/Index/Handlers.h"
+#include "clang/Index/Analyzer.h"
 #include "clang/Index/Utils.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CommandLineSourceLoc.h"
@@ -100,73 +101,57 @@ DisableFree("disable-free",
 
 static bool HadErrors = false;
 
-static void ProcessDecl(Decl *D) {
-  assert(D);
+static void ProcessASTLocation(ASTLocation ASTLoc, Indexer &Idxer) {
+  assert(ASTLoc.isValid());
+
+  Decl *D = ASTLoc.getReferencedDecl();
+  if (D == 0) {
+    llvm::errs() << "Error: Couldn't get referenced Decl for the ASTLocation\n";
+    HadErrors = true;
+    return;
+  }
+
   llvm::raw_ostream &OS = llvm::outs();
-  
+  typedef Storing<TULocationHandler> ResultsTy;
+  ResultsTy Results;
+
+  Analyzer Analyz(Idxer.getProgram(), Idxer);
+
   switch (ProgAction) {
   default: assert(0);
   case PrintRefs: {
-    NamedDecl *ND = dyn_cast<NamedDecl>(D);
-    if (!ND)
-      return;
-
-    DeclReferenceMap RefMap(ND->getASTContext());
-    for (DeclReferenceMap::astlocation_iterator
-           I = RefMap.refs_begin(ND), E = RefMap.refs_end(ND); I != E; ++I)
+    Analyz.FindReferences(D, Results);
+    for (ResultsTy::iterator
+           I = Results.begin(), E = Results.end(); I != E; ++I)
       I->print(OS);
     break;
   }
-  
-  case PrintDefs: {
-    const Decl *DefD = 0;
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      const FunctionDecl *DFD = 0;
-      FD->getBody(DFD);
-      DefD = DFD;
-    } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-      const VarDecl *DVD = 0;
-      VD->getDefinition(DVD);
-      DefD = DVD;
-    } 
 
-    if (DefD)
-      ASTLocation(DefD).print(OS);
-    break;    
-  }
-  
-  case PrintDecls :
-    for (Decl::redecl_iterator I = D->redecls_begin(),
-                               E = D->redecls_end(); I != E; ++I)
-      ASTLocation(*I).print(OS);
+  case PrintDecls: {
+    Analyz.FindDeclarations(D, Results);
+    for (ResultsTy::iterator
+           I = Results.begin(), E = Results.end(); I != E; ++I)
+      I->print(OS);
     break;
-    
   }
-}
 
-static void ProcessASTLocation(ASTLocation ASTLoc, Indexer &Idxer) {
-  assert(ASTLoc.isValid());
+  case PrintDefs:{
+    Analyz.FindDeclarations(D, Results);
+    for (ResultsTy::iterator
+           I = Results.begin(), E = Results.end(); I != E; ++I) {
+      const Decl *D = I->getDecl();
+      bool isDef = false;
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+        isDef = FD->isThisDeclarationADefinition();
+      else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+        isDef = VD->getInit() != 0;
 
-  Decl *D = ASTLoc.getReferencedDecl();
-  if (D == 0) {
-    llvm::errs() << "Error: Couldn't get referenced Decl for the ASTLocation\n";
-    HadErrors = true;
-    return;
+      if (isDef)
+        I->print(OS);
+    }
+    break;
   }
 
-  Entity Ent = Entity::get(D, Idxer.getProgram());
-  if (Ent.isInvalid() || Ent.isInternalToTU())
-    return ProcessDecl(D);
-
-  Storing<TranslationUnitHandler> TURes;
-  Idxer.GetTranslationUnitsFor(Ent, TURes);
-
-  // Find the "same" Decl in other translation units and print information.
-  for (Storing<TranslationUnitHandler>::iterator
-         I = TURes.begin(), E = TURes.end(); I != E; ++I) {
-    Decl *OtherD = Ent.getDecl((*I)->getASTContext());
-    assert(OtherD && "Couldn't resolve Entity");
-    ProcessDecl(OtherD);
   }
 }