CheckerContext.h revision df95d146c13cf02e106b32b01d147577d6d6b5a1
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 const LocationContext *getLocationContext() { 67 return Pred->getLocationContext(); 68 } 69 70 BugReporter &getBugReporter() { 71 return Eng.getBugReporter(); 72 } 73 74 SourceManager &getSourceManager() { 75 return getBugReporter().getSourceManager(); 76 } 77 78 SValBuilder &getSValBuilder() { 79 return Eng.getSValBuilder(); 80 } 81 82 SymbolManager &getSymbolManager() { 83 return getSValBuilder().getSymbolManager(); 84 } 85 86 bool isObjCGCEnabled() { 87 return Eng.isObjCGCEnabled(); 88 } 89 90 ProgramStateManager &getStateManager() { 91 return Eng.getStateManager(); 92 } 93 94 AnalysisDeclContext *getCurrentAnalysisDeclContext() const { 95 return Pred->getLocationContext()->getAnalysisDeclContext(); 96 } 97 98 /// \brief Generates a new transition in the program state graph 99 /// (ExplodedGraph). Uses the default CheckerContext predecessor node. 100 /// 101 /// @param State The state of the generated node. 102 /// @param Tag The tag is used to uniquely identify the creation site. If no 103 /// tag is specified, a default tag, unique to the given checker, 104 /// will be used. Tags are used to prevent states generated at 105 /// different sites from caching out. 106 ExplodedNode *addTransition(const ProgramState *State, 107 const ProgramPointTag *Tag = 0) { 108 return addTransitionImpl(State, false, 0, Tag); 109 } 110 111 /// \brief Generates a default transition (containing checker tag but no 112 /// checker state changes). 113 ExplodedNode *addTransition() { 114 return addTransition(getState()); 115 } 116 117 /// \brief Generates a new transition with the given predecessor. 118 /// Allows checkers to generate a chain of nodes. 119 /// 120 /// @param State The state of the generated node. 121 /// @param Pred The transition will be generated from the specified Pred node 122 /// to the newly generated node. 123 /// @param Tag The tag to uniquely identify the creation site. 124 /// @param IsSink Mark the new node as sink, which will stop exploration of 125 /// the given path. 126 ExplodedNode *addTransition(const ProgramState *State, 127 ExplodedNode *Pred, 128 const ProgramPointTag *Tag = 0, 129 bool IsSink = false) { 130 return addTransitionImpl(State, IsSink, Pred, Tag); 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 addTransitionImpl(state ? state : getState(), true); 137 } 138 139 /// \brief Emit the diagnostics report. 140 void EmitReport(BugReport *R) { 141 Eng.getBugReporter().EmitReport(R); 142 } 143 144private: 145 ExplodedNode *addTransitionImpl(const ProgramState *State, 146 bool MarkAsSink, 147 ExplodedNode *P = 0, 148 const ProgramPointTag *Tag = 0) { 149 assert(State); 150 if (State == Pred->getState() && !Tag && !MarkAsSink) 151 return Pred; 152 153 ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location, 154 State, 155 P ? P : Pred, MarkAsSink); 156 return node; 157 } 158}; 159 160} // end GR namespace 161 162} // end clang namespace 163 164#endif 165