CheckerContext.h revision 2e9264a17bacc7dc228d5f93caaeb98dfb23d508
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//== CheckerContext.h - Context info for path-sensitive checkers--*- C++ -*--=// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines CheckerContext that provides contextual info for 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// path-sensitive checkers. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_CLANG_SA_CORE_PATHSENSITIVE_CHECKERCONTEXT 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace clang { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ento { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CheckerContext { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprEngine &Eng; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExplodedNode *Pred; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgramPoint Location; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgramState *ST; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NodeBuilder &NB; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool *respondsToCallback; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckerContext(NodeBuilder &builder, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExprEngine &eng, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExplodedNode *pred, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgramPoint &loc, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool *respondsToCB = 0, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ProgramState *st = 0) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Eng(eng), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pred(pred), 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Location(loc), 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ST(st), 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NB(builder), 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) respondsToCallback(respondsToCB) { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) assert(!(ST && ST != Pred->getState())); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~CheckerContext(); 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExprEngine &getEngine() { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Eng; 51 } 52 53 AnalysisManager &getAnalysisManager() { 54 return Eng.getAnalysisManager(); 55 } 56 57 ConstraintManager &getConstraintManager() { 58 return Eng.getConstraintManager(); 59 } 60 61 StoreManager &getStoreManager() { 62 return Eng.getStoreManager(); 63 } 64 65 ExplodedNode *&getPredecessor() { return Pred; } 66 const ProgramState *getState() { return ST ? ST : Pred->getState(); } 67 68 /// \brief Returns the number of times the current block has been visited 69 /// along the analyzed path. 70 unsigned getCurrentBlockCount() { 71 return NB.getContext().getCurrentBlockCount(); 72 } 73 74 ASTContext &getASTContext() { 75 return Eng.getContext(); 76 } 77 78 BugReporter &getBugReporter() { 79 return Eng.getBugReporter(); 80 } 81 82 SourceManager &getSourceManager() { 83 return getBugReporter().getSourceManager(); 84 } 85 86 SValBuilder &getSValBuilder() { 87 return Eng.getSValBuilder(); 88 } 89 90 SymbolManager &getSymbolManager() { 91 return getSValBuilder().getSymbolManager(); 92 } 93 94 bool isObjCGCEnabled() { 95 return Eng.isObjCGCEnabled(); 96 } 97 98 /// \brief Generate a default checker node (containing checker tag but no 99 /// checker state changes). 100 ExplodedNode *generateNode(bool autoTransition = true) { 101 return generateNode(getState(), autoTransition); 102 } 103 104 /// \brief Generate a new checker node with the given predecessor. 105 /// Allows checkers to generate a chain of nodes. 106 ExplodedNode *generateNode(const ProgramState *state, 107 ExplodedNode *pred, 108 const ProgramPointTag *tag = 0, 109 bool autoTransition = true, 110 bool isSink = false) { 111 ExplodedNode *N = generateNodeImpl(state, isSink, pred, tag); 112 return N; 113 } 114 115 /// \brief Generate a new checker node. 116 ExplodedNode *generateNode(const ProgramState *state, 117 bool autoTransition = true, 118 const ProgramPointTag *tag = 0) { 119 ExplodedNode *N = generateNodeImpl(state, false, 0, tag); 120 return N; 121 } 122 123 /// \brief Generate a sink node. Generating sink stops exploration of the 124 /// given path. 125 ExplodedNode *generateSink(const ProgramState *state = 0) { 126 return generateNodeImpl(state ? state : getState(), true); 127 } 128 129 void addTransition(const ProgramState *state, 130 const ProgramPointTag *tag = 0) { 131 assert(state); 132 // If the 'state' is not new, we need to check if the cached state 'ST' 133 // is new. 134 if (state != getState()) 135 generateNode(state, true, tag); 136 } 137 138 void EmitReport(BugReport *R) { 139 Eng.getBugReporter().EmitReport(R); 140 } 141 142 AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 143 return Pred->getLocationContext()->getAnalysisDeclContext(); 144 } 145 146private: 147 ExplodedNode *generateNodeImpl(const ProgramState *state, 148 bool markAsSink, 149 ExplodedNode *pred = 0, 150 const ProgramPointTag *tag = 0) { 151 ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location, 152 state, 153 pred ? pred : Pred, markAsSink); 154 return node; 155 } 156}; 157 158} // end GR namespace 159 160} // end clang namespace 161 162#endif 163