diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-11 16:50:36 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-11 16:50:36 +0000 |
commit | c6d64a26c28bbeee50e06c94c4f4c08e610327b7 (patch) | |
tree | bdaf1e7360cdd97c0e27d3a33062c902c42f3728 /lib | |
parent | 85663e7b40097b2f162f58ba9f4dae2d0f24f648 (diff) |
Emit -verify diagnostics even when we have a fatal error.
Previously we'd halt at the fatal error as expected, but not actually emit
any -verify-related diagnostics. This lets us catch cases that emit a
/different/ fatal error from the one we expected.
This is implemented by adding a "force emit" mode to DiagnosticBuilder, which
will cause diagnostics to immediately be emitted regardless of current
suppression. Needless to say this should probably be used /very/ sparingly.
Patch by Andy Gibbs! Tests for all of Andy's -verify patches coming soon.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160053 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/Diagnostic.cpp | 27 | ||||
-rw-r--r-- | lib/Basic/DiagnosticIDs.cpp | 31 | ||||
-rw-r--r-- | lib/Frontend/VerifyDiagnosticConsumer.cpp | 4 |
3 files changed, 35 insertions, 27 deletions
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index fdc37b63cb..6e79b85a99 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -382,17 +382,34 @@ void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { CurDiagID = ~0U; } -bool DiagnosticsEngine::EmitCurrentDiagnostic() { - // Process the diagnostic, sending the accumulated information to the - // DiagnosticConsumer. - bool Emitted = ProcessDiag(); +bool DiagnosticsEngine::EmitCurrentDiagnostic(bool Force) { + assert(getClient() && "DiagnosticClient not set!"); + + bool Emitted; + if (Force) { + Diagnostic Info(this); + + // Figure out the diagnostic level of this message. + DiagnosticIDs::Level DiagLevel + = Diags->getDiagnosticLevel(Info.getID(), Info.getLocation(), *this); + + Emitted = (DiagLevel != DiagnosticIDs::Ignored); + if (Emitted) { + // Emit the diagnostic regardless of suppression level. + Diags->EmitDiag(*this, DiagLevel); + } + } else { + // Process the diagnostic, sending the accumulated information to the + // DiagnosticConsumer. + Emitted = ProcessDiag(); + } // Clear out the current diagnostic object. unsigned DiagID = CurDiagID; Clear(); // If there was a delayed diagnostic, emit it now. - if (DelayedDiagID && DelayedDiagID != DiagID) + if (!Force && DelayedDiagID && DelayedDiagID != DiagID) ReportDelayed(); return Emitted; diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index 8c33a963c9..d00573fec5 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/lib/Basic/DiagnosticIDs.cpp @@ -357,7 +357,7 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, return CustomDiagInfo->getLevel(DiagID); unsigned DiagClass = getBuiltinDiagClass(DiagID); - assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!"); + if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note; return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag); } @@ -583,24 +583,9 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { assert(Diag.getClient() && "DiagnosticClient not set!"); // Figure out the diagnostic level of this message. - DiagnosticIDs::Level DiagLevel; unsigned DiagID = Info.getID(); - - if (DiagID >= diag::DIAG_UPPER_LIMIT) { - // Handle custom diagnostics, which cannot be mapped. - DiagLevel = CustomDiagInfo->getLevel(DiagID); - } else { - // Get the class of the diagnostic. If this is a NOTE, map it onto whatever - // the diagnostic level was for the previous diagnostic so that it is - // filtered the same as the previous diagnostic. - unsigned DiagClass = getBuiltinDiagClass(DiagID); - if (DiagClass == CLASS_NOTE) { - DiagLevel = DiagnosticIDs::Note; - } else { - DiagLevel = getDiagnosticLevel(DiagID, DiagClass, Info.getLocation(), - Diag); - } - } + DiagnosticIDs::Level DiagLevel + = getDiagnosticLevel(DiagID, Info.getLocation(), Diag); if (DiagLevel != DiagnosticIDs::Note) { // Record that a fatal error occurred only when we see a second @@ -658,6 +643,14 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { } // Finally, report it. + EmitDiag(Diag, DiagLevel); + return true; +} + +void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const { + Diagnostic Info(&Diag); + assert(DiagLevel != DiagnosticIDs::Ignored && "Cannot emit ignored diagnostics!"); + Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info); if (Diag.Client->IncludeInDiagnosticCounts()) { if (DiagLevel == DiagnosticIDs::Warning) @@ -665,8 +658,6 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { } Diag.CurDiagID = ~0U; - - return true; } bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp index 1d9c196443..236b700662 100644 --- a/lib/Frontend/VerifyDiagnosticConsumer.cpp +++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp @@ -387,7 +387,7 @@ static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceM OS << ": " << I->second; } - Diags.Report(diag::err_verify_inconsistent_diags) + Diags.Report(diag::err_verify_inconsistent_diags).setForceEmit() << Kind << /*Unexpected=*/true << OS.str(); return std::distance(diag_begin, diag_end); } @@ -411,7 +411,7 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager &SourceMgr OS << ": " << D.Text; } - Diags.Report(diag::err_verify_inconsistent_diags) + Diags.Report(diag::err_verify_inconsistent_diags).setForceEmit() << Kind << /*Unexpected=*/false << OS.str(); return DL.size(); } |