Static Analyzer Diagnostics: Move custom diagnostic visitors from BugReporterContext to BugReport.
One API change: I added BugReporter as an additional parameter to the BugReporterVisitor::VisitNode() method to allow visitors register other visitors with the report on the fly (while processing a node). This functionality is used by NilReceiverVisitor, which registers TrackNullOrUndefValue when the receiver is null.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138001 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 95303a0..6624b93 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -33,27 +33,6 @@
using namespace ento;
BugReporterVisitor::~BugReporterVisitor() {}
-BugReporterContext::~BugReporterContext() {
- for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I)
- if ((*I)->isOwnedByReporterContext()) delete *I;
-}
-
-void BugReporterContext::addVisitor(BugReporterVisitor* visitor) {
- if (!visitor)
- return;
-
- llvm::FoldingSetNodeID ID;
- visitor->Profile(ID);
- void *InsertPos;
-
- if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
- delete visitor;
- return;
- }
-
- CallbacksSet.InsertNode(visitor, InsertPos);
- Callbacks = F.add(visitor, Callbacks);
-}
//===----------------------------------------------------------------------===//
// Helper routines for walking the ExplodedGraph and fetching statements.
@@ -161,15 +140,15 @@
BugReport *r, NodeBackMap *Backmap,
PathDiagnosticClient *pdc)
: BugReporterContext(br),
- R(r), PDC(pdc), NMC(Backmap) {
- addVisitor(R);
- }
+ R(r), PDC(pdc), NMC(Backmap) {}
PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N);
PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os,
const ExplodedNode *N);
+ BugReport *getBugReport() { return R; }
+
Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
ParentMap& getParentMap() { return R->getErrorNode()->getParentMap(); }
@@ -791,9 +770,11 @@
}
if (NextNode) {
- for (BugReporterContext::visitor_iterator I = PDB.visitor_begin(),
- E = PDB.visitor_end(); I!=E; ++I) {
- if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB))
+ // Add diagnostic pieces from custom visitors.
+ BugReport *R = PDB.getBugReport();
+ for (BugReport::visitor_iterator I = R->visitor_begin(),
+ E = R->visitor_end(); I!=E; ++I) {
+ if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R))
PD.push_front(p);
}
}
@@ -1198,9 +1179,11 @@
if (!NextNode)
continue;
- for (BugReporterContext::visitor_iterator I = PDB.visitor_begin(),
- E = PDB.visitor_end(); I!=E; ++I) {
- if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB)) {
+ // Add pieces from custom visitors.
+ BugReport *R = PDB.getBugReport();
+ for (BugReport::visitor_iterator I = R->visitor_begin(),
+ E = R->visitor_end(); I!=E; ++I) {
+ if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
const PathDiagnosticLocation &Loc = p->getLocation();
EB.addEdge(Loc, true);
PD.push_front(p);
@@ -1222,7 +1205,30 @@
// Methods for BugReport and subclasses.
//===----------------------------------------------------------------------===//
-BugReport::~BugReport() {}
+void BugReport::addVisitor(BugReporterVisitor* visitor) {
+ if (!visitor)
+ return;
+
+ llvm::FoldingSetNodeID ID;
+ visitor->Profile(ID);
+ void *InsertPos;
+
+ if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
+ delete visitor;
+ return;
+ }
+
+ CallbacksSet.InsertNode(visitor, InsertPos);
+ Callbacks = F.add(visitor, Callbacks);
+}
+
+BugReport::~BugReport() {
+ for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
+ // TODO: Remove the isOwned method; use reference counting to track visitors?.
+ assert((*I)->isOwnedByReporterContext());
+ delete *I;
+ }
+}
void BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
hash.AddPointer(&BT);
@@ -1336,7 +1342,8 @@
PathDiagnosticPiece *BugReport::VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,
- BugReporterContext &BRC) {
+ BugReporterContext &BRC,
+ BugReport &BR) {
return NULL;
}
@@ -1655,10 +1662,9 @@
else
return;
- // Register node visitors.
- R->registerInitialVisitors(PDB, N);
- bugreporter::registerNilReceiverVisitor(PDB);
- bugreporter::registerConditionVisitor(PDB);
+ // Register additional node visitors.
+ bugreporter::registerNilReceiverVisitor(*R);
+ bugreporter::registerConditionVisitor(*R);
switch (PDB.getGenerationScheme()) {
case PathDiagnosticClient::Extensive: