CheckerContext.h revision f05aac8472d8ed081a361a218fd14d59ddc91b85
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 21namespace clang { 22 23namespace ento { 24 25class CheckerContext { 26 ExplodedNodeSet &Dst; 27 StmtNodeBuilder &B; 28 ExprEngine &Eng; 29 ExplodedNode *Pred; 30 const ProgramPoint Location; 31 const ProgramState *ST; 32 const unsigned size; 33 NodeBuilder NB; 34public: 35 bool *respondsToCallback; 36public: 37 CheckerContext(ExplodedNodeSet &dst, 38 StmtNodeBuilder &builder, 39 ExprEngine &eng, 40 ExplodedNode *pred, 41 const ProgramPoint &loc, 42 bool *respondsToCB = 0, 43 const ProgramState *st = 0) 44 : Dst(dst), 45 B(builder), 46 Eng(eng), 47 Pred(pred), 48 Location(loc), 49 ST(st), 50 size(Dst.size()), 51 NB(builder.Eng, pred), 52 respondsToCallback(respondsToCB) { 53 assert(!(ST && ST != Pred->getState())); 54 } 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 ExplodedNode *&getPredecessor() { return Pred; } 75 const ProgramState *getState() { return ST ? ST : Pred->getState(); } 76 77 /// \brief Returns the number of times the current block has been visited 78 /// along the analyzed path. 79 unsigned getCurrentBlockCount() {return B.getCurrentBlockCount();} 80 81 ASTContext &getASTContext() { 82 return Eng.getContext(); 83 } 84 85 BugReporter &getBugReporter() { 86 return Eng.getBugReporter(); 87 } 88 89 SourceManager &getSourceManager() { 90 return getBugReporter().getSourceManager(); 91 } 92 93 SValBuilder &getSValBuilder() { 94 return Eng.getSValBuilder(); 95 } 96 97 SymbolManager &getSymbolManager() { 98 return getSValBuilder().getSymbolManager(); 99 } 100 101 bool isObjCGCEnabled() { 102 return Eng.isObjCGCEnabled(); 103 } 104 105 /// \brief Generate a default checker node (containing checker tag but no 106 /// checker state changes). 107 ExplodedNode *generateNode(bool autoTransition = true) { 108 return generateNode(getState(), autoTransition); 109 } 110 111 /// \brief Generate a new checker node with the given predecessor. 112 /// Allows checkers to generate a chain of nodes. 113 ExplodedNode *generateNode(const ProgramState *state, 114 ExplodedNode *pred, 115 const ProgramPointTag *tag = 0, 116 bool autoTransition = true, 117 bool isSink = false) { 118 ExplodedNode *N = generateNodeImpl(state, isSink, pred, tag); 119 return N; 120 } 121 122 /// \brief Generate a new checker node. 123 ExplodedNode *generateNode(const ProgramState *state, 124 bool autoTransition = true, 125 const ProgramPointTag *tag = 0) { 126 ExplodedNode *N = generateNodeImpl(state, false, 0, tag); 127 return N; 128 } 129 130 /// \brief Generate a sink node. Generating sink stops exploration of the 131 /// given path. 132 ExplodedNode *generateSink(const ProgramState *state = 0) { 133 return generateNodeImpl(state ? state : getState(), true); 134 } 135 136 void addTransition(const ProgramState *state, 137 const ProgramPointTag *tag = 0) { 138 assert(state); 139 // If the 'state' is not new, we need to check if the cached state 'ST' 140 // is new. 141 if (state != getState()) 142 generateNode(state, true, tag); 143 } 144 145 void EmitReport(BugReport *R) { 146 Eng.getBugReporter().EmitReport(R); 147 } 148 149 AnalysisContext *getCurrentAnalysisContext() const { 150 return Pred->getLocationContext()->getAnalysisContext(); 151 } 152 153private: 154 ExplodedNode *generateNodeImpl(const ProgramState *state, 155 bool markAsSink, 156 ExplodedNode *pred = 0, 157 const ProgramPointTag *tag = 0) { 158 159 ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location, 160 state, 161 pred ? pred : Pred, markAsSink); 162 return node; 163 } 164}; 165 166} // end GR namespace 167 168} // end clang namespace 169 170#endif 171