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-downstream-compiler.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-downstream-compiler.cpp')
| -rw-r--r-- | source/compiler-core/slang-downstream-compiler.cpp | 331 |
1 files changed, 54 insertions, 277 deletions
diff --git a/source/compiler-core/slang-downstream-compiler.cpp b/source/compiler-core/slang-downstream-compiler.cpp index 64ad7fbc9..4f7462901 100644 --- a/source/compiler-core/slang-downstream-compiler.cpp +++ b/source/compiler-core/slang-downstream-compiler.cpp @@ -12,108 +12,13 @@ #include "../core/slang-blob.h" #include "../core/slang-char-util.h" +#include "../core/slang-castable-list-impl.h" -namespace Slang -{ - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamDiagnostic !!!!!!!!!!!!!!!!!!!!!!!!*/ - -/* static */UnownedStringSlice DownstreamDiagnostic::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 DownstreamDiagnostic::splitPathLocation(const UnownedStringSlice& pathLocation, DownstreamDiagnostic& outDiagnostic) -{ - const Index lineStartIndex = pathLocation.lastIndexOf('('); - if (lineStartIndex >= 0) - { - outDiagnostic.filePath = UnownedStringSlice(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.fileLine = lineNumber; - } - } - else - { - outDiagnostic.filePath = pathLocation; - } - return SLANG_OK; -} - -/* static */SlangResult DownstreamDiagnostic::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; -} +#include "slang-artifact-associated-impl.h" +#include "slang-artifact-util.h" -/* static */SlangResult DownstreamDiagnostic::parseColonDelimitedDiagnostics(const UnownedStringSlice& inText, Int pathIndex, LineParser lineParser, List<DownstreamDiagnostic>& outDiagnostics) +namespace Slang { - List<UnownedStringSlice> splitLine; - - UnownedStringSlice text(inText), line; - while (StringUtil::extractLine(text, line)) - { - SLANG_RETURN_ON_FAIL(splitColonDelimitedLine(line, pathIndex, splitLine)); - - DownstreamDiagnostic diagnostic; - diagnostic.severity = DownstreamDiagnostic::Severity::Error; - diagnostic.stage = DownstreamDiagnostic::Stage::Compile; - diagnostic.fileLine = 0; - - if (SLANG_SUCCEEDED(lineParser(line, splitLine, diagnostic))) - { - outDiagnostics.add(diagnostic); - } - else - { - // If couldn't parse, just add as a note - DownstreamDiagnostics::addNote(line, outDiagnostics); - } - } - - return SLANG_OK; -} /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompilerBase !!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ @@ -154,211 +59,75 @@ void* DownstreamCompilerBase::getObject(const Guid& guid) return nullptr; } -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamDiagnostics !!!!!!!!!!!!!!!!!!!!!!*/ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CommandLineDownstreamArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!*/ -Index DownstreamDiagnostics::getCountAtLeastSeverity(Diagnostic::Severity severity) const +void* CommandLineDownstreamArtifactRepresentation::castAs(const Guid& guid) { - Index count = 0; - for (const auto& msg : diagnostics) - { - count += Index(Index(msg.severity) >= Index(severity)); - } - return count; -} - -Index DownstreamDiagnostics::getCountBySeverity(Diagnostic::Severity severity) const -{ - Index count = 0; - for (const auto& msg : diagnostics) + if (auto ptr = getInterface(guid)) { - count += Index(msg.severity == severity); + return ptr; } - return count; + return getObject(guid); } -void DownstreamDiagnostics::requireErrorDiagnostic() +void* CommandLineDownstreamArtifactRepresentation::getInterface(const Guid& guid) { - // If we find an error, we don't need to add a generic diagnostic - for (const auto& msg : diagnostics) + if (guid == ISlangUnknown::getTypeGuid() || + guid == ICastable::getTypeGuid() || + guid == IArtifactRepresentation::getTypeGuid()) { - if (Index(msg.severity) >= Index(DownstreamDiagnostic::Severity::Error)) - { - return; - } + IArtifactRepresentation* rep = this; + return rep; } - DownstreamDiagnostic diagnostic; - diagnostic.reset(); - diagnostic.severity = DownstreamDiagnostic::Severity::Error; - diagnostic.text = rawDiagnostics; - - // Add the diagnostic - diagnostics.add(diagnostic); -} - -Int DownstreamDiagnostics::countByStage(Diagnostic::Stage stage, Index counts[Int(Diagnostic::Severity::CountOf)]) const -{ - Int count = 0; - ::memset(counts, 0, sizeof(Index) * Int(Diagnostic::Severity::CountOf)); - for (const auto& diagnostic : diagnostics) - { - if (diagnostic.stage == stage) - { - count++; - counts[Index(diagnostic.severity)]++; - } - } - return count++; + return nullptr; } -static void _appendCounts(const Index counts[Int(DownstreamDiagnostic::Severity::CountOf)], StringBuilder& out) +void* CommandLineDownstreamArtifactRepresentation::getObject(const Guid& guid) { - typedef DownstreamDiagnostic::Severity Severity; - - for (Index i = 0; i < Int(Severity::CountOf); i++) - { - if (counts[i] > 0) - { - out << DownstreamDiagnostic::getSeverityText(Severity(i)) << "(" << counts[i] << ") "; - } - } + SLANG_UNUSED(guid); + return nullptr; } -static void _appendSimplified(const Index counts[Int(DownstreamDiagnostic::Severity::CountOf)], StringBuilder& out) +SlangResult CommandLineDownstreamArtifactRepresentation::createRepresentation(const Guid& typeGuid, ICastable** outCastable) { - typedef DownstreamDiagnostic::Severity Severity; - for (Index i = 0; i < Int(Severity::CountOf); i++) + if (typeGuid == ISlangSharedLibrary::getTypeGuid()) { - if (counts[i] > 0) + // Okay we want to load + // Try loading the shared library + SharedLibrary::Handle handle; + if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(m_moduleFilePath.getBuffer(), handle))) { - out << DownstreamDiagnostic::getSeverityText(Severity(i)) << " "; + return SLANG_FAIL; } - } -} -void DownstreamDiagnostics::appendSummary(StringBuilder& out) const -{ - Index counts[Int(Diagnostic::Severity::CountOf)]; - if (countByStage(Diagnostic::Stage::Compile, counts) > 0) - { - out << "Compile: "; - _appendCounts(counts, out); - out << "\n"; - } - if (countByStage(Diagnostic::Stage::Link, counts) > 0) - { - out << "Link: "; - _appendCounts(counts, out); - out << "\n"; - } -} - -void DownstreamDiagnostics::appendSimplifiedSummary(StringBuilder& out) const -{ - Index counts[Int(Diagnostic::Severity::CountOf)]; - if (countByStage(Diagnostic::Stage::Compile, counts) > 0) - { - out << "Compile: "; - _appendSimplified(counts, out); - out << "\n"; - } - if (countByStage(Diagnostic::Stage::Link, counts) > 0) - { - out << "Link: "; - _appendSimplified(counts, out); - out << "\n"; - } -} + // The shared library needs to keep temp files in scope + auto temporarySharedLibrary = new TemporarySharedLibrary(handle, m_moduleFilePath); + ComPtr<ISlangSharedLibrary> lib(temporarySharedLibrary); -void DownstreamDiagnostics::removeBySeverity(Diagnostic::Severity severity) -{ - Index count = diagnostics.getCount(); - for (Index i = 0; i < count; ++i) - { - if (diagnostics[i].severity == severity) - { - diagnostics.removeAt(i); - i--; - count--; - } - } -} + // Set any additional info on the non COM pointer + temporarySharedLibrary->m_temporaryFileSet = m_temporaryFiles; -/* static */void DownstreamDiagnostics::addNote(const UnownedStringSlice& in, List<DownstreamDiagnostic>& ioDiagnostics) -{ - // Don't bother adding an empty line - if (in.trim().getLength() == 0) - { - return; + *outCastable = lib.detach(); + return SLANG_OK; } - - // If there's nothing previous, we'll ignore too, as note should be in addition to - // a pre-existing error/warning - if (ioDiagnostics.getCount() == 0) + else if (typeGuid == ISlangBlob::getTypeGuid()) { - return; - } - - // Make it a note on the output - DownstreamDiagnostic diagnostic; - diagnostic.reset(); - diagnostic.severity = DownstreamDiagnostic::Severity::Info; - diagnostic.text = in; - ioDiagnostics.add(diagnostic); -} - -void DownstreamDiagnostics::addNote(const UnownedStringSlice& in) -{ - addNote(in, diagnostics); -} - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CommandLineDownstreamCompileResult !!!!!!!!!!!!!!!!!!!!!!*/ + List<uint8_t> contents; + // Read the binary + // Read the contents of the binary + SLANG_RETURN_ON_FAIL(File::readAllBytes(m_moduleFilePath, contents)); -SlangResult CommandLineDownstreamCompileResult::getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) -{ - if (m_hostCallableSharedLibrary) - { - outLibrary = m_hostCallableSharedLibrary; + *outCastable = CastableUtil::getCastable(ScopeRefObjectBlob::create(ListBlob::moveCreate(contents), m_temporaryFiles).detach()).detach(); return SLANG_OK; } - // Okay we want to load - // Try loading the shared library - SharedLibrary::Handle handle; - if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(m_moduleFilePath.getBuffer(), handle))) - { - return SLANG_FAIL; - } - - { - // The shared library needs to keep temp files in scope - auto temporarySharedLibrary = new TemporarySharedLibrary(handle, m_moduleFilePath); - // Make sure it gets a ref count - m_hostCallableSharedLibrary = temporarySharedLibrary; - // Set any additional info on the non COM pointer - temporarySharedLibrary->m_temporaryFileSet = m_temporaryFiles; - } - - outLibrary = m_hostCallableSharedLibrary; - return SLANG_OK; + return SLANG_E_NOT_AVAILABLE; } -SlangResult CommandLineDownstreamCompileResult::getBinary(ComPtr<ISlangBlob>& outBlob) +bool CommandLineDownstreamArtifactRepresentation::exists() { - if (m_binaryBlob) - { - outBlob = m_binaryBlob; - return SLANG_OK; - } - - List<uint8_t> contents; - // Read the binary - // Read the contents of the binary - SLANG_RETURN_ON_FAIL(File::readAllBytes(m_moduleFilePath, contents)); - - m_binaryBlob = ScopeRefObjectBlob::create(ListBlob::moveCreate(contents), m_temporaryFiles); - outBlob = m_binaryBlob; - return SLANG_OK; + return File::exists(m_moduleFilePath); } /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CommandLineDownstreamCompiler !!!!!!!!!!!!!!!!!!!!!!*/ @@ -392,7 +161,7 @@ static bool _isContentsInFile(const DownstreamCompileOptions& options) return false; } -SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptions, RefPtr<DownstreamCompileResult>& out) +SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptions, IArtifact** outArtifact) { // Copy the command line options CommandLine cmdLine(m_cmdLine); @@ -402,7 +171,6 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio // Find all the files that will be produced RefPtr<TemporaryFileSet> productFileSet(new TemporaryFileSet); - if (options.modulePath.getLength() == 0 || options.sourceContents.getLength() != 0) { String modulePath = options.modulePath; @@ -491,10 +259,19 @@ SlangResult CommandLineDownstreamCompiler::compile(const CompileOptions& inOptio } #endif - DownstreamDiagnostics diagnostics; + auto artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType); + + auto diagnostics = ArtifactDiagnostics::create(); + SLANG_RETURN_ON_FAIL(parseOutput(exeRes, diagnostics)); - out = new CommandLineDownstreamCompileResult(diagnostics, moduleFilePath, productFileSet); + // Add the artifact + artifact->addAssociated(diagnostics); + + ComPtr<IArtifactRepresentation> rep(new CommandLineDownstreamArtifactRepresentation(moduleFilePath, productFileSet)); + artifact->addRepresentation(rep); + + *outArtifact = artifact.detach(); return SLANG_OK; } |
