[cfe-commits] r160053 - in /cfe/trunk: include/clang/Basic/Diagnostic.h include/clang/Basic/DiagnosticIDs.h lib/Basic/Diagnostic.cpp lib/Basic/DiagnosticIDs.cpp lib/Frontend/VerifyDiagnosticConsumer.cpp
Jordan Rose
jordan_rose at apple.com
Wed Jul 11 09:50:37 PDT 2012
Author: jrose
Date: Wed Jul 11 11:50:36 2012
New Revision: 160053
URL: http://llvm.org/viewvc/llvm-project?rev=160053&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/include/clang/Basic/DiagnosticIDs.h
cfe/trunk/lib/Basic/Diagnostic.cpp
cfe/trunk/lib/Basic/DiagnosticIDs.cpp
cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=160053&r1=160052&r2=160053&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Wed Jul 11 11:50:36 2012
@@ -763,7 +763,9 @@
friend class Sema;
/// \brief Emit the current diagnostic and clear the diagnostic state.
- bool EmitCurrentDiagnostic();
+ ///
+ /// \param Force Emit the diagnostic regardless of suppression settings.
+ bool EmitCurrentDiagnostic(bool Force = false);
unsigned getCurrentDiagID() const { return CurDiagID; }
@@ -833,14 +835,20 @@
// Emit() would end up with if we used that as our status variable.
mutable bool IsActive;
+ /// \brief Flag indicating that this diagnostic is being emitted via a
+ /// call to ForceEmit.
+ mutable bool IsForceEmit;
+
void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
friend class DiagnosticsEngine;
DiagnosticBuilder()
- : DiagObj(0), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(false) { }
+ : DiagObj(0), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(false),
+ IsForceEmit(false) { }
explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
- : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true) {
+ : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true),
+ IsForceEmit(false) {
assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
}
@@ -857,6 +865,7 @@
void Clear() const {
DiagObj = 0;
IsActive = false;
+ IsForceEmit = false;
}
/// \brief Determine whether this diagnostic is still active.
@@ -879,7 +888,7 @@
FlushCounts();
// Process the diagnostic.
- bool Result = DiagObj->EmitCurrentDiagnostic();
+ bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
// This diagnostic is dead.
Clear();
@@ -893,6 +902,7 @@
DiagnosticBuilder(const DiagnosticBuilder &D) {
DiagObj = D.DiagObj;
IsActive = D.IsActive;
+ IsForceEmit = D.IsForceEmit;
D.Clear();
NumArgs = D.NumArgs;
NumRanges = D.NumRanges;
@@ -909,6 +919,12 @@
Emit();
}
+ /// \brief Forces the diagnostic to be emitted.
+ const DiagnosticBuilder &setForceEmit() const {
+ IsForceEmit = true;
+ return *this;
+ }
+
/// \brief Conversion of DiagnosticBuilder to bool always returns \c true.
///
/// This allows is to be used in boolean error contexts (where \c true is
Modified: cfe/trunk/include/clang/Basic/DiagnosticIDs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticIDs.h?rev=160053&r1=160052&r2=160053&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticIDs.h (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticIDs.h Wed Jul 11 11:50:36 2012
@@ -268,6 +268,10 @@
/// suppressed.
bool ProcessDiag(DiagnosticsEngine &Diag) const;
+ /// \brief Used to emit a diagnostic that is finally fully formed,
+ /// ignoring suppression.
+ void EmitDiag(DiagnosticsEngine &Diag, Level DiagLevel) const;
+
/// \brief Whether the diagnostic may leave the AST in a state where some
/// invariants can break.
bool isUnrecoverable(unsigned DiagID) const;
Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=160053&r1=160052&r2=160053&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Wed Jul 11 11:50:36 2012
@@ -382,17 +382,34 @@
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;
Modified: cfe/trunk/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/DiagnosticIDs.cpp?rev=160053&r1=160052&r2=160053&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (original)
+++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Wed Jul 11 11:50:36 2012
@@ -357,7 +357,7 @@
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 @@
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 @@
}
// 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 @@
}
Diag.CurDiagID = ~0U;
-
- return true;
}
bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
Modified: cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp?rev=160053&r1=160052&r2=160053&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/VerifyDiagnosticConsumer.cpp Wed Jul 11 11:50:36 2012
@@ -387,7 +387,7 @@
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 @@
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();
}
More information about the cfe-commits
mailing list