From d9fd0ff3f0fc7b775de1e05570f01798fbc8baa3 Mon Sep 17 00:00:00 2001 From: Alexey Panteleev Date: Tue, 17 May 2022 15:05:44 -0700 Subject: Configuration for warnings (#2241) * Added support for disabling specific warnings or turning them into errors. * Added API entry points for adding diagnostic severity overrides and manipulating some sink flags. --- source/compiler-core/slang-diagnostic-sink.cpp | 28 ++++++++++++++++++++++- source/compiler-core/slang-diagnostic-sink.h | 27 +++++++++++++++++++--- source/compiler-core/slang-misc-diagnostic-defs.h | 1 + 3 files changed, 52 insertions(+), 4 deletions(-) (limited to 'source/compiler-core') diff --git a/source/compiler-core/slang-diagnostic-sink.cpp b/source/compiler-core/slang-diagnostic-sink.cpp index db2885f05..314ec1c2c 100644 --- a/source/compiler-core/slang-diagnostic-sink.cpp +++ b/source/compiler-core/slang-diagnostic-sink.cpp @@ -525,8 +525,34 @@ void DiagnosticSink::diagnoseImpl(DiagnosticInfo const& info, const UnownedStrin } } -void DiagnosticSink::diagnoseImpl(SourceLoc const& pos, DiagnosticInfo const& info, int argCount, DiagnosticArg const* const* args) +Severity DiagnosticSink::getEffectiveMessageSeverity(DiagnosticInfo const& info) { + Severity effectiveSeverity = info.severity; + + Severity* pSeverityOverride = m_severityOverrides.TryGetValue(info.id); + + // See if there is an override + if (pSeverityOverride) + { + // Override the current severity, but don't allow lowering it if it's Error or Fatal + if (effectiveSeverity < Severity::Error || *pSeverityOverride >= effectiveSeverity) + effectiveSeverity = *pSeverityOverride; + } + + if (isFlagSet(Flag::TreatWarningsAsErrors) && info.severity == Severity::Warning) + effectiveSeverity = Severity::Error; + + return effectiveSeverity; +} + +void DiagnosticSink::diagnoseImpl(SourceLoc const& pos, DiagnosticInfo info, int argCount, DiagnosticArg const* const* args) +{ + // Override the severity in the 'info' structure to pass it further into formatDiagnostics + info.severity = getEffectiveMessageSeverity(info); + + if (info.severity == Severity::Disable) + return; + StringBuilder messageBuilder; { StringBuilder sb; diff --git a/source/compiler-core/slang-diagnostic-sink.h b/source/compiler-core/slang-diagnostic-sink.h index f83672679..b78023bc8 100644 --- a/source/compiler-core/slang-diagnostic-sink.h +++ b/source/compiler-core/slang-diagnostic-sink.h @@ -15,18 +15,28 @@ namespace Slang enum class Severity { + Disable, Note, Warning, Error, Fatal, - Internal, + Internal }; +// Make sure that the slang.h severity constants match those defined here +static_assert(SLANG_SEVERITY_DISABLED == int(Severity::Disable), "mismatched Severity enum values"); +static_assert(SLANG_SEVERITY_NOTE == int(Severity::Note), "mismatched Severity enum values"); +static_assert(SLANG_SEVERITY_WARNING == int(Severity::Warning), "mismatched Severity enum values"); +static_assert(SLANG_SEVERITY_ERROR == int(Severity::Error), "mismatched Severity enum values"); +static_assert(SLANG_SEVERITY_FATAL == int(Severity::Fatal), "mismatched Severity enum values"); +static_assert(SLANG_SEVERITY_INTERNAL == int(Severity::Internal), "mismatched Severity enum values"); + // TODO(tfoley): move this into a source file... inline const char* getSeverityName(Severity severity) { switch (severity) { + case Severity::Disable: return "ignored"; case Severity::Note: return "note"; case Severity::Warning: return "warning"; case Severity::Error: return "error"; @@ -128,7 +138,6 @@ struct DiagnosticArg {} }; - class DiagnosticSink { public: @@ -141,6 +150,7 @@ public: VerbosePath = 0x1, ///< Will display a more verbose path (if available) - such as a canonical or absolute path SourceLocationLine = 0x2, ///< If set will display the location line if source is available HumaneLoc = 0x4, ///< If set will display humane locs (filename/line number) information + TreatWarningsAsErrors = 0x8 ///< If set will turn all Warning type messages (after overrides) into Error type messages }; }; @@ -215,6 +225,12 @@ public: /// Test if flag is set bool isFlagSet(Flag::Enum flag) { return (m_flags & Flags(flag)) != 0; } + /// Sets an override on the severity of a specific diagnostic message (by numeric identifier) + void overrideDiagnosticSeverity(int messageID, Severity overrideSeverity) + { + m_severityOverrides[messageID] = overrideSeverity; + } + /// Get the (optional) diagnostic sink lexer. This is used to /// improve quality of highlighting a locations token. If not set, will just have a single /// character caret at location @@ -252,9 +268,11 @@ public: ISlangWriter* writer = nullptr; protected: - void diagnoseImpl(SourceLoc const& pos, DiagnosticInfo const& info, int argCount, DiagnosticArg const* const* args); + void diagnoseImpl(SourceLoc const& pos, DiagnosticInfo info, int argCount, DiagnosticArg const* const* args); void diagnoseImpl(DiagnosticInfo const& info, const UnownedStringSlice& formattedMessage); + Severity getEffectiveMessageSeverity(DiagnosticInfo const& info); + /// If set all diagnostics (as formatted by *this* sink, will be routed to the parent). DiagnosticSink* m_parentSink = nullptr; @@ -271,6 +289,9 @@ protected: SourceManager* m_sourceManager = nullptr; SourceLocationLexer m_sourceLocationLexer; + + // Configuration that allows the user to control the severity of certain diagnostic messages + Dictionary m_severityOverrides; }; /// An `ISlangWriter` that writes directly to a diagnostic sink. diff --git a/source/compiler-core/slang-misc-diagnostic-defs.h b/source/compiler-core/slang-misc-diagnostic-defs.h index aa87f02f9..aed83eb30 100644 --- a/source/compiler-core/slang-misc-diagnostic-defs.h +++ b/source/compiler-core/slang-misc-diagnostic-defs.h @@ -29,6 +29,7 @@ DIAGNOSTIC(100001, Error, expectedArgumentForOption, "expected an argument for c DIAGNOSTIC(100002, Error, unbalancedDownstreamArguments, "unbalanced downstream arguments") DIAGNOSTIC(100003, Error, closeOfUnopenDownstreamArgs, "close of an unopen downstream argument scope") DIAGNOSTIC(100004, Error, downstreamToolNameNotDefined, "downstream tool name not defined") +DIAGNOSTIC(100005, Error, invalidArgumentForOption, "invalid argument format for command-line option '$0'") DIAGNOSTIC(99999, Note, noteLocationOfInternalError, "an internal error threw an exception while working on code near this location") -- cgit v1.2.3