diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2022-08-22 10:08:25 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-22 10:08:25 -0400 |
| commit | 15055d20c143cb398bd3e269541eebf24777390a (patch) | |
| tree | 81f96a53824765fabc1fbb81d2d588476996eaa9 /source/compiler-core/slang-artifact-diagnostic-util.cpp | |
| parent | af70651a4843b16dd24e14b5cedffe399ebeb862 (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.cpp | 158 |
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 |
