summaryrefslogtreecommitdiffstats
path: root/include/clang/Analysis/PathSensitive/AnalysisContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Analysis/PathSensitive/AnalysisContext.h')
-rw-r--r--include/clang/Analysis/PathSensitive/AnalysisContext.h126
1 files changed, 93 insertions, 33 deletions
diff --git a/include/clang/Analysis/PathSensitive/AnalysisContext.h b/include/clang/Analysis/PathSensitive/AnalysisContext.h
index 8b1a329..abc33b7 100644
--- a/include/clang/Analysis/PathSensitive/AnalysisContext.h
+++ b/include/clang/Analysis/PathSensitive/AnalysisContext.h
@@ -15,9 +15,10 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-#include "clang/AST/Stmt.h"
+#include "clang/AST/Decl.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Allocator.h"
@@ -29,7 +30,10 @@ class CFG;
class LiveVariables;
class ParentMap;
class ImplicitParamDecl;
-
+class LocationContextManager;
+class BlockDataRegion;
+class StackFrameContext;
+
/// AnalysisContext contains the context data for the function or method under
/// analysis.
class AnalysisContext {
@@ -78,7 +82,7 @@ public:
class LocationContext : public llvm::FoldingSetNode {
public:
- enum ContextKind { StackFrame, Scope };
+ enum ContextKind { StackFrame, Scope, Block };
private:
ContextKind Kind;
@@ -91,7 +95,7 @@ protected:
: Kind(k), Ctx(ctx), Parent(parent) {}
public:
- virtual ~LocationContext() {}
+ virtual ~LocationContext();
ContextKind getKind() const { return Kind; }
@@ -114,36 +118,42 @@ public:
const ImplicitParamDecl *getSelfDecl() const {
return Ctx->getSelfDecl();
}
+
+ const StackFrameContext *getCurrentStackFrame() const;
+ const StackFrameContext *
+ getStackFrameForDeclContext(const DeclContext *DC) const;
- virtual void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Kind, Ctx, Parent);
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ContextKind k,
- AnalysisContext *ctx, const LocationContext *parent);
+ virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
static bool classof(const LocationContext*) { return true; }
+
+public:
+ static void ProfileCommon(llvm::FoldingSetNodeID &ID,
+ ContextKind ck,
+ AnalysisContext *ctx,
+ const LocationContext *parent,
+ const void* data);
};
class StackFrameContext : public LocationContext {
const Stmt *CallSite;
-public:
+ friend class LocationContextManager;
StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s)
: LocationContext(StackFrame, ctx, parent), CallSite(s) {}
-
- virtual ~StackFrameContext() {}
+public:
+ ~StackFrameContext() {}
- Stmt const *getCallSite() const { return CallSite; }
-
- virtual void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAnalysisContext(), getParent(), CallSite);
- }
+ const Stmt *getCallSite() const { return CallSite; }
+ void Profile(llvm::FoldingSetNodeID &ID);
+
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const Stmt *s);
+ const LocationContext *parent, const Stmt *s) {
+ ProfileCommon(ID, StackFrame, ctx, parent, s);
+ }
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == StackFrame;
@@ -152,41 +162,91 @@ public:
class ScopeContext : public LocationContext {
const Stmt *Enter;
-
-public:
+
+ friend class LocationContextManager;
ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s)
: LocationContext(Scope, ctx, parent), Enter(s) {}
-
- virtual ~ScopeContext() {}
- virtual void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getAnalysisContext(), getParent(), Enter);
- }
+public:
+ ~ScopeContext() {}
+
+ void Profile(llvm::FoldingSetNodeID &ID);
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const Stmt *s);
+ const LocationContext *parent, const Stmt *s) {
+ ProfileCommon(ID, Scope, ctx, parent, s);
+ }
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == Scope;
}
};
+class BlockInvocationContext : public LocationContext {
+ llvm::PointerUnion<const BlockDataRegion *, const BlockDecl *> Data;
+
+ friend class LocationContextManager;
+
+ BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
+ const BlockDataRegion *br)
+ : LocationContext(Block, ctx, parent), Data(br) {}
+
+ BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
+ const BlockDecl *bd)
+ : LocationContext(Block, ctx, parent), Data(bd) {}
+
+public:
+ ~BlockInvocationContext() {}
+
+ const BlockDataRegion *getBlockRegion() const {
+ return Data.is<const BlockDataRegion*>() ?
+ Data.get<const BlockDataRegion*>() : 0;
+ }
+
+ const BlockDecl *getBlockDecl() const;
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+
+ static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
+ const LocationContext *parent, const BlockDataRegion *br){
+ ProfileCommon(ID, Block, ctx, parent, br);
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
+ const LocationContext *parent, const BlockDecl *bd) {
+ ProfileCommon(ID, Block, ctx, parent, bd);
+ }
+
+ static bool classof(const LocationContext* Ctx) {
+ return Ctx->getKind() == Block;
+ }
+};
+
class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
-
public:
~LocationContextManager();
- StackFrameContext *getStackFrame(AnalysisContext *ctx,
- const LocationContext *parent,
- const Stmt *s);
+ const StackFrameContext *getStackFrame(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const Stmt *s);
- ScopeContext *getScope(AnalysisContext *ctx, const LocationContext *parent,
- const Stmt *s);
+ const ScopeContext *getScope(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const Stmt *s);
+
+ const BlockInvocationContext *
+ getBlockInvocation(AnalysisContext *ctx, const LocationContext *parent,
+ const BlockDataRegion *BR);
/// Discard all previously created LocationContext objects.
void clear();
+private:
+ template <typename LOC, typename DATA>
+ const LOC *getLocationContext(AnalysisContext *ctx,
+ const LocationContext *parent,
+ const DATA *d);
};
} // end clang namespace
OpenPOWER on IntegriCloud