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