CheckerContext.h revision b805c8ff133ef0c62df032fa711d6b13c5afd7f4
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  AnalysisManager &getAnalysisManager() {
40    return Eng.getAnalysisManager();
41  }
42
43  ConstraintManager &getConstraintManager() {
44    return Eng.getConstraintManager();
45  }
46
47  StoreManager &getStoreManager() {
48    return Eng.getStoreManager();
49  }
50
51  /// \brief Returns the previous node in the exploded graph, which includes
52  /// the state of the program before the checker ran. Note, checkers should
53  /// not retain the node in their state since the nodes might get invalidated.
54  ExplodedNode *getPredecessor() { return Pred; }
55  const ProgramState *getState() const { return Pred->getState(); }
56
57  /// \brief Returns the number of times the current block has been visited
58  /// along the analyzed path.
59  unsigned getCurrentBlockCount() const {
60    return NB.getContext().getCurrentBlockCount();
61  }
62
63  ASTContext &getASTContext() {
64    return Eng.getContext();
65  }
66
67  const LocationContext *getLocationContext() const {
68    return Pred->getLocationContext();
69  }
70
71  BugReporter &getBugReporter() {
72    return Eng.getBugReporter();
73  }
74
75  SourceManager &getSourceManager() {
76    return getBugReporter().getSourceManager();
77  }
78
79  SValBuilder &getSValBuilder() {
80    return Eng.getSValBuilder();
81  }
82
83  SymbolManager &getSymbolManager() {
84    return getSValBuilder().getSymbolManager();
85  }
86
87  bool isObjCGCEnabled() const {
88    return Eng.isObjCGCEnabled();
89  }
90
91  ProgramStateManager &getStateManager() {
92    return Eng.getStateManager();
93  }
94
95  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
96    return Pred->getLocationContext()->getAnalysisDeclContext();
97  }
98
99  /// \brief Generates a new transition in the program state graph
100  /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
101  ///
102  /// @param State The state of the generated node.
103  /// @param Tag The tag is used to uniquely identify the creation site. If no
104  ///        tag is specified, a default tag, unique to the given checker,
105  ///        will be used. Tags are used to prevent states generated at
106  ///        different sites from caching out.
107  ExplodedNode *addTransition(const ProgramState *State,
108                              const ProgramPointTag *Tag = 0) {
109    return addTransitionImpl(State, false, 0, Tag);
110  }
111
112  /// \brief Generates a default transition (containing checker tag but no
113  /// checker state changes).
114  ExplodedNode *addTransition() {
115    return addTransition(getState());
116  }
117
118  /// \brief Generates a new transition with the given predecessor.
119  /// Allows checkers to generate a chain of nodes.
120  ///
121  /// @param State The state of the generated node.
122  /// @param Pred The transition will be generated from the specified Pred node
123  ///             to the newly generated node.
124  /// @param Tag The tag to uniquely identify the creation site.
125  /// @param IsSink Mark the new node as sink, which will stop exploration of
126  ///               the given path.
127  ExplodedNode *addTransition(const ProgramState *State,
128                             ExplodedNode *Pred,
129                             const ProgramPointTag *Tag = 0,
130                             bool IsSink = false) {
131    return addTransitionImpl(State, IsSink, Pred, Tag);
132  }
133
134  /// \brief Generate a sink node. Generating sink stops exploration of the
135  /// given path.
136  ExplodedNode *generateSink(const ProgramState *state = 0) {
137    return addTransitionImpl(state ? state : getState(), true);
138  }
139
140  /// \brief Emit the diagnostics report.
141  void EmitReport(BugReport *R) {
142    Eng.getBugReporter().EmitReport(R);
143  }
144
145  /// \brief Get the declaration of the called function (path-sensitive).
146  const FunctionDecl *getCalleeDecl(const CallExpr *CE) const;
147
148  /// \brief Get the name of the called function (path-sensitive).
149  StringRef getCalleeName(const CallExpr *CE) const;
150
151private:
152  ExplodedNode *addTransitionImpl(const ProgramState *State,
153                                 bool MarkAsSink,
154                                 ExplodedNode *P = 0,
155                                 const ProgramPointTag *Tag = 0) {
156    assert(State);
157    if (State == Pred->getState() && !Tag && !MarkAsSink)
158      return Pred;
159
160    ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location,
161                                        State,
162                                        P ? P : Pred, MarkAsSink);
163    return node;
164  }
165};
166
167} // end GR namespace
168
169} // end clang namespace
170
171#endif
172