CheckerContext.h revision c9003c89c7aead1686aba89c8e3ddcea1f2bec54
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 ExprEngine &Eng; 28 ExplodedNode *Pred; 29 const ProgramPoint Location; 30 const ProgramState *ST; 31 const unsigned size; 32 // TODO: Use global context. 33 NodeBuilderContext Ctx; 34 NodeBuilder &NB; 35public: 36 bool *respondsToCallback; 37public: 38 CheckerContext(ExplodedNodeSet &dst, 39 NodeBuilder &builder, 40 ExprEngine &eng, 41 ExplodedNode *pred, 42 const ProgramPoint &loc, 43 bool *respondsToCB = 0, 44 const ProgramState *st = 0) 45 : Dst(dst), 46 Eng(eng), 47 Pred(pred), 48 Location(loc), 49 ST(st), 50 size(Dst.size()), 51 Ctx(builder.C.Eng, builder.getBlock(), pred), 52 NB(builder), 53 respondsToCallback(respondsToCB) { 54 assert(!(ST && ST != Pred->getState())); 55 } 56 57 ~CheckerContext(); 58 59 ExprEngine &getEngine() { 60 return Eng; 61 } 62 63 AnalysisManager &getAnalysisManager() { 64 return Eng.getAnalysisManager(); 65 } 66 67 ConstraintManager &getConstraintManager() { 68 return Eng.getConstraintManager(); 69 } 70 71 StoreManager &getStoreManager() { 72 return Eng.getStoreManager(); 73 } 74 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 NB.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 bool isSink = false) { 119 ExplodedNode *N = generateNodeImpl(state, isSink, pred, tag); 120 return N; 121 } 122 123 /// \brief Generate a new checker node. 124 ExplodedNode *generateNode(const ProgramState *state, 125 bool autoTransition = true, 126 const ProgramPointTag *tag = 0) { 127 ExplodedNode *N = generateNodeImpl(state, false, 0, tag); 128 return N; 129 } 130 131 /// \brief Generate a sink node. Generating sink stops exploration of the 132 /// given path. 133 ExplodedNode *generateSink(const ProgramState *state = 0) { 134 return generateNodeImpl(state ? state : getState(), true); 135 } 136 137 void addTransition(const ProgramState *state, 138 const ProgramPointTag *tag = 0) { 139 assert(state); 140 // If the 'state' is not new, we need to check if the cached state 'ST' 141 // is new. 142 if (state != getState()) 143 generateNode(state, true, tag); 144 } 145 146 void EmitReport(BugReport *R) { 147 Eng.getBugReporter().EmitReport(R); 148 } 149 150 AnalysisContext *getCurrentAnalysisContext() const { 151 return Pred->getLocationContext()->getAnalysisContext(); 152 } 153 154private: 155 ExplodedNode *generateNodeImpl(const ProgramState *state, 156 bool markAsSink, 157 ExplodedNode *pred = 0, 158 const ProgramPointTag *tag = 0) { 159 160 ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location, 161 state, 162 pred ? pred : Pred, markAsSink); 163 return node; 164 } 165}; 166 167} // end GR namespace 168 169} // end clang namespace 170 171#endif 172