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