aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis/AnalysisContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/AnalysisContext.h')
-rw-r--r--include/clang/Analysis/AnalysisContext.h97
1 files changed, 71 insertions, 26 deletions
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index 6a1876e65900..3d0e88a51d8a 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -19,6 +19,7 @@
#include "clang/AST/Expr.h"
#include "clang/Analysis/CFG.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
@@ -31,14 +32,35 @@ class Stmt;
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 {
@@ -54,7 +76,6 @@ class AnalysisContext {
CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
bool builtCFG, builtCompleteCFG;
- const bool useUnoptimizedCFG;
llvm::OwningPtr<LiveVariables> liveness;
llvm::OwningPtr<LiveVariables> relaxedLiveness;
@@ -67,12 +88,13 @@ class AnalysisContext {
// FIXME: remove.
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+ void *ManagedAnalyses;
+
public:
+ AnalysisContext(const Decl *d, idx::TranslationUnit *tu);
+
AnalysisContext(const Decl *d, idx::TranslationUnit *tu,
- bool useUnoptimizedCFG = false,
- bool addehedges = false,
- bool addImplicitDtors = false,
- bool addInitializers = false);
+ const CFG::BuildOptions &buildOptions);
~AnalysisContext();
@@ -81,13 +103,22 @@ public:
idx::TranslationUnit *getTranslationUnit() const { return TU; }
+ /// Return the build options used to construct the CFG.
+ CFG::BuildOptions &getCFGBuildOptions() {
+ return cfgBuildOptions;
+ }
+
+ const CFG::BuildOptions &getCFGBuildOptions() const {
+ return cfgBuildOptions;
+ }
+
/// getAddEHEdges - Return true iff we are adding exceptional edges from
/// callExprs. If this is false, then try/catch statements and blocks
/// reachable from them can appear to be dead in the CFG, analysis passes must
/// cope with that.
bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
bool getUseUnoptimizedCFG() const {
- return cfgBuildOptions.PruneTriviallyFalseEdges;
+ return !cfgBuildOptions.PruneTriviallyFalseEdges;
}
bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
@@ -95,7 +126,7 @@ public:
void registerForcedBlockExpression(const Stmt *stmt);
const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
- Stmt *getBody();
+ Stmt *getBody() const;
CFG *getCFG();
CFGStmtMap *getCFGStmtMap();
@@ -114,8 +145,6 @@ public:
ParentMap &getParentMap();
PseudoConstantAnalysis *getPseudoConstantAnalysis();
- LiveVariables *getLiveVariables();
- LiveVariables *getRelaxedLiveVariables();
typedef const VarDecl * const * referenced_decls_iterator;
@@ -125,29 +154,44 @@ public:
/// 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 {
typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
ContextMap Contexts;
- bool UseUnoptimizedCFG;
- bool AddImplicitDtors;
- bool AddInitializers;
+ CFG::BuildOptions cfgBuildOptions;
public:
AnalysisContextManager(bool useUnoptimizedCFG = false,
- bool addImplicitDtors = false, bool addInitializers = false)
- : UseUnoptimizedCFG(useUnoptimizedCFG), AddImplicitDtors(addImplicitDtors),
- AddInitializers(addInitializers) {}
+ bool addImplicitDtors = false,
+ bool addInitializers = false);
~AnalysisContextManager();
AnalysisContext *getContext(const Decl *D, idx::TranslationUnit *TU = 0);
- bool getUseUnoptimizedCFG() const { return UseUnoptimizedCFG; }
- bool getAddImplicitDtors() const { return AddImplicitDtors; }
- bool getAddInitializers() const { return AddInitializers; }
+ bool getUseUnoptimizedCFG() const {
+ return !cfgBuildOptions.PruneTriviallyFalseEdges;
+ }
+
+ CFG::BuildOptions &getCFGBuildOptions() {
+ return cfgBuildOptions;
+ }
- // Discard all previously created AnalysisContexts.
+ /// Discard all previously created AnalysisContexts.
void clear();
};
@@ -187,8 +231,9 @@ public:
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 {
@@ -212,7 +257,7 @@ public:
ContextKind ck,
AnalysisContext *ctx,
const LocationContext *parent,
- const void* data);
+ const void *data);
};
class StackFrameContext : public LocationContext {
@@ -251,7 +296,7 @@ public:
ID.AddInteger(idx);
}
- static bool classof(const LocationContext* Ctx) {
+ static bool classof(const LocationContext *Ctx) {
return Ctx->getKind() == StackFrame;
}
};
@@ -274,7 +319,7 @@ public:
ProfileCommon(ID, Scope, ctx, parent, s);
}
- static bool classof(const LocationContext* Ctx) {
+ static bool classof(const LocationContext *Ctx) {
return Ctx->getKind() == Scope;
}
};
@@ -302,7 +347,7 @@ public:
ProfileCommon(ID, Block, ctx, parent, bd);
}
- static bool classof(const LocationContext* Ctx) {
+ static bool classof(const LocationContext *Ctx) {
return Ctx->getKind() == Block;
}
};