r320904 - [TextDiagnosticBuffer] Fix diagnostic note emission order

Hal Finkel via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 15 17:40:19 PST 2017


Author: hfinkel
Date: Fri Dec 15 17:40:19 2017
New Revision: 320904

URL: http://llvm.org/viewvc/llvm-project?rev=320904&view=rev
Log:
[TextDiagnosticBuffer] Fix diagnostic note emission order

The frontend currently groups diagnostics from the command line according to
diagnostic level, but that places all notes last. Fix that by emitting such
diagnostics in the order they were generated.

Patch by Joel E. Denny, thanks!

Differential Revision: https://reviews.llvm.org/D40995

Added:
    cfe/trunk/test/Frontend/diagnostics-order.c
Modified:
    cfe/trunk/include/clang/Frontend/TextDiagnosticBuffer.h
    cfe/trunk/lib/Frontend/TextDiagnosticBuffer.cpp

Modified: cfe/trunk/include/clang/Frontend/TextDiagnosticBuffer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TextDiagnosticBuffer.h?rev=320904&r1=320903&r2=320904&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TextDiagnosticBuffer.h (original)
+++ cfe/trunk/include/clang/Frontend/TextDiagnosticBuffer.h Fri Dec 15 17:40:19 2017
@@ -29,6 +29,11 @@ public:
   typedef DiagList::const_iterator const_iterator;
 private:
   DiagList Errors, Warnings, Remarks, Notes;
+  /// All - All diagnostics in the order in which they were generated.  That
+  /// order likely doesn't correspond to user input order, but it at least
+  /// keeps notes in the right places.  Each pair in the vector is a diagnostic
+  /// level and an index into the corresponding DiagList above.
+  std::vector<std::pair<DiagnosticsEngine::Level, size_t>> All;
 public:
   const_iterator err_begin() const  { return Errors.begin(); }
   const_iterator err_end() const    { return Errors.end(); }

Modified: cfe/trunk/lib/Frontend/TextDiagnosticBuffer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticBuffer.cpp?rev=320904&r1=320903&r2=320904&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticBuffer.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticBuffer.cpp Fri Dec 15 17:40:19 2017
@@ -30,34 +30,45 @@ void TextDiagnosticBuffer::HandleDiagnos
   default: llvm_unreachable(
                          "Diagnostic not handled during diagnostic buffering!");
   case DiagnosticsEngine::Note:
+    All.emplace_back(Level, Notes.size());
     Notes.emplace_back(Info.getLocation(), Buf.str());
     break;
   case DiagnosticsEngine::Warning:
+    All.emplace_back(Level, Warnings.size());
     Warnings.emplace_back(Info.getLocation(), Buf.str());
     break;
   case DiagnosticsEngine::Remark:
+    All.emplace_back(Level, Remarks.size());
     Remarks.emplace_back(Info.getLocation(), Buf.str());
     break;
   case DiagnosticsEngine::Error:
   case DiagnosticsEngine::Fatal:
+    All.emplace_back(Level, Errors.size());
     Errors.emplace_back(Info.getLocation(), Buf.str());
     break;
   }
 }
 
 void TextDiagnosticBuffer::FlushDiagnostics(DiagnosticsEngine &Diags) const {
-  // FIXME: Flush the diagnostics in order.
-  for (const_iterator it = err_begin(), ie = err_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
-        << it->second;
-  for (const_iterator it = warn_begin(), ie = warn_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Warning, "%0"))
-        << it->second;
-  for (const_iterator it = remark_begin(), ie = remark_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Remark, "%0"))
-        << it->second;
-  for (const_iterator it = note_begin(), ie = note_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0"))
-        << it->second;
+  for (auto it = All.begin(), ie = All.end(); it != ie; ++it) {
+    auto Diag = Diags.Report(Diags.getCustomDiagID(it->first, "%0"));
+    switch (it->first) {
+    default: llvm_unreachable(
+                           "Diagnostic not handled during diagnostic flushing!");
+    case DiagnosticsEngine::Note:
+      Diag << Notes[it->second].second;
+      break;
+    case DiagnosticsEngine::Warning:
+      Diag << Warnings[it->second].second;
+      break;
+    case DiagnosticsEngine::Remark:
+      Diag << Remarks[it->second].second;
+      break;
+    case DiagnosticsEngine::Error:
+    case DiagnosticsEngine::Fatal:
+      Diag << Errors[it->second].second;
+      break;
+    }
+  }
 }
 

Added: cfe/trunk/test/Frontend/diagnostics-order.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/diagnostics-order.c?rev=320904&view=auto
==============================================================================
--- cfe/trunk/test/Frontend/diagnostics-order.c (added)
+++ cfe/trunk/test/Frontend/diagnostics-order.c Fri Dec 15 17:40:19 2017
@@ -0,0 +1,10 @@
+// Make sure a note stays with its associated command-line argument diagnostic.
+// Previously, these diagnostics were grouped by diagnostic level with all
+// notes last.
+//
+// RUN: not %clang_cc1 -O999 -std=bogus %s 2> %t
+// RUN: FileCheck < %t %s
+//
+// CHECK: warning: optimization level '-O999' is not supported
+// CHECK-NEXT: error: invalid value 'bogus' in '-std=bogus'
+// CHECK-NEXT: note: use {{.*}} for {{.*}} standard




More information about the cfe-commits mailing list