CheckerContext.h revision 48468dfeb3ccf099ed51ff5dcb8ae0fe783692fd
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/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 19 20namespace clang { 21namespace ento { 22 23class CheckerContext { 24 ExprEngine &Eng; 25 ExplodedNode *Pred; 26 const ProgramPoint Location; 27 NodeBuilder &NB; 28 29public: 30 CheckerContext(NodeBuilder &builder, 31 ExprEngine &eng, 32 ExplodedNode *pred, 33 const ProgramPoint &loc) 34 : Eng(eng), 35 Pred(pred), 36 Location(loc), 37 NB(builder) {} 38 39 ~CheckerContext(); 40 41 AnalysisManager &getAnalysisManager() { 42 return Eng.getAnalysisManager(); 43 } 44 45 ConstraintManager &getConstraintManager() { 46 return Eng.getConstraintManager(); 47 } 48 49 StoreManager &getStoreManager() { 50 return Eng.getStoreManager(); 51 } 52 53 ExplodedNode *&getPredecessor() { return Pred; } 54 const ProgramState *getState() { return Pred->getState(); } 55 56 /// \brief Returns the number of times the current block has been visited 57 /// along the analyzed path. 58 unsigned getCurrentBlockCount() { 59 return NB.getContext().getCurrentBlockCount(); 60 } 61 62 ASTContext &getASTContext() { 63 return Eng.getContext(); 64 } 65 66 BugReporter &getBugReporter() { 67 return Eng.getBugReporter(); 68 } 69 70 SourceManager &getSourceManager() { 71 return getBugReporter().getSourceManager(); 72 } 73 74 SValBuilder &getSValBuilder() { 75 return Eng.getSValBuilder(); 76 } 77 78 SymbolManager &getSymbolManager() { 79 return getSValBuilder().getSymbolManager(); 80 } 81 82 bool isObjCGCEnabled() { 83 return Eng.isObjCGCEnabled(); 84 } 85 86 ProgramStateManager &getStateManager() { 87 return Eng.getStateManager(); 88 } 89 90 AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 91 return Pred->getLocationContext()->getAnalysisDeclContext(); 92 } 93 94 /// \brief Generates a new transition in the program state graph 95 /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 96 /// 97 /// @param State The state of the generated node. 98 /// @param Tag The tag is used to uniquely identify the creation site. If no 99 /// tag is specified, a default tag, unique to the given checker, 100 /// will be used. Tags are used to prevent states generated at 101 /// different sites from caching out. 102 ExplodedNode *addTransition(const ProgramState *State, 103 const ProgramPointTag *Tag = 0) { 104 return addTransitionImpl(State, false, 0, Tag); 105 } 106 107 /// \brief Generates a default transition (containing checker tag but no 108 /// checker state changes). 109 // TODO: Can we remove this one? We always generate autotransitions. 110 ExplodedNode *addTransition() { 111 return addTransition(getState()); 112 } 113 114 /// \brief Generates a new transition with the given predecessor. 115 /// Allows checkers to generate a chain of nodes. 116 /// 117 /// @param State The state of the generated node. 118 /// @param Pred The transition will be generated from the specified Pred node 119 /// to the newly generated node. 120 /// @param Tag The tag to uniquely identify the creation site. 121 /// @param IsSink Mark the new node as sink, which will stop exploration of 122 /// the given path. 123 ExplodedNode *addTransition(const ProgramState *State, 124 ExplodedNode *Pred, 125 const ProgramPointTag *Tag = 0, 126 bool IsSink = false) { 127 return addTransitionImpl(State, IsSink, Pred, Tag); 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 addTransitionImpl(state ? state : getState(), true); 134 } 135 136 /// \brief Emit the diagnostics report. 137 void EmitReport(BugReport *R) { 138 Eng.getBugReporter().EmitReport(R); 139 } 140 141private: 142 ExplodedNode *addTransitionImpl(const ProgramState *state, 143 bool markAsSink, 144 ExplodedNode *pred = 0, 145 const ProgramPointTag *tag = 0) { 146 assert(state); 147 ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location, 148 state, 149 pred ? pred : Pred, markAsSink); 150 return node; 151 } 152}; 153 154} // end GR namespace 155 156} // end clang namespace 157 158#endif 159