1 //== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines Checker and CheckerVisitor, classes used for creating
11 // domain-specific checks.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_ANALYSIS_CHECKER
16 #define LLVM_CLANG_ANALYSIS_CHECKER
17 #include "clang/Analysis/Support/SaveAndRestore.h"
18 #include "clang/Analysis/PathSensitive/GRCoreEngine.h"
19 #include "clang/Analysis/PathSensitive/GRState.h"
20 #include "clang/Analysis/PathSensitive/GRExprEngine.h"
21 #include "clang/AST/ExprCXX.h"
22 #include "clang/AST/ExprObjC.h"
23 #include "clang/AST/StmtCXX.h"
24 #include "clang/AST/StmtObjC.h"
26 //===----------------------------------------------------------------------===//
28 //===----------------------------------------------------------------------===//
33 class CheckerContext {
38 SaveAndRestore<bool> OldSink;
39 SaveAndRestore<const void*> OldTag;
40 SaveAndRestore<ProgramPoint::Kind> OldPointKind;
44 CheckerContext(ExplodedNodeSet &dst,
45 GRStmtNodeBuilder &builder,
48 const void *tag, bool preVisit)
49 : Dst(dst), B(builder), Eng(eng), Pred(pred),
50 OldSink(B.BuildSinks), OldTag(B.Tag),
51 OldPointKind(B.PointKind), OldHasGen(B.HasGeneratedNode) {
52 //assert(Dst.empty()); // This is a fake assertion.
53 // See GRExprEngine::CheckerVisit(), CurrSet is repeatedly used.
56 B.PointKind = ProgramPoint::PreStmtKind;
60 if (!B.BuildSinks && !B.HasGeneratedNode)
64 ConstraintManager &getConstraintManager() {
65 return Eng.getConstraintManager();
67 ExplodedNodeSet &getNodeSet() { return Dst; }
68 GRStmtNodeBuilder &getNodeBuilder() { return B; }
69 ExplodedNode *&getPredecessor() { return Pred; }
70 const GRState *getState() { return B.GetState(Pred); }
72 ASTContext &getASTContext() {
73 return Eng.getContext();
76 BugReporter &getBugReporter() {
77 return Eng.getBugReporter();
80 ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) {
81 return GenerateNode(S, getState(), markAsSink);
84 ExplodedNode *GenerateNode(const Stmt* S, const GRState *state,
85 bool markAsSink = false) {
86 ExplodedNode *node = B.generateNode(S, state, Pred);
88 if (markAsSink && node)
94 void addTransition(ExplodedNode *node) {
98 void EmitReport(BugReport *R) {
99 Eng.getBugReporter().EmitReport(R);
105 friend class GRExprEngine;
107 void GR_Visit(ExplodedNodeSet &Dst,
108 GRStmtNodeBuilder &Builder,
111 ExplodedNode *Pred, void *tag, bool isPrevisit) {
112 CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
113 assert(isPrevisit && "Only previsit supported for now.");
117 void GR_VisitBind(ExplodedNodeSet &Dst,
118 GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
119 const Stmt *stmt, ExplodedNode *Pred, void *tag,
120 SVal location, SVal val,
122 CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
123 assert(isPrevisit && "Only previsit supported for now.");
124 PreVisitBind(C, stmt, location, val);
128 virtual ~Checker() {}
129 virtual void _PreVisit(CheckerContext &C, const Stmt *ST) {}
131 // This is a previsit which takes a node returns a node.
132 virtual ExplodedNode *CheckLocation(const Stmt *S, ExplodedNode *Pred,
133 const GRState *state, SVal V,
138 virtual void PreVisitBind(CheckerContext &C, const Stmt *ST,
139 SVal location, SVal val) {}
141 virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
142 const GRState *state, Stmt *S,
149 } // end clang namespace