]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / include / clang / StaticAnalyzer / Core / PathSensitive / CheckerContext.h
1 //== CheckerContext.h - Context info for path-sensitive 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 CheckerContext that provides contextual info for
11 // path-sensitive checkers.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
16 #define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
17
18 #include "clang/Analysis/Support/SaveAndRestore.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
20
21 namespace clang {
22
23 namespace ento {
24
25 class CheckerContext {
26   ExplodedNodeSet &Dst;
27   StmtNodeBuilder &B;
28   ExprEngine &Eng;
29   ExplodedNode *Pred;
30   SaveAndRestore<bool> OldSink;
31   SaveOr OldHasGen;
32   const ProgramPoint Location;
33   const ProgramState *ST;
34   const unsigned size;
35 public:
36   bool *respondsToCallback;
37 public:
38   CheckerContext(ExplodedNodeSet &dst,
39                  StmtNodeBuilder &builder,
40                  ExprEngine &eng,
41                  ExplodedNode *pred,
42                  const ProgramPoint &loc,
43                  bool *respondsToCB = 0,
44                  const ProgramState *st = 0)
45     : Dst(dst),
46       B(builder),
47       Eng(eng),
48       Pred(pred),
49       OldSink(B.BuildSinks),
50       OldHasGen(B.hasGeneratedNode),
51       Location(loc),
52       ST(st),
53       size(Dst.size()),
54       respondsToCallback(respondsToCB) {}
55
56   ~CheckerContext();
57
58   ExprEngine &getEngine() {
59     return Eng;
60   }
61
62   AnalysisManager &getAnalysisManager() {
63     return Eng.getAnalysisManager();
64   }
65
66   ConstraintManager &getConstraintManager() {
67     return Eng.getConstraintManager();
68   }
69
70   StoreManager &getStoreManager() {
71     return Eng.getStoreManager();
72   }
73
74   ExplodedNodeSet &getNodeSet() { return Dst; }
75   ExplodedNode *&getPredecessor() { return Pred; }
76   const ProgramState *getState() { return ST ? ST : Pred->getState(); }
77
78   /// \brief Returns the number of times the current block has been visited
79   /// along the analyzed path.
80   unsigned getCurrentBlockCount() {return B.getCurrentBlockCount();}
81
82   ASTContext &getASTContext() {
83     return Eng.getContext();
84   }
85   
86   BugReporter &getBugReporter() {
87     return Eng.getBugReporter();
88   }
89   
90   SourceManager &getSourceManager() {
91     return getBugReporter().getSourceManager();
92   }
93
94   SValBuilder &getSValBuilder() {
95     return Eng.getSValBuilder();
96   }
97
98   SymbolManager &getSymbolManager() {
99     return getSValBuilder().getSymbolManager();
100   }
101
102   bool isObjCGCEnabled() {
103     return Eng.isObjCGCEnabled();
104   }
105
106   /// \brief Generate a default checker node (containing checker tag but no
107   /// checker state changes).
108   ExplodedNode *generateNode(bool autoTransition = true) {
109     return generateNode(getState(), autoTransition);
110   }
111   
112   /// \brief Generate a new checker node with the given predecessor.
113   /// Allows checkers to generate a chain of nodes.
114   ExplodedNode *generateNode(const ProgramState *state,
115                              ExplodedNode *pred,
116                              const ProgramPointTag *tag = 0,
117                              bool autoTransition = true) {
118     ExplodedNode *N = generateNodeImpl(state, false, pred, tag);
119     if (N && autoTransition)
120       addTransition(N);
121     return N;
122   }
123
124   /// \brief Generate a new checker node.
125   ExplodedNode *generateNode(const ProgramState *state,
126                              bool autoTransition = true,
127                              const ProgramPointTag *tag = 0) {
128     ExplodedNode *N = generateNodeImpl(state, false, 0, tag);
129     if (N && autoTransition)
130       addTransition(N);
131     return N;
132   }
133
134   /// \brief Generate a sink node. Generating sink stops exploration of the
135   /// given path.
136   ExplodedNode *generateSink(const ProgramState *state = 0) {
137     return generateNodeImpl(state ? state : getState(), true);
138   }
139
140   void addTransition(ExplodedNode *node) {
141     Dst.Add(node);
142   }
143   
144   void addTransition(const ProgramState *state,
145                      const ProgramPointTag *tag = 0) {
146     assert(state);
147     // If the 'state' is not new, we need to check if the cached state 'ST'
148     // is new.
149     if (state != getState() || (ST && ST != Pred->getState()))
150       // state is new or equals to ST.
151       generateNode(state, true, tag);
152     else
153       Dst.Add(Pred);
154   }
155
156   void EmitReport(BugReport *R) {
157     Eng.getBugReporter().EmitReport(R);
158   }
159
160   AnalysisContext *getCurrentAnalysisContext() const {
161     return Pred->getLocationContext()->getAnalysisContext();
162   }
163
164 private:
165   ExplodedNode *generateNodeImpl(const ProgramState *state,
166                                  bool markAsSink,
167                                  ExplodedNode *pred = 0,
168                                  const ProgramPointTag *tag = 0) {
169
170     ExplodedNode *node = B.generateNode(tag ? Location.withTag(tag) : Location,
171                                         state,
172                                         pred ? pred : Pred);
173     if (markAsSink && node)
174       node->markAsSink();
175     return node;
176   }
177 };
178
179 } // end GR namespace
180
181 } // end clang namespace
182
183 #endif