BugReporter.h revision 072192bcbb05a0fee7ec3061750b27e8d2004952
1// BugReporter.h - Generate PathDiagnostics  ----------*- 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 BugReporter, a utility class for generating
11//  PathDiagnostics for analyses based on ValueState.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
16#define LLVM_CLANG_ANALYSIS_BUGREPORTER
17
18#include "clang/Basic/SourceLocation.h"
19#include "clang/Analysis/PathSensitive/ValueState.h"
20#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include <vector>
23
24namespace clang {
25
26class PathDiagnostic;
27class PathDiagnosticPiece;
28class PathDiagnosticClient;
29class ASTContext;
30class Diagnostic;
31class BugReporter;
32class GRExprEngine;
33class ValueState;
34class Stmt;
35class BugReport;
36
37class BugType {
38public:
39  BugType() {}
40  virtual ~BugType();
41
42  virtual const char* getName() const = 0;
43  virtual const char* getDescription() const { return getName(); }
44
45  virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
46    return std::pair<const char**, const char**>(0, 0);
47  }
48
49  virtual void EmitWarnings(BugReporter& BR) {}
50  virtual void GetErrorNodes(std::vector<ExplodedNode<ValueState>*>& Nodes) {}
51
52  virtual bool isCached(BugReport& R) = 0;
53};
54
55class BugTypeCacheLocation : public BugType {
56  llvm::SmallPtrSet<void*,10> CachedErrors;
57public:
58  BugTypeCacheLocation() {}
59  virtual ~BugTypeCacheLocation() {}
60  virtual bool isCached(BugReport& R);
61};
62
63
64class BugReport {
65  BugType& Desc;
66  ExplodedNode<ValueState> *N;
67
68public:
69  BugReport(BugType& D, ExplodedNode<ValueState> *n) : Desc(D), N(n) {}
70  virtual ~BugReport();
71
72  const BugType& getBugType() const { return Desc; }
73  BugType& getBugType() { return Desc; }
74
75  ExplodedNode<ValueState>* getEndNode() const { return N; }
76
77  Stmt* getStmt() const;
78
79  const char* getName() const { return getBugType().getName(); }
80
81  virtual const char* getDescription() const {
82    return getBugType().getDescription();
83  }
84
85  virtual std::pair<const char**,const char**> getExtraDescriptiveText() {
86    return getBugType().getExtraDescriptiveText();
87  }
88
89  virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
90                                          ExplodedNode<ValueState>* N) const;
91
92  virtual FullSourceLoc getLocation(SourceManager& Mgr);
93
94  virtual void getRanges(const SourceRange*& beg,
95                         const SourceRange*& end) const;
96
97  virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
98                                         ExplodedNode<ValueState>* PrevN,
99                                         ExplodedGraph<ValueState>& G,
100                                         BugReporter& BR);
101};
102
103class RangedBugReport : public BugReport {
104  std::vector<SourceRange> Ranges;
105public:
106  RangedBugReport(BugType& D, ExplodedNode<ValueState> *n)
107    : BugReport(D, n) {}
108
109  virtual ~RangedBugReport();
110
111  void addRange(SourceRange R) { Ranges.push_back(R); }
112
113  virtual void getRanges(const SourceRange*& beg,
114                         const SourceRange*& end) const {
115
116    if (Ranges.empty()) {
117      beg = NULL;
118      end = NULL;
119    }
120    else {
121      beg = &Ranges[0];
122      end = beg + Ranges.size();
123    }
124  }
125};
126
127class BugReporter {
128  Diagnostic& Diag;
129  PathDiagnosticClient* PD;
130  ASTContext& Ctx;
131  GRExprEngine& Eng;
132
133public:
134  BugReporter(Diagnostic& diag, PathDiagnosticClient* pd,
135              ASTContext& ctx, GRExprEngine& eng)
136  : Diag(diag), PD(pd), Ctx(ctx), Eng(eng) {}
137
138  ~BugReporter();
139
140  Diagnostic& getDiagnostic() { return Diag; }
141
142  PathDiagnosticClient* getDiagnosticClient() { return PD; }
143
144  ASTContext& getContext() { return Ctx; }
145
146  ExplodedGraph<ValueState>& getGraph();
147
148  GRExprEngine& getEngine() { return Eng; }
149
150  CFG& getCFG() { return getGraph().getCFG(); }
151
152  void EmitWarning(BugReport& R);
153
154  void GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R);
155};
156
157} // end clang namespace
158
159#endif
160