CheckerContext.h revision 0bd6b110e908892d4b5c8671a9f435a1d72ad16a
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
141  /// \brief Emit a very simple diagnostic report. Should only be used for
142  ///        non-path sensitive checkers.
143  // TODO: We should not need it here!
144  void EmitBasicReport(StringRef Name,
145                       StringRef Category,
146                       StringRef Str, PathDiagnosticLocation Loc,
147                       SourceRange* RBeg, unsigned NumRanges) {
148    Eng.getBugReporter().EmitBasicReport(Name, Category, Str, Loc,
149                                         RBeg, NumRanges);
150  }
151
152private:
153  ExplodedNode *addTransitionImpl(const ProgramState *state,
154                                 bool markAsSink,
155                                 ExplodedNode *pred = 0,
156                                 const ProgramPointTag *tag = 0) {
157    assert(state);
158    ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location,
159                                        state,
160                                        pred ? pred : Pred, markAsSink);
161    return node;
162  }
163};
164
165} // end GR namespace
166
167} // end clang namespace
168
169#endif
170