CheckerContext.h revision 6a93bd526c5136ee5a26871e829cf5a8548a1c6a
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
91  AnalysisDeclContext *getCurrentAnalysisDeclContext() const {
92    return Pred->getLocationContext()->getAnalysisDeclContext();
93  }
94
95  /// \brief Generate a default checker node (containing checker tag but no
96  /// checker state changes).
97  ExplodedNode *generateNode() {
98    return generateNode(getState());
99  }
100
101  /// \brief Generate a new checker node.
102  ExplodedNode *generateNode(const ProgramState *state,
103                             const ProgramPointTag *tag = 0) {
104    return generateNodeImpl(state, false, 0, tag);
105  }
106
107  /// \brief Generate a new checker node with the given predecessor.
108  /// Allows checkers to generate a chain of nodes.
109  ExplodedNode *generateNode(const ProgramState *state,
110                             ExplodedNode *pred,
111                             const ProgramPointTag *tag = 0,
112                             bool isSink = false) {
113    return generateNodeImpl(state, isSink, pred, tag);
114  }
115
116  /// \brief Generate a sink node. Generating sink stops exploration of the
117  /// given path.
118  ExplodedNode *generateSink(const ProgramState *state = 0) {
119    return generateNodeImpl(state ? state : getState(), true);
120  }
121
122  /// \brief Emit the diagnostics report.
123  void EmitReport(BugReport *R) {
124    Eng.getBugReporter().EmitReport(R);
125  }
126
127  void EmitBasicReport(StringRef Name,
128                       StringRef Category,
129                       StringRef Str, PathDiagnosticLocation Loc,
130                       SourceRange* RBeg, unsigned NumRanges) {
131    Eng.getBugReporter().EmitBasicReport(Name, Category, Str, Loc,
132                                         RBeg, NumRanges);
133  }
134
135private:
136  ExplodedNode *generateNodeImpl(const ProgramState *state,
137                                 bool markAsSink,
138                                 ExplodedNode *pred = 0,
139                                 const ProgramPointTag *tag = 0) {
140    assert(state);
141    ExplodedNode *node = NB.generateNode(tag ? Location.withTag(tag) : Location,
142                                        state,
143                                        pred ? pred : Pred, markAsSink);
144    return node;
145  }
146};
147
148} // end GR namespace
149
150} // end clang namespace
151
152#endif
153