diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-05-06 21:39:49 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-05-06 21:39:49 +0000 |
commit | 8966bc1c8ce271c09936c0eaf6c841aef4a0af1b (patch) | |
tree | bd37bd8c186718edf20db216c0fec201bfb0f4ba /include/clang/Analysis/PathSensitive/BugReporter.h | |
parent | 1c4483065b52383bb8e501e3a1e7c4f5628921cb (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.h | 83 |
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; |