Added new "BugReporterHelper" class which is used by BugReporter to emit

checker-specific diagnostics.

llvm-svn: 49412
This commit is contained in:
Ted Kremenek 2008-04-09 00:20:43 +00:00
parent b859fb49ed
commit 3cef454e2e
2 changed files with 40 additions and 10 deletions

View File

@ -46,6 +46,16 @@ public:
const SourceRange*& end) const;
};
class BugReporterHelper {
public:
virtual ~BugReporterHelper() {}
virtual PathDiagnosticPiece* VisitNode(ExplodedNode<ValueState>* N,
ExplodedNode<ValueState>* PrevN,
ExplodedGraph<GRExprEngine>& G,
ASTContext& Ctx) = 0;
};
class BugReporter {
llvm::SmallPtrSet<void*,10> CachedErrors;
@ -56,7 +66,9 @@ public:
void EmitPathWarning(Diagnostic& Diag, PathDiagnosticClient* PDC,
ASTContext& Ctx, const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
ExplodedNode<ValueState>* N);
ExplodedNode<ValueState>* 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<GRExprEngine>& G,
ExplodedNode<ValueState>* N);
ExplodedNode<ValueState>* N,
BugReporterHelper** BegHelpers = NULL,
BugReporterHelper** EndHelpers = NULL);
};
} // end clang namespace

View File

@ -83,7 +83,9 @@ void BugDescription::getRanges(const SourceRange*& beg,
void BugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, ASTContext& Ctx,
const BugDescription& B,
ExplodedGraph<GRExprEngine>& G,
ExplodedNode<ValueState>* N) {
ExplodedNode<ValueState>* 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<ValueState>* NextNode = N->pred_empty()
? NULL : *(N->pred_begin());
while (NextNode) {
ExplodedNode<ValueState>* 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<GRExprEngine>& G,
ExplodedNode<ValueState>* N) {
ExplodedNode<ValueState>* 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);