--- /dev/null
+//===--- 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
--- /dev/null
+//===--- 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);
+}
#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"
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);
}
}