diff options
| -rw-r--r-- | slang.h | 50 | ||||
| -rw-r--r-- | source/compiler-core/slang-diagnostic-sink.cpp | 28 | ||||
| -rw-r--r-- | source/compiler-core/slang-diagnostic-sink.h | 27 | ||||
| -rw-r--r-- | source/compiler-core/slang-misc-diagnostic-defs.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-api.cpp | 26 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 50 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 39 |
8 files changed, 216 insertions, 10 deletions
@@ -521,11 +521,19 @@ extern "C" typedef int SlangSeverity; enum { - SLANG_SEVERITY_NOTE = 0, /**< An informative message. */ - SLANG_SEVERITY_WARNING, /**< A warning, which indicates a possible proble. */ - SLANG_SEVERITY_ERROR, /**< An error, indicating that compilation failed. */ - SLANG_SEVERITY_FATAL, /**< An unrecoverable error, which forced compilation to abort. */ - SLANG_SEVERITY_INTERNAL, /**< An internal error, indicating a logic error in the compiler. */ + SLANG_SEVERITY_DISABLED = 0, /**< A message that is disabled, filtered out. */ + SLANG_SEVERITY_NOTE, /**< An informative message. */ + SLANG_SEVERITY_WARNING, /**< A warning, which indicates a possible proble. */ + SLANG_SEVERITY_ERROR, /**< An error, indicating that compilation failed. */ + SLANG_SEVERITY_FATAL, /**< An unrecoverable error, which forced compilation to abort. */ + SLANG_SEVERITY_INTERNAL, /**< An internal error, indicating a logic error in the compiler. */ + }; + + typedef int SlangDiagnosticFlags; + enum + { + SLANG_DIAGNOSTIC_FLAG_VERBOSE_PATHS = 0x01, + SLANG_DIAGNOSTIC_FLAG_TREAT_WARNINGS_AS_ERRORS = 0x02 }; typedef int SlangBindableResourceType; @@ -1709,7 +1717,19 @@ extern "C" size_t reproDataSize, ISlangFileSystem* replaceFileSystem, ISlangFileSystemExt** outFileSystem); - + + /*! @see slang::ICompileRequest::overrideDiagnosticSeverity */ + SLANG_API void spOverrideDiagnosticSeverity( + SlangCompileRequest* request, + SlangInt messageID, + SlangSeverity overrideSeverity); + + /*! @see slang::ICompileRequest::getDiagnosticFlags */ + SLANG_API SlangDiagnosticFlags spGetDiagnosticFlags(SlangCompileRequest* request); + + /*! @see slang::ICompileRequest::setDiagnosticFlags */ + SLANG_API void spSetDiagnosticFlags(SlangCompileRequest* request, SlangDiagnosticFlags flags); + /* Forward declarations of types used in the reflection interface; */ @@ -3883,6 +3903,24 @@ namespace slang If false, the resulting code will std430 for storage buffers. */ virtual SLANG_NO_THROW void SLANG_MCALL setTargetForceGLSLScalarBufferLayout(int targetIndex, bool forceScalarLayout) = 0; + + /** Overrides the severity of a specific diagnostic message. + + @param messageID Numeric identifier of the message to override, + as defined in the 1st parameter of the DIAGNOSTIC macro. + @param overrideSeverity New severity of the message. If the message is originally Error or Fatal, + the new severity cannot be lower than that. + */ + virtual SLANG_NO_THROW void SLANG_MCALL overrideDiagnosticSeverity( + SlangInt messageID, + SlangSeverity overrideSeverity) = 0; + + /** Returns the currently active flags of the request's diagnostic sink. */ + virtual SLANG_NO_THROW SlangDiagnosticFlags SLANG_MCALL getDiagnosticFlags() = 0; + + /** Sets the flags of the request's diagnostic sink. + The previously specified flags are discarded. */ + virtual SLANG_NO_THROW void SLANG_MCALL setDiagnosticFlags(SlangDiagnosticFlags flags) = 0; }; #define SLANG_UUID_ICompileRequest ICompileRequest::getTypeGuid() 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<int, Severity> 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") diff --git a/source/slang/slang-api.cpp b/source/slang/slang-api.cpp index ba0b4296a..911bd0f0f 100644 --- a/source/slang/slang-api.cpp +++ b/source/slang/slang-api.cpp @@ -831,3 +831,29 @@ SLANG_API SlangResult spLoadReproAsFileSystem( return SLANG_OK; } +SLANG_API void spOverrideDiagnosticSeverity( + slang::ICompileRequest* request, + SlangInt messageID, + SlangSeverity overrideSeverity) +{ + if (!request) + return; + + request->overrideDiagnosticSeverity(messageID, overrideSeverity); +} + +SLANG_API SlangDiagnosticFlags spGetDiagnosticFlags(slang::ICompileRequest* request) +{ + if (!request) + return 0; + + return request->getDiagnosticFlags(); +} + +SLANG_API void spSetDiagnosticFlags(slang::ICompileRequest* request, SlangDiagnosticFlags flags) +{ + if (!request) + return; + + request->setDiagnosticFlags(flags); +} diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index a9a19d29c..39ee830d2 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -2539,6 +2539,11 @@ namespace Slang virtual SLANG_NO_THROW void SLANG_MCALL setTargetLineDirectiveMode( SlangInt targetIndex, SlangLineDirectiveMode mode) SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL overrideDiagnosticSeverity( + SlangInt messageID, + SlangSeverity overrideSeverity) SLANG_OVERRIDE; + virtual SLANG_NO_THROW SlangDiagnosticFlags SLANG_MCALL getDiagnosticFlags() SLANG_OVERRIDE; + virtual SLANG_NO_THROW void SLANG_MCALL setDiagnosticFlags(SlangDiagnosticFlags flags) SLANG_OVERRIDE; EndToEndCompileRequest( Session* session); diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 6705f836b..875f18980 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -21,6 +21,7 @@ #include "../compiler-core/slang-command-line-args.h" #include "../compiler-core/slang-artifact-info.h" +#include "../compiler-core/slang-core-diagnostics.h" #include <assert.h> @@ -550,6 +551,9 @@ struct OptionsParser " glsl, hlsl, spirv, spirv-assembly, dxbc,\n" " dxbc-assembly, dxil, dxil-assembly\n" " -v, -version: Display the build version.\n" + " -warnings-as-errors all: Treat all warnings as errors.\n" + " -warnings-as-errors <id>[,<id>...]: Treat specific warning ids as errors.\n" + " -warnings-disable <id>[,<id>...]: Disable specific warning ids.\n" " --: Treat the rest of the command line as input files.\n" "\n" "Target code generation options:\n" @@ -704,6 +708,25 @@ struct OptionsParser #undef EXECUTABLE_EXTENSION } + SlangResult overrideDiagnosticSeverity(String const& identifierList, Severity overrideSeverity) + { + List<UnownedStringSlice> slices; + StringUtil::split(identifierList.getUnownedSlice(), ',', slices); + Index sliceCount = slices.getCount(); + + for (Index i = 0; i < sliceCount; ++i) + { + UnownedStringSlice warningIdentifier = slices[i]; + + Int warningIndex = -1; + SLANG_RETURN_ON_FAIL(StringUtil::parseInt(warningIdentifier, warningIndex)); + + requestImpl->getSink()->overrideDiagnosticSeverity(int(warningIndex), overrideSeverity); + } + + return SLANG_OK; + } + SlangResult parse( int argc, char const* const* argv) @@ -1009,6 +1032,33 @@ struct OptionsParser { requestImpl->getSink()->setFlag(DiagnosticSink::Flag::VerbosePath); } + else if (argValue == "-warnings-as-errors") + { + CommandLineArg operand; + SLANG_RETURN_ON_FAIL(reader.expectArg(operand)); + + if (operand.value == "all") + requestImpl->getSink()->setFlag(DiagnosticSink::Flag::TreatWarningsAsErrors); + else + { + if (SLANG_FAILED(overrideDiagnosticSeverity(operand.value, Severity::Error))) + { + sink->diagnose(operand.loc, MiscDiagnostics::invalidArgumentForOption, "-warnings-as-errors"); + return SLANG_FAIL; + } + } + } + else if (argValue == "-warnings-disable") + { + CommandLineArg operand; + SLANG_RETURN_ON_FAIL(reader.expectArg(operand)); + + if (SLANG_FAILED(overrideDiagnosticSeverity(operand.value, Severity::Disable))) + { + sink->diagnose(operand.loc, MiscDiagnostics::invalidArgumentForOption, "-warnings-disable"); + return SLANG_FAIL; + } + } else if (argValue == "-verify-debug-serial-ir") { requestImpl->getFrontEndReq()->verifyDebugSerialization = true; diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 3a180027a..7ce3594e5 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -4248,6 +4248,45 @@ void EndToEndCompileRequest::setTargetLineDirectiveMode( getLinkage()->targets[targetIndex]->setLineDirectiveMode(LineDirectiveMode(mode)); } +void EndToEndCompileRequest::overrideDiagnosticSeverity( + SlangInt messageID, + SlangSeverity overrideSeverity) +{ + getSink()->overrideDiagnosticSeverity(int(messageID), Severity(overrideSeverity)); +} + +SlangDiagnosticFlags EndToEndCompileRequest::getDiagnosticFlags() +{ + DiagnosticSink::Flags sinkFlags = getSink()->getFlags(); + + SlangDiagnosticFlags flags = 0; + + if (sinkFlags & DiagnosticSink::Flag::VerbosePath) + flags |= SLANG_DIAGNOSTIC_FLAG_VERBOSE_PATHS; + + if (sinkFlags & DiagnosticSink::Flag::TreatWarningsAsErrors) + flags |= SLANG_DIAGNOSTIC_FLAG_TREAT_WARNINGS_AS_ERRORS; + + return flags; +} + +void EndToEndCompileRequest::setDiagnosticFlags(SlangDiagnosticFlags flags) +{ + DiagnosticSink::Flags sinkFlags = getSink()->getFlags(); + + if (flags & SLANG_DIAGNOSTIC_FLAG_VERBOSE_PATHS) + sinkFlags |= DiagnosticSink::Flag::VerbosePath; + else + sinkFlags &= ~DiagnosticSink::Flag::VerbosePath; + + if (flags & SLANG_DIAGNOSTIC_FLAG_TREAT_WARNINGS_AS_ERRORS) + sinkFlags |= DiagnosticSink::Flag::TreatWarningsAsErrors; + else + sinkFlags &= ~DiagnosticSink::Flag::TreatWarningsAsErrors; + + getSink()->setFlags(sinkFlags); +} + SlangResult EndToEndCompileRequest::addTargetCapability(SlangInt targetIndex, SlangCapabilityID capability) { auto& targets = getLinkage()->targets; |
