Remove AnalysisContext::getLiveVariables(), and introduce a templatized mechanism to lazily create analyses that are attached to AnalysisContext objects.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141425 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index fe017fe..3d0e88a 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -32,14 +32,35 @@
class CFGReverseBlockReachabilityAnalysis;
class CFGStmtMap;
class LiveVariables;
+class ManagedAnalysis;
class ParentMap;
class PseudoConstantAnalysis;
class ImplicitParamDecl;
class LocationContextManager;
class StackFrameContext;
-
+
namespace idx { class TranslationUnit; }
+/// The base class of a hierarchy of objects representing analyses tied
+/// to AnalysisContext.
+class ManagedAnalysis {
+protected:
+ ManagedAnalysis() {}
+public:
+ virtual ~ManagedAnalysis();
+
+ // Subclasses need to implement:
+ //
+ // static const void *getTag();
+ //
+ // Which returns a fixed pointer address to distinguish classes of
+ // analysis objects. They also need to implement:
+ //
+ // static [Derived*] create(AnalysisContext &Ctx);
+ //
+ // which creates the analysis object given an AnalysisContext.
+};
+
/// AnalysisContext contains the context data for the function or method under
/// analysis.
class AnalysisContext {
@@ -67,6 +88,8 @@
// FIXME: remove.
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+ void *ManagedAnalyses;
+
public:
AnalysisContext(const Decl *d, idx::TranslationUnit *tu);
@@ -122,8 +145,6 @@
ParentMap &getParentMap();
PseudoConstantAnalysis *getPseudoConstantAnalysis();
- LiveVariables *getLiveVariables();
- LiveVariables *getRelaxedLiveVariables();
typedef const VarDecl * const * referenced_decls_iterator;
@@ -133,6 +154,20 @@
/// Return the ImplicitParamDecl* associated with 'self' if this
/// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise.
const ImplicitParamDecl *getSelfDecl() const;
+
+ /// Return the specified analysis object, lazily running the analysis if
+ /// necessary. Return NULL if the analysis could not run.
+ template <typename T>
+ T *getAnalysis() {
+ const void *tag = T::getTag();
+ ManagedAnalysis *&data = getAnalysisImpl(tag);
+ if (!data) {
+ data = T::create(*this);
+ }
+ return static_cast<T*>(data);
+ }
+private:
+ ManagedAnalysis *&getAnalysisImpl(const void* tag);
};
class AnalysisContextManager {
@@ -196,8 +231,9 @@
CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
- LiveVariables *getLiveVariables() const {
- return getAnalysisContext()->getLiveVariables();
+ template <typename T>
+ T *getAnalysis() const {
+ return getAnalysisContext()->getAnalysis<T>();
}
ParentMap &getParentMap() const {