aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis/PathSensitive/Checker.h
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-07-22 21:42:34 +0000
committerTed Kremenek <kremenek@apple.com>2009-07-22 21:42:34 +0000
commit29e543cc4cacfec24ccb888b1d82b92a98ffe99b (patch)
tree42350479d205b1027909a850923cc305d493fa8c /include/clang/Analysis/PathSensitive/Checker.h
parente01ac5712a94279db2404134817fe6bbf16c1f7c (diff)
Add new 'Checker' and 'CheckerVisitor' classes, which represent a more powerful
interface to plug in domain-specific checker logic than the current GRSimpleAPICheck interface. The new 'Checker' interface can actually generate new nodes, allowing it to modify the state and refine the analysis (which GRSimpleAPIChecks could not). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76793 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/PathSensitive/Checker.h')
-rw-r--r--include/clang/Analysis/PathSensitive/Checker.h102
1 files changed, 102 insertions, 0 deletions
diff --git a/include/clang/Analysis/PathSensitive/Checker.h b/include/clang/Analysis/PathSensitive/Checker.h
new file mode 100644
index 0000000000..9c32d16458
--- /dev/null
+++ b/include/clang/Analysis/PathSensitive/Checker.h
@@ -0,0 +1,102 @@
+//== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines Checker and CheckerVisitor, classes used for creating
+// domain-specific checks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_CHECKER
+#define LLVM_CLANG_ANALYSIS_CHECKER
+#include "clang/Analysis/Support/SaveAndRestore.h"
+#include "clang/Analysis/PathSensitive/GRCoreEngine.h"
+#include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+
+//===----------------------------------------------------------------------===//
+// Checker interface.
+//===----------------------------------------------------------------------===//
+
+namespace clang {
+ class GRExprEngine;
+
+class CheckerContext {
+ ExplodedNodeSet<GRState> &Dst;
+ GRStmtNodeBuilder<GRState> &B;
+ GRExprEngine &Eng;
+ ExplodedNode<GRState> *Pred;
+ SaveAndRestore<bool> OldSink;
+ SaveAndRestore<const void*> OldTag;
+ SaveAndRestore<ProgramPoint::Kind> OldPointKind;
+ SaveOr OldHasGen;
+
+public:
+ CheckerContext(ExplodedNodeSet<GRState> &dst,
+ GRStmtNodeBuilder<GRState> &builder,
+ GRExprEngine &eng,
+ ExplodedNode<GRState> *pred,
+ const void *tag, bool preVisit)
+ : Dst(dst), B(builder), Eng(eng), Pred(pred),
+ OldSink(B.BuildSinks), OldTag(B.Tag),
+ OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) {
+ assert(Dst.empty());
+ B.Tag = tag;
+ if (preVisit)
+ B.PointKind = ProgramPoint::PreStmtKind;
+ }
+
+ ~CheckerContext() {
+ if (!B.BuildSinks && Dst.empty() && !B.HasGeneratedNode)
+ Dst.Add(Pred);
+ }
+
+ ConstraintManager &getConstraintManager() {
+ return Eng.getConstraintManager();
+ }
+ ExplodedNodeSet<GRState> &getNodeSet() { return Dst; }
+ GRStmtNodeBuilder<GRState> &getNodeBuilder() { return B; }
+ ExplodedNode<GRState> *&getPredecessor() { return Pred; }
+ const GRState *getState() { return B.GetState(Pred); }
+
+ ExplodedNode<GRState> *generateNode(const Stmt* S,
+ const GRState *state) {
+ return B.generateNode(S, state, Pred);
+ }
+
+ void EmitReport(BugReport *R) {
+ Eng.getBugReporter().EmitReport(R);
+ }
+};
+
+class Checker {
+private:
+ friend class GRExprEngine;
+
+ void GR_Visit(ExplodedNodeSet<GRState> &Dst,
+ GRStmtNodeBuilder<GRState> &Builder,
+ GRExprEngine &Eng,
+ const Stmt *stmt,
+ ExplodedNode<GRState> *Pred, bool isPrevisit) {
+ CheckerContext C(Dst, Builder, Eng, Pred, getTag(), isPrevisit);
+ assert(isPrevisit && "Only previsit supported for now.");
+ _PreVisit(C, stmt);
+ }
+
+public:
+ virtual void _PreVisit(CheckerContext &C, const Stmt *stmt) = 0;
+ virtual const void *getTag() = 0;
+};
+
+} // end clang namespace
+
+#endif
+ \ No newline at end of file