From 4c271d41690f16f970d4c88abd70729c3c1d6fb6 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Mon, 3 Mar 2014 18:29:52 +0000 Subject: [PATCH] Serialized diagnostic severity levels should be stable. Serialized diagnostics were accidentally using the AST diagnostic level values rather than a dedicated stable enum, so the addition of "remark" broke the reading of existing serialized diagnostics files. I've added a .dia file generated from Xcode 5's Clang to make sure we don't break this in the future. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@202733 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Frontend/SerializedDiagnosticPrinter.h | 13 +++++++++++ lib/Frontend/SerializedDiagnosticPrinter.cpp | 19 +++++++++++++-- test/Misc/Inputs/serialized-diags-stable.dia | Bin 0 -> 580 bytes test/Misc/serialized-diags-stable.c | 20 ++++++++++++++++ tools/libclang/CXLoadedDiagnostic.cpp | 22 +++++++++++------- 5 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 test/Misc/Inputs/serialized-diags-stable.dia create mode 100644 test/Misc/serialized-diags-stable.c diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h index 117771d157..4dda1fa4b6 100644 --- a/include/clang/Frontend/SerializedDiagnosticPrinter.h +++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h @@ -46,6 +46,19 @@ enum RecordIDs { RECORD_LAST = RECORD_FIXIT }; +/// A stable version of DiagnosticIDs::Level. +/// +/// Do not change the order of values in this enum, and please increment the +/// serialized diagnostics version number when you add to it. +enum Level { + Ignored = 0, + Note, + Warning, + Error, + Fatal, + Remark +}; + /// \brief Returns a DiagnosticConsumer that serializes diagnostics to /// a bitcode file. /// diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp index 6514321f22..bed52b5361 100644 --- a/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -174,7 +174,7 @@ private: const SourceManager &SM); /// \brief The version of the diagnostics file. - enum { Version = 1 }; + enum { Version = 2 }; /// \brief Language options, which can differ from one clone of this client /// to another. @@ -566,6 +566,21 @@ void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, &Info); } +static serialized_diags::Level getStableLevel(DiagnosticsEngine::Level Level) { + switch (Level) { +#define CASE(X) case DiagnosticsEngine::X: return serialized_diags::X; + CASE(Ignored) + CASE(Note) + CASE(Remark) + CASE(Warning) + CASE(Error) + CASE(Fatal) +#undef CASE + } + + llvm_unreachable("invalid diagnostic level"); +} + void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, @@ -579,7 +594,7 @@ void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc, // Emit the RECORD_DIAG record. Record.clear(); Record.push_back(RECORD_DIAG); - Record.push_back(Level); + Record.push_back(getStableLevel(Level)); AddLocToRecord(Loc, SM, PLoc, Record); if (const Diagnostic *Info = D.dyn_cast()) { diff --git a/test/Misc/Inputs/serialized-diags-stable.dia b/test/Misc/Inputs/serialized-diags-stable.dia new file mode 100644 index 0000000000000000000000000000000000000000..acdaad26627ee06f9c32b657b20aa48ef04edc17 GIT binary patch literal 580 zcmYLFJ#Q015FLMo#Q5VBSph*n>j*2?m`hUOq_NLII0z&}5CTMz_1!vIvEDPcca{=S z#8!eS4RVpvNU2eZ6qJWj(IAnEf+Cinpx{3+=R{(p*_k(b@9oa6u2t?uQUD78a5-v6 zzbAi}v!kQPl=wLNi{3mP-S|l>yS0?2&&0pRySdZ+>^EAS>zm7aC#A#g%E8HssJ(sO z@4fEtw^}`=_tLe+~TrG)(%zEw8n_6P$ znRe@O!hScc$CDj%pm!>FXC_nKCx3SJjycry)u~)`znuS29t6Xs^cV%h7uk#PePp1n z63OEpQQQN|I0_oTB6e3VFa%nlV{bflgx_S!c;L9q5Te~Iw*0!_mSG7hHw}*|&v?j{ zWhmxyD)QEQ7S!lX@{29b^|wjFMhhA%CTJ2K>kyA-e-AMl5pi2wiq literal 0 HcmV?d00001 diff --git a/test/Misc/serialized-diags-stable.c b/test/Misc/serialized-diags-stable.c new file mode 100644 index 0000000000..29b85f4e64 --- /dev/null +++ b/test/Misc/serialized-diags-stable.c @@ -0,0 +1,20 @@ +// RUN: rm -f %t +// RUN: not %clang -Wall -fsyntax-only %s --serialize-diagnostics %t.dia > /dev/null 2>&1 +// RUN: c-index-test -read-diagnostics %t.dia 2>&1 | FileCheck %s + +// RUN: c-index-test -read-diagnostics %S/Inputs/serialized-diags-stable.dia 2>&1 | FileCheck %s + +int foo() { + // CHECK: serialized-diags-stable.c:[[@LINE+2]]:1: warning: control reaches end of non-void function [-Wreturn-type] [Semantic Issue] + // CHECK-NEXT: Number FIXITs = 0 +} + +// CHECK: serialized-diags-stable.c:[[@LINE+5]]:13: error: redefinition of 'bar' as different kind of symbol [] [Semantic Issue] +// CHECK-NEXT: Number FIXITs = 0 +// CHECK-NEXT: +-/Volumes/Lore/llvm-public/clang/test/Misc/serialized-diags-stable.c:[[@LINE+2]]:6: note: previous definition is here [] [] +// CHECK-NEXT: Number FIXITs = 0 +void bar() {} +typedef int bar; + + +// CHECK-LABEL: Number of diagnostics: 2 diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp index e82ff95da1..86db08b123 100644 --- a/tools/libclang/CXLoadedDiagnostic.cpp +++ b/tools/libclang/CXLoadedDiagnostic.cpp @@ -67,13 +67,19 @@ CXLoadedDiagnostic::~CXLoadedDiagnostic() {} //===----------------------------------------------------------------------===// CXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const { - // FIXME: possibly refactor with logic in CXStoredDiagnostic. - switch (severity) { - case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; - case DiagnosticsEngine::Note: return CXDiagnostic_Note; - case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; - case DiagnosticsEngine::Error: return CXDiagnostic_Error; - case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; + // FIXME: Fail more softly if the diagnostic level is unknown? + assert(severity == static_cast(severity) && + "unknown serialized diagnostic level"); + + switch (static_cast(severity)) { +#define CASE(X) case serialized_diags::X: return CXDiagnostic_##X; + CASE(Ignored) + CASE(Note) + CASE(Warning) + CASE(Error) + CASE(Fatal) + CASE(Remark) +#undef CASE } llvm_unreachable("Invalid diagnostic level"); @@ -175,7 +181,7 @@ void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location, // Deserialize diagnostics. //===----------------------------------------------------------------------===// -enum { MaxSupportedVersion = 1 }; +enum { MaxSupportedVersion = 2 }; typedef SmallVector RecordData; enum LoadResult { Failure = 1, Success = 0 }; enum StreamResult { Read_EndOfStream, -- 2.40.0