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