From 3cef454e2ebaf02f55639ad43601cc073fc5306d Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 9 Apr 2008 00:20:43 +0000 Subject: [PATCH] Added new "BugReporterHelper" class which is used by BugReporter to emit checker-specific diagnostics. llvm-svn: 49412 --- .../Analysis/PathSensitive/BugReporter.h | 18 +++++++++-- clang/lib/Analysis/BugReporter.cpp | 32 ++++++++++++++----- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h index a5af32719514..7ff79fc53d87 100644 --- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/clang/include/clang/Analysis/PathSensitive/BugReporter.h @@ -46,6 +46,16 @@ public: const SourceRange*& end) const; }; +class BugReporterHelper { +public: + virtual ~BugReporterHelper() {} + + virtual PathDiagnosticPiece* VisitNode(ExplodedNode* N, + ExplodedNode* PrevN, + ExplodedGraph& G, + ASTContext& Ctx) = 0; +}; + class BugReporter { llvm::SmallPtrSet CachedErrors; @@ -56,7 +66,9 @@ public: void EmitPathWarning(Diagnostic& Diag, PathDiagnosticClient* PDC, ASTContext& Ctx, const BugDescription& B, ExplodedGraph& G, - ExplodedNode* N); + ExplodedNode* N, + BugReporterHelper** BegHelpers = NULL, + BugReporterHelper** EndHelpers = NULL); void EmitWarning(Diagnostic& Diag, ASTContext& Ctx, const BugDescription& B, @@ -69,7 +81,9 @@ private: void GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, const BugDescription& B, ExplodedGraph& G, - ExplodedNode* N); + ExplodedNode* N, + BugReporterHelper** BegHelpers = NULL, + BugReporterHelper** EndHelpers = NULL); }; } // end clang namespace diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 14f98fa1f4af..66b1b04c9d0f 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -83,7 +83,9 @@ void BugDescription::getRanges(const SourceRange*& beg, void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, const BugDescription& B, ExplodedGraph& G, - ExplodedNode* N) { + ExplodedNode* N, + BugReporterHelper** BegHelpers, + BugReporterHelper** EndHelpers) { if (PathDiagnosticPiece* Piece = B.getEndPath(Ctx,N)) PD.push_back(Piece); @@ -112,11 +114,15 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, assert (NewN->getLocation() == N->getLocation()); N = NewN; - - while (!N->pred_empty()) { + + ExplodedNode* NextNode = N->pred_empty() + ? NULL : *(N->pred_begin()); + + while (NextNode) { ExplodedNode* LastNode = N; - N = *(N->pred_begin()); + N = NextNode; + NextNode = N->pred_empty() ? NULL : *(N->pred_begin()); ProgramPoint P = N->getLocation(); @@ -171,7 +177,7 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, case Stmt::DefaultStmtClass: { os << "Control jumps to the 'default' case at line " - << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n"; + << SMgr.getLogicalLineNumber(S->getLocStart()) << ".\n"; break; } @@ -284,7 +290,15 @@ void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx, break; } } - } + } + else + for (BugReporterHelper** I = BegHelpers; I != EndHelpers; ++I) { + + PathDiagnosticPiece* piece = (*I)->VisitNode(N, NextNode, G, Ctx); + + if (piece) + PD.push_front(piece); + } } } @@ -309,7 +323,9 @@ void BugReporter::EmitPathWarning(Diagnostic& Diag, ASTContext& Ctx, const BugDescription& B, ExplodedGraph& G, - ExplodedNode* N) { + ExplodedNode* N, + BugReporterHelper** BegHelpers, + BugReporterHelper** EndHelpers) { if (!PDC) { EmitWarning(Diag, Ctx, B, N); @@ -320,7 +336,7 @@ void BugReporter::EmitPathWarning(Diagnostic& Diag, return; PathDiagnostic D(B.getName()); - GeneratePathDiagnostic(D, Ctx, B, G, N); + GeneratePathDiagnostic(D, Ctx, B, G, N, BegHelpers, EndHelpers); if (!D.empty()) PDC->HandlePathDiagnostic(D);