1 //== CheckerContext.h - Context info for path-sensitive 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 CheckerContext that provides contextual info for
11 // path-sensitive checkers.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
16 #define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT
18 #include "clang/Analysis/Support/SaveAndRestore.h"
19 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
25 class CheckerContext {
30 SaveAndRestore<bool> OldSink;
32 const ProgramPoint Location;
33 const ProgramState *ST;
36 bool *respondsToCallback;
38 CheckerContext(ExplodedNodeSet &dst,
39 StmtNodeBuilder &builder,
42 const ProgramPoint &loc,
43 bool *respondsToCB = 0,
44 const ProgramState *st = 0)
49 OldSink(B.BuildSinks),
50 OldHasGen(B.hasGeneratedNode),
54 respondsToCallback(respondsToCB) {}
58 ExprEngine &getEngine() {
62 AnalysisManager &getAnalysisManager() {
63 return Eng.getAnalysisManager();
66 ConstraintManager &getConstraintManager() {
67 return Eng.getConstraintManager();
70 StoreManager &getStoreManager() {
71 return Eng.getStoreManager();
74 ExplodedNodeSet &getNodeSet() { return Dst; }
75 ExplodedNode *&getPredecessor() { return Pred; }
76 const ProgramState *getState() { return ST ? ST : Pred->getState(); }
78 /// \brief Returns the number of times the current block has been visited
79 /// along the analyzed path.
80 unsigned getCurrentBlockCount() {return B.getCurrentBlockCount();}
82 ASTContext &getASTContext() {
83 return Eng.getContext();
86 BugReporter &getBugReporter() {
87 return Eng.getBugReporter();
90 SourceManager &getSourceManager() {
91 return getBugReporter().getSourceManager();
94 SValBuilder &getSValBuilder() {
95 return Eng.getSValBuilder();
98 SymbolManager &getSymbolManager() {
99 return getSValBuilder().getSymbolManager();
102 bool isObjCGCEnabled() {
103 return Eng.isObjCGCEnabled();
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);
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,
116 const ProgramPointTag *tag = 0,
117 bool autoTransition = true) {
118 ExplodedNode *N = generateNodeImpl(state, false, pred, tag);
119 if (N && autoTransition)
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)
134 /// \brief Generate a sink node. Generating sink stops exploration of the
136 ExplodedNode *generateSink(const ProgramState *state = 0) {
137 return generateNodeImpl(state ? state : getState(), true);
140 void addTransition(ExplodedNode *node) {
144 void addTransition(const ProgramState *state,
145 const ProgramPointTag *tag = 0) {
147 // If the 'state' is not new, we need to check if the cached state 'ST'
149 if (state != getState() || (ST && ST != Pred->getState()))
150 // state is new or equals to ST.
151 generateNode(state, true, tag);
156 void EmitReport(BugReport *R) {
157 Eng.getBugReporter().EmitReport(R);
160 AnalysisContext *getCurrentAnalysisContext() const {
161 return Pred->getLocationContext()->getAnalysisContext();
165 ExplodedNode *generateNodeImpl(const ProgramState *state,
167 ExplodedNode *pred = 0,
168 const ProgramPointTag *tag = 0) {
170 ExplodedNode *node = B.generateNode(tag ? Location.withTag(tag) : Location,
173 if (markAsSink && node)
179 } // end GR namespace
181 } // end clang namespace