aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis/PathSensitive/BugReporter.h
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-05-06 21:39:49 +0000
committerTed Kremenek <kremenek@apple.com>2009-05-06 21:39:49 +0000
commit8966bc1c8ce271c09936c0eaf6c841aef4a0af1b (patch)
treebd37bd8c186718edf20db216c0fec201bfb0f4ba /include/clang/Analysis/PathSensitive/BugReporter.h
parent1c4483065b52383bb8e501e3a1e7c4f5628921cb (diff)
Refactor BugReporter interface to have a new 'BugReporterContext' and
'BugReporterVisitor'. This simplifies callbacks from BugReporter to BugReports (via VisitNode). It also lays the foundation for arbitrary visitor "call backs" that can be registered to a BugReporterContext as a PathDiagnostic is constructed. These call backs can help operate as separate "experts" that can work on constructed pieces of a PathDiagnostic for which they possess special knowledge. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71121 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/PathSensitive/BugReporter.h')
-rw-r--r--include/clang/Analysis/PathSensitive/BugReporter.h83
1 files changed, 77 insertions, 6 deletions
diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h
index f941a7a570..99cbfd844b 100644
--- a/include/clang/Analysis/PathSensitive/BugReporter.h
+++ b/include/clang/Analysis/PathSensitive/BugReporter.h
@@ -34,6 +34,7 @@ class PathDiagnosticClient;
class ASTContext;
class Diagnostic;
class BugReporter;
+class BugReporterContext;
class GRExprEngine;
class GRState;
class Stmt;
@@ -43,9 +44,19 @@ class ParentMap;
//===----------------------------------------------------------------------===//
// Interface for individual bug reports.
//===----------------------------------------------------------------------===//
+
+class BugReporterVisitor {
+public:
+ virtual ~BugReporterVisitor();
+ virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
+ const ExplodedNode<GRState>* PrevN,
+ BugReporterContext& BR) = 0;
+
+ virtual bool isOwnedByReporterContext() { return true; }
+};
// FIXME: Combine this with RangedBugReport and remove RangedBugReport.
-class BugReport {
+class BugReport : public BugReporterVisitor {
protected:
BugType& BT;
std::string ShortDescription;
@@ -76,8 +87,9 @@ public:
const ExplodedNode<GRState> *n)
: BT(bt), ShortDescription(shortDesc), Description(desc), EndNode(n) {}
-
virtual ~BugReport();
+
+ virtual bool isOwnedByReporterContext() { return false; }
const BugType& getBugType() const { return BT; }
BugType& getBugType() { return BT; }
@@ -87,6 +99,8 @@ public:
// FIXME: Do we need this? Maybe getLocation() should return a ProgramPoint
// object.
+ // FIXME: If we do need it, we can probably just make it private to
+ // BugReporter.
Stmt* getStmt(BugReporter& BR) const;
const std::string& getDescription() const { return Description; }
@@ -101,7 +115,7 @@ public:
}
// FIXME: Perhaps move this into a subclass.
- virtual PathDiagnosticPiece* getEndPath(BugReporter& BR,
+ virtual PathDiagnosticPiece* getEndPath(BugReporterContext& BR,
const ExplodedNode<GRState>* N);
/// getLocation - Return the "definitive" location of the reported bug.
@@ -114,12 +128,17 @@ public:
virtual void getRanges(BugReporter& BR,const SourceRange*& beg,
const SourceRange*& end);
- // FIXME: Perhaps this should be moved into a subclass?
+ virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
+ const ExplodedNode<GRState>* PrevN,
+ BugReporterContext& BR);
+
+ /*
virtual PathDiagnosticPiece* VisitNode(const ExplodedNode<GRState>* N,
const ExplodedNode<GRState>* PrevN,
const ExplodedGraph<GRState>& G,
- BugReporter& BR,
+ BugReporterContext& BR,
NodeResolver& NR);
+ */
};
//===----------------------------------------------------------------------===//
@@ -332,7 +351,7 @@ public:
static bool classof(const BugReporter* R) { return true; }
};
-
+
// FIXME: Get rid of GRBugReporter. It's the wrong abstraction.
class GRBugReporter : public BugReporter {
GRExprEngine& Eng;
@@ -371,6 +390,58 @@ public:
return R->getKind() == GRBugReporterKind;
}
};
+
+class BugReporterContext {
+ GRBugReporter &BR;
+ std::vector<BugReporterVisitor*> Callbacks;
+public:
+ BugReporterContext(GRBugReporter& br) : BR(br) {}
+ virtual ~BugReporterContext();
+
+ void addVisitor(BugReporterVisitor* visitor) {
+ if (visitor) Callbacks.push_back(visitor);
+ }
+
+ typedef std::vector<BugReporterVisitor*>::iterator visitor_iterator;
+ visitor_iterator visitor_begin() { return Callbacks.begin(); }
+ visitor_iterator visitor_end() { return Callbacks.end(); }
+
+ GRBugReporter& getBugReporter() { return BR; }
+
+ ExplodedGraph<GRState>& getGraph() { return BR.getGraph(); }
+
+ void addNotableSymbol(SymbolRef Sym) {
+ // FIXME: For now forward to GRBugReporter.
+ BR.addNotableSymbol(Sym);
+ }
+
+ bool isNotable(SymbolRef Sym) const {
+ // FIXME: For now forward to GRBugReporter.
+ return BR.isNotable(Sym);
+ }
+
+ GRStateManager& getStateManager() {
+ return BR.getStateManager();
+ }
+
+ ASTContext& getASTContext() {
+ return BR.getContext();
+ }
+
+ SourceManager& getSourceManager() {
+ return BR.getSourceManager();
+ }
+
+ const Decl& getCodeDecl() {
+ return getStateManager().getCodeDecl();
+ }
+
+ const CFG& getCFG() {
+ return *BR.getCFG();
+ }
+
+ virtual BugReport::NodeResolver& getNodeResolver() = 0;
+};
class DiagBugReport : public RangedBugReport {
std::list<std::string> Strs;