summaryrefslogtreecommitdiff
path: root/source/compiler-core/slang-artifact-diagnostic-util.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-22 10:08:25 -0400
committerGitHub <noreply@github.com>2022-08-22 10:08:25 -0400
commit15055d20c143cb398bd3e269541eebf24777390a (patch)
tree81f96a53824765fabc1fbb81d2d588476996eaa9 /source/compiler-core/slang-artifact-diagnostic-util.cpp
parentaf70651a4843b16dd24e14b5cedffe399ebeb862 (diff)
Replace DownstreamCompileResult with Artifact (#2369)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP replacing DownstreamCompileResult. * First attempt at replacing DownstreamCompileResult with IArtifact and associated types. * Small renaming around CharSlice. * ICastable -> ISlangCastable Added IClonable Fix issue with cloning in ArtifactDiagnostics. * Only add the blob if one is defined in DXC. * Guard adding blob representation. * Make cloneInterface available across code base. Set enums backing type for ArtifactDiagnostic. * Added ::create for ArtifactDiagnostics.
Diffstat (limited to 'source/compiler-core/slang-artifact-diagnostic-util.cpp')
-rw-r--r--source/compiler-core/slang-artifact-diagnostic-util.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/source/compiler-core/slang-artifact-diagnostic-util.cpp b/source/compiler-core/slang-artifact-diagnostic-util.cpp
new file mode 100644
index 000000000..0f6b70ab4
--- /dev/null
+++ b/source/compiler-core/slang-artifact-diagnostic-util.cpp
@@ -0,0 +1,158 @@
+// slang-artifact-diagnostic-util.cpp
+#include "slang-artifact-diagnostic-util.h"
+
+#include "../core/slang-char-util.h"
+#include "../core/slang-string-util.h"
+
+namespace Slang {
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CharSliceAllocator !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+TerminatedCharSlice CharSliceAllocator::allocate(const char* in)
+{
+ const size_t length = ::strlen(in);
+ auto dst = m_arena.allocateString(in, length);
+ return TerminatedCharSlice(dst, length);
+}
+
+TerminatedCharSlice CharSliceAllocator::allocate(const UnownedStringSlice& slice)
+{
+ const auto length = slice.getLength();
+ auto dst = m_arena.allocateString(slice.begin(), length);
+ return TerminatedCharSlice(dst, length);
+}
+
+TerminatedCharSlice CharSliceAllocator::allocate(const Slice<char>& slice)
+{
+ const auto count = slice.count;
+ auto dst = m_arena.allocateString(slice.begin(), count);
+ return TerminatedCharSlice(dst, count);
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDiagnosticsUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */UnownedStringSlice ArtifactDiagnosticUtil::getSeverityText(Severity severity)
+{
+ switch (severity)
+ {
+ default: return UnownedStringSlice::fromLiteral("Unknown");
+ case Severity::Info: return UnownedStringSlice::fromLiteral("Info");
+ case Severity::Warning: return UnownedStringSlice::fromLiteral("Warning");
+ case Severity::Error: return UnownedStringSlice::fromLiteral("Error");
+ }
+}
+
+/* static */SlangResult ArtifactDiagnosticUtil::splitPathLocation(CharSliceAllocator& allocator, const UnownedStringSlice& pathLocation, ArtifactDiagnostic& outDiagnostic)
+{
+ const Index lineStartIndex = pathLocation.lastIndexOf('(');
+ if (lineStartIndex >= 0)
+ {
+ outDiagnostic.filePath = allocator.allocate(pathLocation.head(lineStartIndex).trim());
+
+ const UnownedStringSlice tail = pathLocation.tail(lineStartIndex + 1);
+ const Index lineEndIndex = tail.indexOf(')');
+
+ if (lineEndIndex >= 0)
+ {
+ // Extract the location info
+ UnownedStringSlice locationSlice(tail.begin(), tail.begin() + lineEndIndex);
+
+ UnownedStringSlice slices[2];
+ const Index numSlices = StringUtil::split(locationSlice, ',', 2, slices);
+
+ // NOTE! FXC actually outputs a range of columns in the form of START-END in the column position
+ // We don't need to parse here, because we only care about the line number
+
+ Int lineNumber = 0;
+ if (numSlices > 0)
+ {
+ SLANG_RETURN_ON_FAIL(StringUtil::parseInt(slices[0], lineNumber));
+ }
+
+ // Store the line
+ outDiagnostic.location.line = lineNumber;
+ }
+ }
+ else
+ {
+ outDiagnostic.filePath = allocator.allocate(pathLocation);
+ }
+ return SLANG_OK;
+}
+
+/* static */SlangResult ArtifactDiagnosticUtil::splitColonDelimitedLine(const UnownedStringSlice& line, Int pathIndex, List<UnownedStringSlice>& outSlices)
+{
+ StringUtil::split(line, ':', outSlices);
+
+ // Now we want to fix up a path as might have drive letter, and therefore :
+ // If this is the situation then we need to have a slice after the one at the index
+ if (outSlices.getCount() > pathIndex + 1)
+ {
+ const UnownedStringSlice pathStart = outSlices[pathIndex].trim();
+ if (pathStart.getLength() == 1 && CharUtil::isAlpha(pathStart[0]))
+ {
+ // Splice back together
+ outSlices[pathIndex] = UnownedStringSlice(outSlices[pathIndex].begin(), outSlices[pathIndex + 1].end());
+ outSlices.removeAt(pathIndex + 1);
+ }
+ }
+
+ return SLANG_OK;
+}
+
+/* static */SlangResult ArtifactDiagnosticUtil::parseColonDelimitedDiagnostics(CharSliceAllocator& allocator, const UnownedStringSlice& inText, Int pathIndex, LineParser lineParser, IArtifactDiagnostics* diagnostics)
+{
+ List<UnownedStringSlice> splitLine;
+
+ UnownedStringSlice text(inText), line;
+ while (StringUtil::extractLine(text, line))
+ {
+ SLANG_RETURN_ON_FAIL(splitColonDelimitedLine(line, pathIndex, splitLine));
+
+ ArtifactDiagnostic diagnostic;
+ diagnostic.severity = Severity::Error;
+ diagnostic.stage = ArtifactDiagnostic::Stage::Compile;
+ diagnostic.location.line = 0;
+ diagnostic.location.column = 0;
+
+ if (SLANG_SUCCEEDED(lineParser(allocator, line, splitLine, diagnostic)))
+ {
+ diagnostics->add(diagnostic);
+ }
+ else
+ {
+ // If couldn't parse, just add as a note
+ maybeAddNote(line, diagnostics);
+ }
+ }
+
+ return SLANG_OK;
+}
+
+/* static */void ArtifactDiagnosticUtil::maybeAddNote(const UnownedStringSlice& in, IArtifactDiagnostics* diagnostics)
+{
+ // Don't bother adding an empty line
+ if (in.trim().getLength() == 0)
+ {
+ return;
+ }
+
+ // If there's nothing previous, we'll ignore too, as note should be in addition to
+ // a pre-existing error/warning
+ if (diagnostics->getCount() == 0)
+ {
+ return;
+ }
+
+ // Make it a note on the output
+ ArtifactDiagnostic diagnostic;
+
+ String text(in);
+
+ diagnostic.severity = ArtifactDiagnostic::Severity::Info;
+ diagnostic.text = CharSliceCaster::asTerminatedCharSlice(text);
+ diagnostics->add(diagnostic);
+}
+
+
+} // namespace Slang