]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/clang/Analysis/PathSensitive/Checker.h
Update clang to r86025.
[FreeBSD/FreeBSD.git] / include / clang / Analysis / PathSensitive / Checker.h
1 //== Checker.h - Abstract interface for checkers -----------------*- C++ -*--=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines Checker and CheckerVisitor, classes used for creating
11 //  domain-specific checks.
12 //
13 //===----------------------------------------------------------------------===//
14
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"
25
26 //===----------------------------------------------------------------------===//
27 // Checker interface.
28 //===----------------------------------------------------------------------===//
29
30 namespace clang {
31   class GRExprEngine;
32
33 class CheckerContext {
34   ExplodedNodeSet &Dst;
35   GRStmtNodeBuilder &B;
36   GRExprEngine &Eng;
37   ExplodedNode *Pred;
38   SaveAndRestore<bool> OldSink;
39   SaveAndRestore<const void*> OldTag;
40   SaveAndRestore<ProgramPoint::Kind> OldPointKind;
41   SaveOr OldHasGen;
42
43 public:
44   CheckerContext(ExplodedNodeSet &dst,
45                  GRStmtNodeBuilder &builder,
46                  GRExprEngine &eng,
47                  ExplodedNode *pred,
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.
54         B.Tag = tag;
55         if (preVisit)
56           B.PointKind = ProgramPoint::PreStmtKind;
57       }
58
59   ~CheckerContext() {
60     if (!B.BuildSinks && !B.HasGeneratedNode)
61       Dst.Add(Pred);
62   }
63
64   ConstraintManager &getConstraintManager() {
65       return Eng.getConstraintManager();
66   }
67   ExplodedNodeSet &getNodeSet() { return Dst; }
68   GRStmtNodeBuilder &getNodeBuilder() { return B; }
69   ExplodedNode *&getPredecessor() { return Pred; }
70   const GRState *getState() { return B.GetState(Pred); }
71
72   ASTContext &getASTContext() {
73     return Eng.getContext();
74   }
75   
76   BugReporter &getBugReporter() {
77     return Eng.getBugReporter();
78   }
79
80   ExplodedNode *GenerateNode(const Stmt *S, bool markAsSink = false) {
81     return GenerateNode(S, getState(), markAsSink);
82   }
83
84   ExplodedNode *GenerateNode(const Stmt* S, const GRState *state,
85                              bool markAsSink = false) {
86     ExplodedNode *node = B.generateNode(S, state, Pred);
87
88     if (markAsSink && node)
89       node->markAsSink();
90
91     return node;
92   }
93
94   void addTransition(ExplodedNode *node) {
95     Dst.Add(node);
96   }
97
98   void EmitReport(BugReport *R) {
99     Eng.getBugReporter().EmitReport(R);
100   }
101 };
102
103 class Checker {
104 private:
105   friend class GRExprEngine;
106
107   void GR_Visit(ExplodedNodeSet &Dst,
108                 GRStmtNodeBuilder &Builder,
109                 GRExprEngine &Eng,
110                 const Stmt *stmt,
111                 ExplodedNode *Pred, void *tag, bool isPrevisit) {
112     CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
113     assert(isPrevisit && "Only previsit supported for now.");
114     _PreVisit(C, stmt);
115   }
116
117   void GR_VisitBind(ExplodedNodeSet &Dst,
118                     GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
119                     const Stmt *stmt, ExplodedNode *Pred, void *tag, 
120                     SVal location, SVal val,
121                     bool isPrevisit) {
122     CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
123     assert(isPrevisit && "Only previsit supported for now.");
124     PreVisitBind(C, stmt, location, val);
125   }
126
127 public:
128   virtual ~Checker() {}
129   virtual void _PreVisit(CheckerContext &C, const Stmt *ST) {}
130   
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,
134                                       GRExprEngine &Eng) {
135     return Pred;
136   }
137   
138   virtual void PreVisitBind(CheckerContext &C, const Stmt *ST, 
139                             SVal location, SVal val) {}
140
141   virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred, 
142                                   const GRState *state, Stmt *S, 
143                                   GRExprEngine &Eng) {
144     return Pred;
145   }
146
147 };
148
149 } // end clang namespace
150
151 #endif
152