summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler-core')
-rw-r--r--source/compiler-core/slang-artifact-associated-impl.cpp169
-rw-r--r--source/compiler-core/slang-artifact-associated-impl.h60
-rw-r--r--source/compiler-core/slang-artifact-associated.h79
-rw-r--r--source/compiler-core/slang-artifact-diagnostic-util.cpp158
-rw-r--r--source/compiler-core/slang-artifact-diagnostic-util.h87
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.cpp21
-rw-r--r--source/compiler-core/slang-artifact-util.cpp2
-rw-r--r--source/compiler-core/slang-artifact-util.h1
-rw-r--r--source/compiler-core/slang-artifact.h36
-rw-r--r--source/compiler-core/slang-downstream-compiler.cpp331
-rw-r--r--source/compiler-core/slang-downstream-compiler.h166
-rw-r--r--source/compiler-core/slang-downstream-dep1.cpp134
-rw-r--r--source/compiler-core/slang-downstream-dep1.h59
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp51
-rw-r--r--source/compiler-core/slang-fxc-compiler.cpp44
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp85
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.h4
-rw-r--r--source/compiler-core/slang-glslang-compiler.cpp44
-rw-r--r--source/compiler-core/slang-nvrtc-compiler.cpp57
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.cpp55
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.h4
21 files changed, 913 insertions, 734 deletions
diff --git a/source/compiler-core/slang-artifact-associated-impl.cpp b/source/compiler-core/slang-artifact-associated-impl.cpp
index dcca24a7c..9b437b9c0 100644
--- a/source/compiler-core/slang-artifact-associated-impl.cpp
+++ b/source/compiler-core/slang-artifact-associated-impl.cpp
@@ -7,30 +7,63 @@
#include "../core/slang-io.h"
#include "../core/slang-array-view.h"
-#include "slang-artifact-util.h"
+#include "../core/slang-char-util.h"
+
+#include "slang-artifact-diagnostic-util.h"
namespace Slang {
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!! DiagnosticsImpl !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDiagnostics !!!!!!!!!!!!!!!!!!!!!!!!!!! */
-void* DiagnosticsImpl::getInterface(const Guid& guid)
+ArtifactDiagnostics::ArtifactDiagnostics(const ThisType& rhs):
+ m_result(rhs.m_result),
+ m_diagnostics(rhs.m_diagnostics),
+ m_raw(rhs.m_raw.getLength() + 1)
+{
+ // We need to be careful with raw, we want a new *copy* not a non atomic ref counting
+ // In initialization we should have enough space
+ m_raw.append(rhs.m_raw.getUnownedSlice());
+
+ // Reallocate all the strings
+ for (auto& diagnostic : m_diagnostics)
+ {
+ diagnostic.filePath = m_allocator.allocate(diagnostic.filePath);
+ diagnostic.code = m_allocator.allocate(diagnostic.code);
+ diagnostic.text = m_allocator.allocate(diagnostic.text);
+ }
+}
+
+void* ArtifactDiagnostics::clone(const Guid& guid)
+{
+ ThisType* copy = new ThisType(*this);
+ if (auto ptr = copy->castAs(guid))
+ {
+ return ptr;
+ }
+ // If the cast fails, we delete the item.
+ delete copy;
+ return nullptr;
+}
+
+void* ArtifactDiagnostics::getInterface(const Guid& guid)
{
if (guid == ISlangUnknown::getTypeGuid() ||
guid == ICastable::getTypeGuid() ||
- guid == IDiagnostics::getTypeGuid())
+ guid == IClonable::getTypeGuid() ||
+ guid == IArtifactDiagnostics::getTypeGuid())
{
- return static_cast<IDiagnostics*>(this);
+ return static_cast<IArtifactDiagnostics*>(this);
}
return nullptr;
}
-void* DiagnosticsImpl::getObject(const Guid& guid)
+void* ArtifactDiagnostics::getObject(const Guid& guid)
{
SLANG_UNUSED(guid);
return nullptr;
}
-void* DiagnosticsImpl::castAs(const Guid& guid)
+void* ArtifactDiagnostics::castAs(const Guid& guid)
{
if (auto intf = getInterface(guid))
{
@@ -39,42 +72,42 @@ void* DiagnosticsImpl::castAs(const Guid& guid)
return getObject(guid);
}
-void DiagnosticsImpl::reset()
+void ArtifactDiagnostics::reset()
{
m_diagnostics.clear();
- m_raw = ZeroTerminatedCharSlice();
+ m_raw.Clear();
m_result = SLANG_OK;
- m_arena.deallocateAll();
+ m_allocator.deallocateAll();
}
-ZeroTerminatedCharSlice DiagnosticsImpl::_allocateSlice(const Slice<char>& in)
-{
- if (in.count == 0)
- {
- return ZeroTerminatedCharSlice("", 0);
- }
- const char* dst = m_arena.allocateString(in.data, in.count);
- return ZeroTerminatedCharSlice(dst, in.count);
-}
-
-void DiagnosticsImpl::add(const Diagnostic& inDiagnostic)
+void ArtifactDiagnostics::add(const Diagnostic& inDiagnostic)
{
Diagnostic diagnostic(inDiagnostic);
- diagnostic.text = _allocateSlice(inDiagnostic.text);
- diagnostic.code = _allocateSlice(inDiagnostic.code);
- diagnostic.filePath = _allocateSlice(inDiagnostic.filePath);
+ diagnostic.text = m_allocator.allocate(inDiagnostic.text);
+ diagnostic.code = m_allocator.allocate(inDiagnostic.code);
+ diagnostic.filePath = m_allocator.allocate(inDiagnostic.filePath);
m_diagnostics.add(diagnostic);
}
-void DiagnosticsImpl::setRaw(const ZeroTerminatedCharSlice& slice)
+void ArtifactDiagnostics::setRaw(const CharSlice& slice)
+{
+ m_raw.Clear();
+ m_raw << asStringSlice(slice);
+}
+
+void ArtifactDiagnostics::appendRaw(const CharSlice& slice)
{
- m_raw = _allocateSlice(slice);
+ if (m_raw.getLength() && m_raw[m_raw.getLength() - 1] != '\n')
+ {
+ m_raw.appendChar('\n');
+ }
+ m_raw << asStringSlice(slice);
}
-Count DiagnosticsImpl::getCountAtLeastSeverity(Severity severity)
+Count ArtifactDiagnostics::getCountAtLeastSeverity(Diagnostic::Severity severity)
{
Index count = 0;
for (const auto& msg : m_diagnostics)
@@ -84,7 +117,7 @@ Count DiagnosticsImpl::getCountAtLeastSeverity(Severity severity)
return count;
}
-Count DiagnosticsImpl::getCountBySeverity(Severity severity)
+Count ArtifactDiagnostics::getCountBySeverity(Diagnostic::Severity severity)
{
Index count = 0;
for (const auto& msg : m_diagnostics)
@@ -94,7 +127,7 @@ Count DiagnosticsImpl::getCountBySeverity(Severity severity)
return count;
}
-bool DiagnosticsImpl::hasOfAtLeastSeverity(Severity severity)
+bool ArtifactDiagnostics::hasOfAtLeastSeverity(Diagnostic::Severity severity)
{
for (const auto& msg : m_diagnostics)
{
@@ -106,10 +139,10 @@ bool DiagnosticsImpl::hasOfAtLeastSeverity(Severity severity)
return false;
}
-Count DiagnosticsImpl::getCountByStage(Stage stage, Count outCounts[Int(Severity::CountOf)])
+Count ArtifactDiagnostics::getCountByStage(Diagnostic::Stage stage, Count outCounts[Int(Diagnostic::Severity::CountOf)])
{
Int count = 0;
- ::memset(outCounts, 0, sizeof(Index) * Int(Severity::CountOf));
+ ::memset(outCounts, 0, sizeof(Index) * Int(Diagnostic::Severity::CountOf));
for (const auto& diagnostic : m_diagnostics)
{
if (diagnostic.stage == stage)
@@ -121,7 +154,7 @@ Count DiagnosticsImpl::getCountByStage(Stage stage, Count outCounts[Int(Severity
return count++;
}
-void DiagnosticsImpl::removeBySeverity(Severity severity)
+void ArtifactDiagnostics::removeBySeverity(Diagnostic::Severity severity)
{
Index count = m_diagnostics.getCount();
for (Index i = 0; i < count; ++i)
@@ -135,51 +168,33 @@ void DiagnosticsImpl::removeBySeverity(Severity severity)
}
}
-void DiagnosticsImpl::maybeAddNote(const ZeroTerminatedCharSlice& in)
+void ArtifactDiagnostics::maybeAddNote(const CharSlice& in)
{
- // Don't bother adding an empty line
- if (UnownedStringSlice(in.begin(), in.end()).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 (m_diagnostics.getCount() == 0)
- {
- return;
- }
-
- // Make it a note on the output
- Diagnostic diagnostic;
-
- diagnostic.severity = Severity::Info;
- diagnostic.text = _allocateSlice(in);
- m_diagnostics.add(diagnostic);
+ ArtifactDiagnosticUtil::maybeAddNote(asStringSlice(in), this);
}
-void DiagnosticsImpl::requireErrorDiagnostic()
+void ArtifactDiagnostics::requireErrorDiagnostic()
{
// If we find an error, we don't need to add a generic diagnostic
for (const auto& msg : m_diagnostics)
{
- if (Index(msg.severity) >= Index(Severity::Error))
+ if (Index(msg.severity) >= Index(Diagnostic::Severity::Error))
{
return;
}
}
Diagnostic diagnostic;
- diagnostic.severity = Severity::Error;
- diagnostic.text = m_raw;
+ diagnostic.severity = Diagnostic::Severity::Error;
+ diagnostic.text = m_allocator.allocate(m_raw);
// Add the diagnostic
m_diagnostics.add(diagnostic);
}
-/* static */UnownedStringSlice _getSeverityText(IDiagnostics::Severity severity)
+/* static */UnownedStringSlice _getSeverityText(ArtifactDiagnostic::Severity severity)
{
- typedef IDiagnostics::Severity Severity;
+ typedef ArtifactDiagnostic::Severity Severity;
switch (severity)
{
default: return UnownedStringSlice::fromLiteral("Unknown");
@@ -189,9 +204,9 @@ void DiagnosticsImpl::requireErrorDiagnostic()
}
}
-static void _appendCounts(const Index counts[Int(IDiagnostics::Severity::CountOf)], StringBuilder& out)
+static void _appendCounts(const Index counts[Int(ArtifactDiagnostic::Severity::CountOf)], StringBuilder& out)
{
- typedef IDiagnostics::Severity Severity;
+ typedef ArtifactDiagnostic::Severity Severity;
for (Index i = 0; i < Int(Severity::CountOf); i++)
{
@@ -202,9 +217,9 @@ static void _appendCounts(const Index counts[Int(IDiagnostics::Severity::CountOf
}
}
-static void _appendSimplified(const Index counts[Int(IDiagnostics::Severity::CountOf)], StringBuilder& out)
+static void _appendSimplified(const Index counts[Int(ArtifactDiagnostic::Severity::CountOf)], StringBuilder& out)
{
- typedef IDiagnostics::Severity Severity;
+ typedef ArtifactDiagnostic::Severity Severity;
for (Index i = 0; i < Int(Severity::CountOf); i++)
{
if (counts[i] > 0)
@@ -214,18 +229,18 @@ static void _appendSimplified(const Index counts[Int(IDiagnostics::Severity::Cou
}
}
-void DiagnosticsImpl::appendSummary(ISlangBlob** outBlob)
+void ArtifactDiagnostics::calcSummary(ISlangBlob** outBlob)
{
StringBuilder buf;
- Index counts[Int(Severity::CountOf)];
- if (getCountByStage(Stage::Compile, counts) > 0)
+ Index counts[Int(Diagnostic::Severity::CountOf)];
+ if (getCountByStage(Diagnostic::Stage::Compile, counts) > 0)
{
buf << "Compile: ";
_appendCounts(counts, buf);
buf << "\n";
}
- if (getCountByStage(Stage::Link, counts) > 0)
+ if (getCountByStage(Diagnostic::Stage::Link, counts) > 0)
{
buf << "Link: ";
_appendCounts(counts, buf);
@@ -235,18 +250,18 @@ void DiagnosticsImpl::appendSummary(ISlangBlob** outBlob)
*outBlob = StringBlob::moveCreate(buf).detach();
}
-void DiagnosticsImpl::appendSimplifiedSummary(ISlangBlob** outBlob)
+void ArtifactDiagnostics::calcSimplifiedSummary(ISlangBlob** outBlob)
{
StringBuilder buf;
- Index counts[Int(Severity::CountOf)];
- if (getCountByStage(Stage::Compile, counts) > 0)
+ Index counts[Int(Diagnostic::Severity::CountOf)];
+ if (getCountByStage(Diagnostic::Stage::Compile, counts) > 0)
{
buf << "Compile: ";
_appendSimplified(counts, buf);
buf << "\n";
}
- if (getCountByStage(Stage::Link, counts) > 0)
+ if (getCountByStage(Diagnostic::Stage::Link, counts) > 0)
{
buf << "Link: ";
_appendSimplified(counts, buf);
@@ -256,20 +271,20 @@ void DiagnosticsImpl::appendSimplifiedSummary(ISlangBlob** outBlob)
*outBlob = StringBlob::moveCreate(buf).detach();
}
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataImpl !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactPostEmitMetadata !!!!!!!!!!!!!!!!!!!!!!!!!!! */
-void* PostEmitMetadataImpl::getInterface(const Guid& guid)
+void* ArtifactPostEmitMetadata::getInterface(const Guid& guid)
{
if (guid == ISlangUnknown::getTypeGuid() ||
guid == ICastable::getTypeGuid() ||
- guid == IPostEmitMetadata::getTypeGuid())
+ guid == IArtifactPostEmitMetadata::getTypeGuid())
{
- return static_cast<IPostEmitMetadata*>(this);
+ return static_cast<IArtifactPostEmitMetadata*>(this);
}
return nullptr;
}
-void* PostEmitMetadataImpl::getObject(const Guid& uuid)
+void* ArtifactPostEmitMetadata::getObject(const Guid& uuid)
{
if (uuid == getTypeGuid())
{
@@ -278,7 +293,7 @@ void* PostEmitMetadataImpl::getObject(const Guid& uuid)
return nullptr;
}
-void* PostEmitMetadataImpl::castAs(const Guid& guid)
+void* ArtifactPostEmitMetadata::castAs(const Guid& guid)
{
if (auto ptr = getInterface(guid))
{
@@ -287,7 +302,7 @@ void* PostEmitMetadataImpl::castAs(const Guid& guid)
return getObject(guid);
}
-Slice<ShaderBindingRange> PostEmitMetadataImpl::getUsedBindingRanges()
+Slice<ShaderBindingRange> ArtifactPostEmitMetadata::getUsedBindingRanges()
{
return Slice<ShaderBindingRange>(m_usedBindings.getBuffer(), m_usedBindings.getCount());
}
diff --git a/source/compiler-core/slang-artifact-associated-impl.h b/source/compiler-core/slang-artifact-associated-impl.h
index eef965e3e..415e01494 100644
--- a/source/compiler-core/slang-artifact-associated-impl.h
+++ b/source/compiler-core/slang-artifact-associated-impl.h
@@ -10,16 +10,24 @@
#include "slang-artifact-associated.h"
+#include "slang-artifact-util.h"
+
+#include "slang-artifact-diagnostic-util.h"
+
namespace Slang
{
-class DiagnosticsImpl : public ComBaseObject, public IDiagnostics
+class ArtifactDiagnostics : public ComBaseObject, public IArtifactDiagnostics
{
public:
+ typedef ArtifactDiagnostics ThisType;
+
SLANG_COM_BASE_IUNKNOWN_ALL
// ICastable
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+ // IClonable
+ SLANG_NO_THROW virtual void* SLANG_MCALL clone(const Guid& intf) SLANG_OVERRIDE;
// IDiagnostic
SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) SLANG_OVERRIDE { return &m_diagnostics[i]; }
SLANG_NO_THROW virtual Count SLANG_MCALL getCount() SLANG_OVERRIDE { return m_diagnostics.getCount(); }
@@ -27,42 +35,42 @@ public:
SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) SLANG_OVERRIDE { m_diagnostics.removeAt(i); }
SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() SLANG_OVERRIDE { return m_result; }
SLANG_NO_THROW virtual void SLANG_MCALL setResult(SlangResult res) SLANG_OVERRIDE { m_result = res; }
- SLANG_NO_THROW virtual void SLANG_MCALL setRaw(const ZeroTerminatedCharSlice& slice) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual ZeroTerminatedCharSlice SLANG_MCALL getRaw() SLANG_OVERRIDE { return m_raw; }
+ SLANG_NO_THROW virtual void SLANG_MCALL setRaw(const CharSlice& slice) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual void SLANG_MCALL appendRaw(const CharSlice& slice) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual TerminatedCharSlice SLANG_MCALL getRaw() SLANG_OVERRIDE { return CharSliceCaster::asTerminatedCharSlice(m_raw); }
SLANG_NO_THROW virtual void SLANG_MCALL reset() SLANG_OVERRIDE;
- SLANG_NO_THROW virtual Count SLANG_MCALL getCountAtLeastSeverity(Severity severity) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual Count SLANG_MCALL getCountBySeverity(Severity severity) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual bool SLANG_MCALL hasOfAtLeastSeverity(Severity severity) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual Count SLANG_MCALL getCountByStage(Stage stage, Count outCounts[Int(Severity::CountOf)]) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual void SLANG_MCALL removeBySeverity(Severity severity) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual void SLANG_MCALL maybeAddNote(const ZeroTerminatedCharSlice& in) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual Count SLANG_MCALL getCountAtLeastSeverity(Diagnostic::Severity severity) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual Count SLANG_MCALL getCountBySeverity(Diagnostic::Severity severity) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual bool SLANG_MCALL hasOfAtLeastSeverity(Diagnostic::Severity severity) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual Count SLANG_MCALL getCountByStage(Diagnostic::Stage stage, Count outCounts[Int(Diagnostic::Severity::CountOf)]) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual void SLANG_MCALL removeBySeverity(Diagnostic::Severity severity) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual void SLANG_MCALL maybeAddNote(const CharSlice& in) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL requireErrorDiagnostic() SLANG_OVERRIDE;
- SLANG_NO_THROW virtual void SLANG_MCALL appendSummary(ISlangBlob** outBlob) SLANG_OVERRIDE;
- SLANG_NO_THROW virtual void SLANG_MCALL appendSimplifiedSummary(ISlangBlob** outBlob) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual void SLANG_MCALL calcSummary(ISlangBlob** outBlob) SLANG_OVERRIDE;
+ SLANG_NO_THROW virtual void SLANG_MCALL calcSimplifiedSummary(ISlangBlob** outBlob) SLANG_OVERRIDE;
- DiagnosticsImpl():
- m_arena(1024)
- {
- }
+ /// Default ctor
+ ArtifactDiagnostics() {}
+ /// Copy ctor
+ ArtifactDiagnostics(const ThisType& rhs);
+
+ /// Create
+ static ComPtr<IArtifactDiagnostics> create() { return ComPtr<IArtifactDiagnostics>(new ThisType); }
protected:
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
- ZeroTerminatedCharSlice _allocateSlice(const Slice<char>& in);
-
- // We could consider storing paths, codes in StringSlicePool, but for now we just allocate all 'string type things'
- // in the arena.
- MemoryArena m_arena;
+ CharSliceAllocator m_allocator;
List<Diagnostic> m_diagnostics;
SlangResult m_result = SLANG_OK;
// Raw diagnostics
- ZeroTerminatedCharSlice m_raw;
+ StringBuilder m_raw;
};
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataImpl !!!!!!!!!!!!!!!!!!!!!!!!!! */
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactPostEmitMetadata !!!!!!!!!!!!!!!!!!!!!!!!!! */
struct ShaderBindingRange
{
@@ -133,9 +141,11 @@ struct ShaderBindingRange
}
};
-class PostEmitMetadataImpl : public ComBaseObject, public IPostEmitMetadata
+class ArtifactPostEmitMetadata : public ComBaseObject, public IArtifactPostEmitMetadata
{
public:
+ typedef ArtifactPostEmitMetadata ThisType;
+
SLANG_CLASS_GUID(0x6f82509f, 0xe48b, 0x4b83, { 0xa3, 0x84, 0x5d, 0x70, 0x83, 0x19, 0x83, 0xcc })
SLANG_COM_BASE_IUNKNOWN_ALL
@@ -143,12 +153,14 @@ public:
// ICastable
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
- // IPostEmitMetadata
+ // IArtifactPostEmitMetadata
SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getUsedBindingRanges() SLANG_OVERRIDE;
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
+ static ComPtr<IArtifactPostEmitMetadata> create() { return ComPtr<IArtifactPostEmitMetadata>(new ThisType); }
+
List<ShaderBindingRange> m_usedBindings;
};
diff --git a/source/compiler-core/slang-artifact-associated.h b/source/compiler-core/slang-artifact-associated.h
index e3dd83062..f63b8a673 100644
--- a/source/compiler-core/slang-artifact-associated.h
+++ b/source/compiler-core/slang-artifact-associated.h
@@ -7,15 +7,11 @@
namespace Slang
{
-/* Diagnostics.
-
-If there are raw diagnostics they can be associated to an artifact as (Kind::Text, Payload::Diagnostics) artifact */
-class IDiagnostics : public ICastable
+struct ArtifactDiagnostic
{
-public:
- SLANG_COM_INTERFACE(0x91f9b857, 0xcd6b, 0x45ca, { 0x8e, 0x3, 0x8f, 0xa3, 0x3c, 0x5c, 0xf0, 0x1a });
+ typedef ArtifactDiagnostic ThisType;
- enum class Severity
+ enum class Severity : uint8_t
{
Unknown,
Info,
@@ -23,7 +19,7 @@ public:
Error,
CountOf,
};
- enum class Stage
+ enum class Stage : uint8_t
{
Compile,
Link,
@@ -31,19 +27,42 @@ public:
struct Location
{
+ typedef Location ThisType;
+ bool operator==(const ThisType& rhs) const { return line == rhs.line && column == rhs.column; }
+ bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
Int line = 0; ///< One indexed line number. 0 if not defined
Int column = 0; ///< One indexed *character (not byte)* column number. 0 if not defined
};
- struct Diagnostic
+ bool operator==(const ThisType& rhs) const
{
- Severity severity = Severity::Unknown; ///< The severity of error
- Stage stage = Stage::Compile; ///< The stage the error came from
- ZeroTerminatedCharSlice text; ///< The text of the error
- ZeroTerminatedCharSlice code; ///< The compiler specific error code
- ZeroTerminatedCharSlice filePath; ///< The path the error originated from
- Location location;
- };
+ return severity == rhs.severity &&
+ stage == rhs.stage &&
+ text == rhs.text &&
+ code == rhs.code &&
+ location == rhs.location;
+ }
+ bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
+ Severity severity = Severity::Unknown; ///< The severity of error
+ Stage stage = Stage::Compile; ///< The stage the error came from
+ TerminatedCharSlice text; ///< The text of the error
+ TerminatedCharSlice code; ///< The compiler specific error code
+ TerminatedCharSlice filePath; ///< The path the error originated from
+ Location location; ///< The location of the diagnostic in the filePath
+};
+
+/* Artifact diagnostics interface.
+
+IArtifactDiagnostics are added as associated types on an IArtifact typically.
+*/
+class IArtifactDiagnostics : public IClonable
+{
+public:
+ SLANG_COM_INTERFACE(0x91f9b857, 0xcd6b, 0x45ca, { 0x8e, 0x3, 0x8f, 0xa3, 0x3c, 0x5c, 0xf0, 0x1a });
+
+ typedef ArtifactDiagnostic Diagnostic;
/// Get the diagnostic at the index
SLANG_NO_THROW virtual const Diagnostic* SLANG_MCALL getAt(Index i) = 0;
@@ -55,9 +74,11 @@ public:
SLANG_NO_THROW virtual void SLANG_MCALL removeAt(Index i) = 0;
/// Get raw diagnostics information
- SLANG_NO_THROW virtual ZeroTerminatedCharSlice SLANG_MCALL getRaw() = 0;
+ SLANG_NO_THROW virtual TerminatedCharSlice SLANG_MCALL getRaw() = 0;
/// Set the raw diagnostic info
- SLANG_NO_THROW virtual void SLANG_MCALL setRaw(const ZeroTerminatedCharSlice& slice) = 0;
+ SLANG_NO_THROW virtual void SLANG_MCALL setRaw(const CharSlice& slice) = 0;
+ /// Append to the raw diagnostic
+ SLANG_NO_THROW virtual void SLANG_MCALL appendRaw(const CharSlice& slice) = 0;
/// Get the result for a compilation
SLANG_NO_THROW virtual SlangResult SLANG_MCALL getResult() = 0;
@@ -68,35 +89,35 @@ public:
SLANG_NO_THROW virtual void SLANG_MCALL reset() = 0;
/// Count the number of diagnostics which have 'severity' or greater
- SLANG_NO_THROW virtual Count SLANG_MCALL getCountAtLeastSeverity(Severity severity) = 0;
+ SLANG_NO_THROW virtual Count SLANG_MCALL getCountAtLeastSeverity(Diagnostic::Severity severity) = 0;
/// Get the number of diagnostics by severity
- SLANG_NO_THROW virtual Count SLANG_MCALL getCountBySeverity(Severity severity) = 0;
+ SLANG_NO_THROW virtual Count SLANG_MCALL getCountBySeverity(Diagnostic::Severity severity) = 0;
/// True if there are any diagnostics of severity or worse
- SLANG_NO_THROW virtual bool SLANG_MCALL hasOfAtLeastSeverity(Severity severity) = 0;
+ SLANG_NO_THROW virtual bool SLANG_MCALL hasOfAtLeastSeverity(Diagnostic::Severity severity) = 0;
/// Stores in outCounts, the amount of diagnostics for the stage of each severity
- SLANG_NO_THROW virtual Count SLANG_MCALL getCountByStage(Stage stage, Count outCounts[Int(Severity::CountOf)]) = 0;
+ SLANG_NO_THROW virtual Count SLANG_MCALL getCountByStage(Diagnostic::Stage stage, Count outCounts[Int(Diagnostic::Severity::CountOf)]) = 0;
/// Remove all diagnostics of the type
- SLANG_NO_THROW virtual void SLANG_MCALL removeBySeverity(Severity severity) = 0;
+ SLANG_NO_THROW virtual void SLANG_MCALL removeBySeverity(Diagnostic::Severity severity) = 0;
/// Add a note
- SLANG_NO_THROW virtual void SLANG_MCALL maybeAddNote(const ZeroTerminatedCharSlice& in) = 0;
+ SLANG_NO_THROW virtual void SLANG_MCALL maybeAddNote(const CharSlice& in) = 0;
/// If there are no error diagnostics, adds a generic error diagnostic
SLANG_NO_THROW virtual void SLANG_MCALL requireErrorDiagnostic() = 0;
- /// Append a summary to out
- SLANG_NO_THROW virtual void SLANG_MCALL appendSummary(ISlangBlob** outBlob) = 0;
- /// Appends a summary that just identifies if there is an error of a type (not a count)
- SLANG_NO_THROW virtual void SLANG_MCALL appendSimplifiedSummary(ISlangBlob** outBlob) = 0;
+ /// Creates summary text and place in outBlob
+ SLANG_NO_THROW virtual void SLANG_MCALL calcSummary(ISlangBlob** outBlob) = 0;
+ /// Creates a simplified summary text and places it in out blob
+ SLANG_NO_THROW virtual void SLANG_MCALL calcSimplifiedSummary(ISlangBlob** outBlob) = 0;
};
struct ShaderBindingRange;
-class IPostEmitMetadata : public ICastable
+class IArtifactPostEmitMetadata : public ICastable
{
public:
SLANG_COM_INTERFACE(0x5d03bce9, 0xafb1, 0x4fc8, { 0xa4, 0x6f, 0x3c, 0xe0, 0x7b, 0x6, 0x1b, 0x1b });
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
diff --git a/source/compiler-core/slang-artifact-diagnostic-util.h b/source/compiler-core/slang-artifact-diagnostic-util.h
new file mode 100644
index 000000000..5a98acd22
--- /dev/null
+++ b/source/compiler-core/slang-artifact-diagnostic-util.h
@@ -0,0 +1,87 @@
+// slang-artifact-diagnostic-util.h
+#ifndef SLANG_ARTIFACT_DIAGNOSTIC_UTIL_H
+#define SLANG_ARTIFACT_DIAGNOSTIC_UTIL_H
+
+#include "slang-artifact.h"
+
+#include "slang-artifact-associated.h"
+
+#include "../core/slang-memory-arena.h"
+
+namespace Slang
+{
+
+/*
+The reason to wrap in a struct rathan than have as free functions is doing so will lead to compile time
+errors with incorrect usage around temporarires.
+*/
+struct CharSliceCaster
+{
+ /// The slice will only be in scope whilst the string is
+ static TerminatedCharSlice asTerminatedCharSlice(const String& in) { auto unowned = in.getUnownedSlice(); return TerminatedCharSlice(unowned.begin(), unowned.getLength()); }
+
+ static CharSlice asCharSlice(const String& in) { auto unowned = in.getUnownedSlice(); return CharSlice(unowned.begin(), unowned.getLength()); }
+
+private:
+ // We don't want temporaries to be 'asSliced' so disable
+ static TerminatedCharSlice asTerminatedCharSlice(const String&& in) = delete;
+ static CharSlice asCharSlice(const String&& in) = delete;
+};
+
+SLANG_FORCE_INLINE UnownedStringSlice asStringSlice(const CharSlice& slice)
+{
+ return UnownedStringSlice(slice.begin(), slice.end());
+}
+
+SLANG_FORCE_INLINE CharSlice asCharSlice(const UnownedStringSlice& slice)
+{
+ return CharSlice(slice.begin(), slice.getLength());
+}
+
+struct CharSliceAllocator
+{
+ TerminatedCharSlice allocate(const Slice<char>& slice);
+ TerminatedCharSlice allocate(const UnownedStringSlice& slice);
+ TerminatedCharSlice allocate(const String& in) { return allocate(in.getUnownedSlice()); }
+ TerminatedCharSlice allocate(const char* in);
+ TerminatedCharSlice allocate(const char* start, const char* end) { return allocate(UnownedStringSlice(start, end)); }
+
+ void deallocateAll() { m_arena.deallocateAll(); }
+
+ CharSliceAllocator():
+ m_arena(1024)
+ {
+ }
+protected:
+
+ MemoryArena m_arena;
+};
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDiagnosticUtil !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+struct ArtifactDiagnosticUtil
+{
+ typedef ArtifactDiagnostic::Severity Severity;
+
+ /// Given severity return as text
+ static UnownedStringSlice getSeverityText(Severity severity);
+
+ /// Given a path, that holds line number and potentially column number in () after path, writes result into outDiagnostic
+ static SlangResult splitPathLocation(CharSliceAllocator& allocator, const UnownedStringSlice& pathLocation, ArtifactDiagnostic& outDiagnostic);
+
+ /// Split the line (separated by :), where a path is at pathIndex
+ static SlangResult splitColonDelimitedLine(const UnownedStringSlice& line, Int pathIndex, List<UnownedStringSlice>& outSlices);
+
+ typedef SlangResult(*LineParser)(CharSliceAllocator& allocator, const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, ArtifactDiagnostic& outDiagnostic);
+
+ /// Given diagnostics in inText that are colon delimited, use lineParser to do per line parsing.
+ static SlangResult parseColonDelimitedDiagnostics(CharSliceAllocator& allocator, const UnownedStringSlice& inText, Int pathIndex, LineParser lineParser, IArtifactDiagnostics* diagnostics);
+
+ /// Maybe add a note
+ static void maybeAddNote(const UnownedStringSlice& in, IArtifactDiagnostics* diagnostics);
+};
+
+
+} // namespace Slang
+
+#endif
diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp
index c342becec..028fa1bb9 100644
--- a/source/compiler-core/slang-artifact-handler-impl.cpp
+++ b/source/compiler-core/slang-artifact-handler-impl.cpp
@@ -14,9 +14,6 @@
#include "../core/slang-io.h"
#include "../core/slang-shared-library.h"
-// For workaround for DownstreamResult
-#include "slang-downstream-dep1.h"
-
namespace Slang {
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -129,24 +126,6 @@ SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifac
}
}
- // TODO(JS): Temporary whilst DownstreamCompileResult is
- // Special handling for DownstreamCompileResult
- if (auto downstreamResult = findRepresentation<DownstreamCompileResult>(artifact))
- {
- if (guid == ISlangBlob::getTypeGuid())
- {
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(downstreamResult->getBinary(blob));
- return _addRepresentation(artifact, keep, blob, outCastable);
- }
- else if (guid == ISlangSharedLibrary::getTypeGuid())
- {
- ComPtr<ISlangSharedLibrary> lib;
- SLANG_RETURN_ON_FAIL(DownstreamUtil_Dep1::getDownstreamSharedLibrary(downstreamResult, lib));
- return _addRepresentation(artifact, keep, lib, outCastable);
- }
- }
-
// We can ask each representation if they can do the conversion to the type, if they can we just use that
for (ICastable* castable : reps)
{
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
index fb3157522..a09454998 100644
--- a/source/compiler-core/slang-artifact-util.cpp
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -12,6 +12,8 @@
namespace Slang {
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
/* static */ComPtr<IArtifactContainer> ArtifactUtil::createContainer(const ArtifactDesc& desc)
{
const auto containerDesc = ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults, desc.style);
diff --git a/source/compiler-core/slang-artifact-util.h b/source/compiler-core/slang-artifact-util.h
index c4768a7b8..dc370b557 100644
--- a/source/compiler-core/slang-artifact-util.h
+++ b/source/compiler-core/slang-artifact-util.h
@@ -10,7 +10,6 @@ namespace Slang
struct ArtifactUtil
{
-
/// Get the base name of this artifact.
/// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
/// Else if there is an explicit name set, this is returned.
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index c54282c09..ee5f6b61d 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -9,7 +9,6 @@
namespace Slang
{
-
/* Simplest slice types. We can't use UnownedStringSlice etc, because they implement functionality in libraries,
and we want to use these types in headers.
If we wanted a C implementation it would be easy to use a macro to generate the functionality */
@@ -30,12 +29,30 @@ struct Slice
Count count;
};
-struct ZeroTerminatedCharSlice : Slice<char>
+struct CharSlice : public Slice<char>
{
+ typedef CharSlice ThisType;
typedef Slice<char> Super;
- explicit ZeroTerminatedCharSlice(const char* in) :Super(in, ::strlen(in)) {}
- ZeroTerminatedCharSlice(const char* in, Count inCount) :Super(in, inCount) { SLANG_ASSERT(in[inCount] == 0); }
- ZeroTerminatedCharSlice() :Super("", 0) {}
+
+ bool operator==(const ThisType& rhs) const { return count == rhs.count && (data == rhs.data || ::memcmp(data, rhs.data, count) == 0); }
+ bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
+ explicit CharSlice(const char* in) :Super(in, ::strlen(in)) {}
+ CharSlice(const char* in, Count inCount) :Super(in, inCount) {}
+ CharSlice() :Super(nullptr, 0) {}
+};
+
+struct TerminatedCharSlice : public CharSlice
+{
+ typedef TerminatedCharSlice ThisType;
+ typedef CharSlice Super;
+
+ SLANG_FORCE_INLINE bool operator==(const ThisType& rhs) const { return Super::operator==(rhs); }
+ SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
+
+ explicit TerminatedCharSlice(const char* in) :Super(in) {}
+ TerminatedCharSlice(const char* in, Count inCount) :Super(in, inCount) { SLANG_ASSERT(in[inCount] == 0); }
+ TerminatedCharSlice() :Super("", 0) {}
};
/* As a rule of thumb, if we can define some aspect in a hierarchy then we should do so at the highest level.
@@ -386,6 +403,15 @@ public:
virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) = 0;
};
+/* Interface for an artifact that *contain* a hierarchy of other child artifacts.
+
+Containment is a different concept to *association*. An association can hold any interface, and associations are for
+objects that are associated with an artifact - like diagnostics or meta data. Children artifacts can build up hierarchies
+and the children can be thought to be contained by the artifact they are a child of.
+
+The IArtifactContainer interface exists additionally to provide some type safety, and make it clear
+in code where a container or just 'an artifact' is required.
+*/
class IArtifactContainer : public IArtifact
{
public:
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;
}
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index ece6c1c51..997a2b099 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -14,147 +14,13 @@
#include "../../slang-com-ptr.h"
#include "slang-artifact.h"
+#include "slang-artifact-associated.h"
namespace Slang
{
struct SourceManager;
-struct DownstreamDiagnostic
-{
- typedef DownstreamDiagnostic ThisType;
-
- enum class Severity
- {
- Unknown,
- Info,
- Warning,
- Error,
- CountOf,
- };
- enum class Stage
- {
- Compile,
- Link,
- };
-
- void reset()
- {
- severity = Severity::Unknown;
- stage = Stage::Compile;
- fileLine = 0;
- }
-
- bool operator==(const ThisType& rhs) const
- {
- return severity == rhs.severity &&
- stage == rhs.stage &&
- text == rhs.text &&
- code == rhs.code &&
- filePath == rhs.filePath &&
- fileLine == rhs.fileLine;
- }
- bool operator!=(const ThisType& rhs) const { return !(*this == rhs); }
-
- static UnownedStringSlice getSeverityText(Severity severity);
-
- /// Given a path, that holds line number and potentially column number in () after path, writes result into outDiagnostic
- static SlangResult splitPathLocation(const UnownedStringSlice& pathLocation, DownstreamDiagnostic& outDiagnostic);
-
- /// Split the line (separated by :), where a path is at pathIndex
- static SlangResult splitColonDelimitedLine(const UnownedStringSlice& line, Int pathIndex, List<UnownedStringSlice>& outSlices);
-
- typedef SlangResult (*LineParser)(const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, DownstreamDiagnostic& outDiagnostic);
-
- /// Given diagnostics in inText that are colon delimited, use lineParser to do per line parsing.
- static SlangResult parseColonDelimitedDiagnostics(const UnownedStringSlice& inText, Int pathIndex, LineParser lineParser, List<DownstreamDiagnostic>& outDiagnostics);
-
- Severity severity = Severity::Unknown; ///< The severity of error
- Stage stage = Stage::Compile; ///< The stage the error came from
- String text; ///< The text of the error
- String code; ///< The compiler specific error code
- String filePath; ///< The path the error originated from
- Int fileLine = 0; ///< The line number the error came from
-};
-
-struct DownstreamDiagnostics
-{
- typedef DownstreamDiagnostic Diagnostic;
-
- /// Reset to an initial empty state
- void reset() { diagnostics.clear(); rawDiagnostics = String(); result = SLANG_OK; }
-
- /// Count the number of diagnostics which have 'severity' or greater
- Index getCountAtLeastSeverity(Diagnostic::Severity severity) const;
-
- /// Get the number of diagnostics by severity
- Index getCountBySeverity(Diagnostic::Severity severity) const;
- /// True if there are any diagnostics of severity
- bool has(Diagnostic::Severity severity) const { return getCountBySeverity(severity) > 0; }
-
- /// Stores in outCounts, the amount of diagnostics for the stage of each severity
- Int countByStage(Diagnostic::Stage stage, Index outCounts[Int(Diagnostic::Severity::CountOf)]) const;
-
- /// Append a summary to out
- void appendSummary(StringBuilder& out) const;
- /// Appends a summary that just identifies if there is an error of a type (not a count)
- void appendSimplifiedSummary(StringBuilder& out) const;
-
- /// Remove all diagnostics of the type
- void removeBySeverity(Diagnostic::Severity severity);
-
- /// Add a note
- void addNote(const UnownedStringSlice& in);
-
- /// If there are no error diagnostics, adds a generic error diagnostic
- void requireErrorDiagnostic();
-
- static void addNote(const UnownedStringSlice& in, List<DownstreamDiagnostic>& ioDiagnostics);
-
- String rawDiagnostics;
-
- SlangResult result = SLANG_OK;
- List<Diagnostic> diagnostics;
-};
-
-class DownstreamCompileResult : public RefObject
-{
-public:
- SLANG_CLASS_GUID(0xdfc5d318, 0x8675, 0x40ef, { 0xbd, 0x7b, 0x4, 0xa4, 0xff, 0x66, 0x11, 0x30 })
-
- virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) = 0;
- virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) = 0;
-
- const DownstreamDiagnostics& getDiagnostics() const { return m_diagnostics; }
-
- /// Ctor
- DownstreamCompileResult(const DownstreamDiagnostics& diagnostics):
- m_diagnostics(diagnostics)
- {}
-
-protected:
- DownstreamDiagnostics m_diagnostics;
-};
-
-
-class BlobDownstreamCompileResult : public DownstreamCompileResult
-{
-public:
- typedef DownstreamCompileResult Super;
-
- virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) SLANG_OVERRIDE { SLANG_UNUSED(outLibrary); return SLANG_FAIL; }
- virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) SLANG_OVERRIDE { outBlob = m_blob; return m_blob ? SLANG_OK : SLANG_FAIL; }
-
- BlobDownstreamCompileResult(const DownstreamDiagnostics& diags, ISlangBlob* blob):
- Super(diags),
- m_blob(blob)
- {
-
- }
-protected:
- ComPtr<ISlangBlob> m_blob;
-};
-
// Compiler description
struct DownstreamCompilerDesc
{
@@ -320,8 +186,7 @@ public:
typedef DownstreamCompilerDesc Desc;
typedef DownstreamCompileOptions CompileOptions;
- typedef DownstreamCompileResult CompileResult;
-
+
typedef CompileOptions::OptimizationLevel OptimizationLevel;
typedef CompileOptions::DebugInfoType DebugInfoType;
typedef CompileOptions::FloatingPointMode FloatingPointMode;
@@ -332,7 +197,7 @@ public:
/// Get the desc of this compiler
virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() = 0;
/// Compile using the specified options. The result is in resOut
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) = 0;
/// Some compilers have support converting a binary blob into disassembly. Output disassembly is held in the output blob
virtual SLANG_NO_THROW SlangResult SLANG_MCALL disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) = 0;
@@ -364,25 +229,30 @@ public:
Desc m_desc;
};
-class CommandLineDownstreamCompileResult : public DownstreamCompileResult
+class CommandLineDownstreamArtifactRepresentation : public ComBaseObject, public IArtifactRepresentation
{
public:
- typedef DownstreamCompileResult Super;
+ SLANG_COM_BASE_IUNKNOWN_ALL
- virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) SLANG_OVERRIDE;
- virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) SLANG_OVERRIDE;
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+ // IArtifactRepresentation
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
- CommandLineDownstreamCompileResult(const DownstreamDiagnostics& diagnostics, const String& moduleFilePath, TemporaryFileSet* temporaryFileSet) :
- Super(diagnostics),
+ CommandLineDownstreamArtifactRepresentation(const String& moduleFilePath, TemporaryFileSet* temporaryFileSet) :
m_moduleFilePath(moduleFilePath),
m_temporaryFiles(temporaryFileSet)
{
}
-
+
RefPtr<TemporaryFileSet> m_temporaryFiles;
protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
String m_moduleFilePath;
DownstreamCompileOptions m_options;
ComPtr<ISlangBlob> m_binaryBlob;
@@ -396,7 +266,7 @@ public:
typedef DownstreamCompilerBase Super;
// IDownstreamCompiler
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE { return true; }
// Functions to be implemented for a specific CommandLine
@@ -409,7 +279,7 @@ public:
virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, List<String>& outPaths) = 0;
virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) = 0;
- virtual SlangResult parseOutput(const ExecuteResult& exeResult, DownstreamDiagnostics& output) = 0;
+ virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) = 0;
CommandLineDownstreamCompiler(const Desc& desc, const ExecutableLocation& exe) :
Super(desc)
@@ -439,8 +309,6 @@ struct DownstreamCompilerBaseUtil
typedef DownstreamProductFlag ProductFlag;
typedef DownstreamProductFlags ProductFlags;
-
- typedef DownstreamDiagnostic Diagnostic;
};
}
diff --git a/source/compiler-core/slang-downstream-dep1.cpp b/source/compiler-core/slang-downstream-dep1.cpp
index e5eb4ac24..25964964f 100644
--- a/source/compiler-core/slang-downstream-dep1.cpp
+++ b/source/compiler-core/slang-downstream-dep1.cpp
@@ -1,12 +1,136 @@
// slang-downstream-dep1.cpp
#include "slang-downstream-dep1.h"
+#include "slang-artifact-util.h"
+#include "slang-artifact-associated-impl.h"
+
+#include "../core/slang-castable-list-impl.h"
namespace Slang
{
+/* !!!!!!!!!!!!!!!!!!!!!!!!! DownstreamArtifactRepresentation_Dep1 !!!!!!!!!!!!!!!!!!!!!!!! */
+
+class DownstreamResultArtifactRepresentationAdapater_Dep1 : public ComBaseObject, public IArtifactRepresentation
+{
+public:
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
+
+ // IArtifactRepresentation
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createRepresentation(const Guid& typeGuid, ICastable** outCastable) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; }
+
+ DownstreamResultArtifactRepresentationAdapater_Dep1(DownstreamCompileResult_Dep1* result):
+ m_result(result)
+ {
+ }
+
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ RefPtr<DownstreamCompileResult_Dep1> m_result;
+};
+
+void* DownstreamResultArtifactRepresentationAdapater_Dep1::castAs(const SlangUUID& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* DownstreamResultArtifactRepresentationAdapater_Dep1::getInterface(const Guid& guid)
+{
+ if (guid == ISlangBlob::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == IArtifactRepresentation::getTypeGuid())
+ {
+ IArtifactRepresentation* rep = this;
+ return rep;
+ }
+ return nullptr;
+}
+
+void* DownstreamResultArtifactRepresentationAdapater_Dep1::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+SlangResult DownstreamResultArtifactRepresentationAdapater_Dep1::createRepresentation(const Guid& typeGuid, ICastable** outCastable)
+{
+ if (typeGuid == ISlangSharedLibrary::getTypeGuid())
+ {
+ ComPtr<ISlangSharedLibrary> lib;
+ SLANG_RETURN_ON_FAIL(DownstreamUtil_Dep1::getDownstreamSharedLibrary(m_result, lib));
+
+ *outCastable = lib.detach();
+ return SLANG_OK;
+ }
+ else if (typeGuid == ISlangBlob::getTypeGuid())
+ {
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(m_result->getBinary(blob));
+
+ *outCastable = CastableUtil::getCastable(blob).detach();
+ return SLANG_OK;
+ }
+
+ return SLANG_E_NOT_AVAILABLE;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompilerAdapter_Dep1 !!!!!!!!!!!!!!!!!!!!!!!! */
+
+SlangResult DownstreamCompilerAdapter_Dep1::compile(const CompileOptions& options, IArtifact** outArtifact)
+{
+ RefPtr<DownstreamCompileResult_Dep1> result;
+ SLANG_RETURN_ON_FAIL(m_dep->compile(options, result));
+
+ typedef CharSliceCaster Caster;
+
+ ComPtr<IArtifact> artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType);
+
+ // Convert the diagnostics
+
+ auto dstDiagnostics = ArtifactDiagnostics::create();
+ const DownstreamDiagnostics_Dep1* srcDiagnostics = &result->getDiagnostics();
+
+ dstDiagnostics->setResult(srcDiagnostics->result);
+ dstDiagnostics->setRaw(Caster::asCharSlice(srcDiagnostics->rawDiagnostics));
+
+ for (const auto& srcDiagnostic : srcDiagnostics->diagnostics)
+ {
+ IArtifactDiagnostics::Diagnostic dstDiagnostic;
+
+ dstDiagnostic.severity = ArtifactDiagnostic::Severity(srcDiagnostic.severity);
+ dstDiagnostic.stage = ArtifactDiagnostic::Stage(srcDiagnostic.stage);
+
+ dstDiagnostic.code = Caster::asTerminatedCharSlice(srcDiagnostic.code);
+ dstDiagnostic.text = Caster::asTerminatedCharSlice(srcDiagnostic.text);
+ dstDiagnostic.filePath = Caster::asTerminatedCharSlice(srcDiagnostic.filePath);
+
+ dstDiagnostic.location.line = srcDiagnostic.fileLine;
+ }
+
+ artifact->addAssociated(dstDiagnostics);
+
+ // We need to add a representation that can produce shared libraries/blobs on demand
+
+ auto rep = new DownstreamResultArtifactRepresentationAdapater_Dep1(result);
+ artifact->addRepresentation(rep);
+
+ *outArtifact = artifact.detach();
+ return SLANG_OK;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!! SharedLibraryDep1Adapter !!!!!!!!!!!!!!!!!!!!!!!! */
+
// A temporary class that adapts `ISlangSharedLibrary_Dep1` to ISlangSharedLibrary
-class SharedLibraryDep1Adapter : public ComBaseObject, public ISlangSharedLibrary
+class SharedLibraryAdapter_Dep1 : public ComBaseObject, public ISlangSharedLibrary
{
public:
SLANG_COM_BASE_IUNKNOWN_ALL
@@ -17,7 +141,7 @@ public:
// ISlangSharedLibrary
virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE { return m_contained->findSymbolAddressByName(name); }
- SharedLibraryDep1Adapter(ISlangSharedLibrary_Dep1* dep1) :
+ SharedLibraryAdapter_Dep1(ISlangSharedLibrary_Dep1* dep1) :
m_contained(dep1)
{
}
@@ -42,7 +166,7 @@ protected:
ComPtr<ISlangSharedLibrary_Dep1> m_contained;
};
-void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid)
+void* SharedLibraryAdapter_Dep1::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
{
@@ -52,7 +176,7 @@ void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid)
}
/* Hack to take into account downstream compilers shared library interface might need an adapter */
-/* static */SlangResult DownstreamUtil_Dep1::getDownstreamSharedLibrary(DownstreamCompileResult* downstreamResult, ComPtr<ISlangSharedLibrary>& outSharedLibrary)
+/* static */SlangResult DownstreamUtil_Dep1::getDownstreamSharedLibrary(DownstreamCompileResult_Dep1* downstreamResult, ComPtr<ISlangSharedLibrary>& outSharedLibrary)
{
ComPtr<ISlangSharedLibrary> lib;
SLANG_RETURN_ON_FAIL(downstreamResult->getHostCallableSharedLibrary(lib));
@@ -66,7 +190,7 @@ void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid)
if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary_Dep1::getTypeGuid(), (void**)libDep1.writeRef())))
{
// Okay, we need to adapt for now
- outSharedLibrary = new SharedLibraryDep1Adapter(libDep1);
+ outSharedLibrary = new SharedLibraryAdapter_Dep1(libDep1);
return SLANG_OK;
}
return SLANG_E_NOT_FOUND;
diff --git a/source/compiler-core/slang-downstream-dep1.h b/source/compiler-core/slang-downstream-dep1.h
index fd0efd1e9..19d8a6d68 100644
--- a/source/compiler-core/slang-downstream-dep1.h
+++ b/source/compiler-core/slang-downstream-dep1.h
@@ -8,6 +8,59 @@ namespace Slang
{
// (DEPRECIATED)
+struct DownstreamDiagnostic_Dep1
+{
+ enum class Severity
+ {
+ Unknown,
+ Info,
+ Warning,
+ Error,
+ CountOf,
+ };
+ enum class Stage
+ {
+ Compile,
+ Link,
+ };
+
+ Severity severity = Severity::Unknown; ///< The severity of error
+ Stage stage = Stage::Compile; ///< The stage the error came from
+ String text; ///< The text of the error
+ String code; ///< The compiler specific error code
+ String filePath; ///< The path the error originated from
+ Int fileLine = 0; ///< The line number the error came from
+};
+
+struct DownstreamDiagnostics_Dep1
+{
+ typedef DownstreamDiagnostic_Dep1 Diagnostic;
+
+ String rawDiagnostics;
+
+ SlangResult result = SLANG_OK;
+ List<Diagnostic> diagnostics;
+};
+
+class DownstreamCompileResult_Dep1 : public RefObject
+{
+public:
+ SLANG_CLASS_GUID(0xdfc5d318, 0x8675, 0x40ef, { 0xbd, 0x7b, 0x4, 0xa4, 0xff, 0x66, 0x11, 0x30 })
+
+ virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) { SLANG_UNUSED(outLibrary); return SLANG_FAIL; }
+ virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) { SLANG_UNUSED(outBlob); return SLANG_FAIL; }
+
+ const DownstreamDiagnostics_Dep1& getDiagnostics() const { return m_diagnostics; }
+
+ /// Ctor
+ DownstreamCompileResult_Dep1(const DownstreamDiagnostics_Dep1& diagnostics) :
+ m_diagnostics(diagnostics)
+ {}
+
+protected:
+ DownstreamDiagnostics_Dep1 m_diagnostics;
+};
+
class DownstreamCompiler_Dep1: public RefObject
{
public:
@@ -16,7 +69,7 @@ public:
/// Get the desc of this compiler
const DownstreamCompilerDesc& getDesc() const { return m_desc; }
/// Compile using the specified options. The result is in resOut
- virtual SlangResult compile(const DownstreamCompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) = 0;
+ virtual SlangResult compile(const DownstreamCompileOptions& options, RefPtr<DownstreamCompileResult_Dep1>& outResult) = 0;
/// Some compilers have support converting a binary blob into disassembly. Output disassembly is held in the output blob
virtual SlangResult disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out);
@@ -33,7 +86,7 @@ class DownstreamCompilerAdapter_Dep1 : public DownstreamCompilerBase
public:
// IDownstreamCompiler
virtual SLANG_NO_THROW const Desc& SLANG_MCALL getDesc() SLANG_OVERRIDE { return m_dep->getDesc(); }
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE { return m_dep->compile(options, outResult); }
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE { return m_dep->disassemble(sourceBlobTarget, blob, blobSize, out); }
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE { return m_dep->isFileBased(); }
@@ -48,7 +101,7 @@ protected:
struct DownstreamUtil_Dep1
{
- static SlangResult getDownstreamSharedLibrary(DownstreamCompileResult* downstreamResult, ComPtr<ISlangSharedLibrary>& outSharedLibrary);
+ static SlangResult getDownstreamSharedLibrary(DownstreamCompileResult_Dep1* downstreamResult, ComPtr<ISlangSharedLibrary>& outSharedLibrary);
};
}
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index 5126e53cc..7a3281463 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -19,7 +19,9 @@
#include "../core/slang-shared-library.h"
-#include "../compiler-core/slang-artifact-util.h"
+#include "slang-artifact-associated-impl.h"
+#include "slang-artifact-util.h"
+#include "slang-artifact-diagnostic-util.h"
// Enable calling through to `dxc` to
// generate code on Windows.
@@ -161,7 +163,7 @@ public:
typedef DownstreamCompilerBase Super;
// IDownstreamCompiler
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE { return false; }
@@ -192,7 +194,7 @@ SlangResult DXCDownstreamCompiler::init(ISlangSharedLibrary* library)
return SLANG_OK;
}
-static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, DownstreamDiagnostic& outDiagnostic)
+static SlangResult _parseDiagnosticLine(CharSliceAllocator& allocator, const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, IArtifactDiagnostics::Diagnostic& outDiagnostic)
{
/* tests/diagnostics/syntax-error-intrinsic.slang:14:2: error: expected expression */
if (lineSlices.getCount() < 5)
@@ -200,27 +202,27 @@ static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<Uno
return SLANG_FAIL;
}
- outDiagnostic.filePath = lineSlices[0];
+ outDiagnostic.filePath = allocator.allocate(lineSlices[0]);
- SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineSlices[1], outDiagnostic.fileLine));
+ SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineSlices[1], outDiagnostic.location.line));
//Int lineCol;
//SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineSlices[2], lineCol));
UnownedStringSlice severitySlice = lineSlices[3].trim();
- outDiagnostic.severity = DownstreamDiagnostic::Severity::Error;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Error;
if (severitySlice == UnownedStringSlice::fromLiteral("warning"))
{
- outDiagnostic.severity = DownstreamDiagnostic::Severity::Warning;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Warning;
}
// The rest of the line
- outDiagnostic.text = UnownedStringSlice(lineSlices[4].begin(), line.end());
+ outDiagnostic.text = allocator.allocate(lineSlices[4].begin(), line.end());
return SLANG_OK;
}
-static SlangResult _handleOperationResult(IDxcOperationResult* dxcResult, DownstreamDiagnostics& ioDiagnostics, ComPtr<IDxcBlob>& outBlob)
+static SlangResult _handleOperationResult(IDxcOperationResult* dxcResult, IArtifactDiagnostics* diagnostics, ComPtr<IDxcBlob>& outBlob)
{
// Retrieve result.
HRESULT resultCode = S_OK;
@@ -231,9 +233,9 @@ static SlangResult _handleOperationResult(IDxcOperationResult* dxcResult, Downst
// *unless* the compile failed (no way to get
// warnings out!?).
- if (SLANG_SUCCEEDED(ioDiagnostics.result))
+ if (SLANG_SUCCEEDED(diagnostics->getResult()))
{
- ioDiagnostics.result = resultCode;
+ diagnostics->setResult(resultCode);
}
// Try getting the error/diagnostics blob
@@ -245,13 +247,11 @@ static SlangResult _handleOperationResult(IDxcOperationResult* dxcResult, Downst
const UnownedStringSlice diagnosticsSlice = _getSlice(dxcErrorBlob);
if (diagnosticsSlice.getLength())
{
- if (ioDiagnostics.rawDiagnostics.getLength() > 0)
- {
- ioDiagnostics.rawDiagnostics.append("\n");
- }
- ioDiagnostics.rawDiagnostics.append(diagnosticsSlice);
+ diagnostics->appendRaw(asCharSlice(diagnosticsSlice));
- SlangResult diagnosticParseRes = DownstreamDiagnostic::parseColonDelimitedDiagnostics(diagnosticsSlice, 0, _parseDiagnosticLine, ioDiagnostics.diagnostics);
+ CharSliceAllocator allocator;
+ List<IArtifactDiagnostics::Diagnostic> parsedDiagnostics;
+ SlangResult diagnosticParseRes = ArtifactDiagnosticUtil::parseColonDelimitedDiagnostics(allocator, diagnosticsSlice, 0, _parseDiagnosticLine, diagnostics);
SLANG_UNUSED(diagnosticParseRes);
SLANG_ASSERT(SLANG_SUCCEEDED(diagnosticParseRes));
@@ -262,7 +262,7 @@ static SlangResult _handleOperationResult(IDxcOperationResult* dxcResult, Downst
if (SLANG_FAILED(resultCode))
{
// In case the parsing failed, we still have an error -> so require there is one in the diagnostics
- ioDiagnostics.requireErrorDiagnostic();
+ diagnostics->requireErrorDiagnostic();
}
else
{
@@ -274,7 +274,7 @@ static SlangResult _handleOperationResult(IDxcOperationResult* dxcResult, Downst
return SLANG_OK;
}
-SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult)
+SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, IArtifact** outArtifact)
{
// This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath
if (options.sourceFiles.getCount() > 0)
@@ -446,8 +446,8 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
&includeHandler, // `#include` handler
dxcResult.writeRef()));
- DownstreamDiagnostics diagnostics;
-
+ auto diagnostics = ArtifactDiagnostics::create();
+
ComPtr<IDxcBlob> dxcResultBlob;
SLANG_RETURN_ON_FAIL(_handleOperationResult(dxcResult, diagnostics, dxcResultBlob));
@@ -517,7 +517,14 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
dxcResultBlob = linkedBlob;
}
- outResult = new BlobDownstreamCompileResult(diagnostics, (ISlangBlob*)dxcResultBlob.get());
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType);
+ artifact->addAssociated(diagnostics);
+ if (dxcResultBlob)
+ {
+ artifact->addRepresentationUnknown((ISlangBlob*)dxcResultBlob.get());
+ }
+
+ *outArtifact = artifact.detach();
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-fxc-compiler.cpp b/source/compiler-core/slang-fxc-compiler.cpp
index d9d506221..21cd14759 100644
--- a/source/compiler-core/slang-fxc-compiler.cpp
+++ b/source/compiler-core/slang-fxc-compiler.cpp
@@ -17,6 +17,10 @@
#include "slang-include-system.h"
#include "slang-source-loc.h"
+#include "slang-artifact-associated-impl.h"
+
+#include "slang-artifact-diagnostic-util.h"
+
#include "../core/slang-shared-library.h"
// Enable calling through to `fxc` or `dxc` to
@@ -113,7 +117,7 @@ public:
typedef DownstreamCompilerBase Super;
// IDownstreamCompiler
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE { return false; }
@@ -148,7 +152,7 @@ SlangResult FXCDownstreamCompiler::init(ISlangSharedLibrary* library)
return SLANG_OK;
}
-static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, DownstreamDiagnostic& outDiagnostic)
+static SlangResult _parseDiagnosticLine(CharSliceAllocator& allocator, const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, ArtifactDiagnostic& outDiagnostic)
{
/* tests/diagnostics/syntax-error-intrinsic.slang(14,2): error X3000: syntax error: unexpected token '@' */
if (lineSlices.getCount() < 3)
@@ -156,26 +160,26 @@ static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<Uno
return SLANG_FAIL;
}
- SLANG_RETURN_ON_FAIL(DownstreamDiagnostic::splitPathLocation(lineSlices[0], outDiagnostic));
+ SLANG_RETURN_ON_FAIL(ArtifactDiagnosticUtil::splitPathLocation(allocator, lineSlices[0], outDiagnostic));
{
const UnownedStringSlice severityAndCodeSlice = lineSlices[1].trim();
const UnownedStringSlice severitySlice = StringUtil::getAtInSplit(severityAndCodeSlice, ' ', 0);
- outDiagnostic.code = StringUtil::getAtInSplit(severityAndCodeSlice, ' ', 1);
+ outDiagnostic.code = allocator.allocate(StringUtil::getAtInSplit(severityAndCodeSlice, ' ', 1));
- outDiagnostic.severity = DownstreamDiagnostic::Severity::Error;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Error;
if (severitySlice == "warning")
{
- outDiagnostic.severity = DownstreamDiagnostic::Severity::Warning;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Warning;
}
}
- outDiagnostic.text = UnownedStringSlice(lineSlices[2].begin(), line.end());
+ outDiagnostic.text = allocator.allocate(lineSlices[2].begin(), line.end());
return SLANG_OK;
}
-SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult)
+SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, IArtifact** outArtifact)
{
// This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath
if (options.sourceFiles.getCount() > 0)
@@ -284,17 +288,19 @@ SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
codeBlob.writeRef(),
diagnosticsBlob.writeRef());
- DownstreamDiagnostics diagnostics;
+ auto diagnostics = ArtifactDiagnostics::create();
// HRESULT is compatible with SlangResult
- diagnostics.result = hr;
+ diagnostics->setResult(hr);
+
+ CharSliceAllocator allocator;
if (diagnosticsBlob)
{
UnownedStringSlice diagnosticText = _getSlice(diagnosticsBlob);
- diagnostics.rawDiagnostics = diagnosticText;
+ diagnostics->setRaw(asCharSlice(diagnosticText));
- SlangResult diagnosticParseRes = DownstreamDiagnostic::parseColonDelimitedDiagnostics(diagnosticText, 0, _parseDiagnosticLine, diagnostics.diagnostics);
+ SlangResult diagnosticParseRes = ArtifactDiagnosticUtil::parseColonDelimitedDiagnostics(allocator, diagnosticText, 0, _parseDiagnosticLine, diagnostics);
SLANG_UNUSED(diagnosticParseRes);
SLANG_ASSERT(SLANG_SUCCEEDED(diagnosticParseRes));
}
@@ -302,13 +308,19 @@ SlangResult FXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
// If FXC failed, make sure we have an error in the diagnostics
if (FAILED(hr))
{
- diagnostics.requireErrorDiagnostic();
+ diagnostics->requireErrorDiagnostic();
}
- // ID3DBlob is compatible with ISlangBlob, so just cast away...
- ISlangBlob* slangCodeBlob = (ISlangBlob*)codeBlob.get();
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType);
+ artifact->addAssociated(diagnostics);
+
+ if (codeBlob)
+ {
+ // ID3DBlob is compatible with ISlangBlob, so just cast away...
+ artifact->addRepresentationUnknown((ISlangBlob*)codeBlob.get());
+ }
- outResult = new BlobDownstreamCompileResult(diagnostics, slangCodeBlob);
+ *outArtifact = artifact.detach();
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 61cf5640a..d33e72824 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -11,6 +11,7 @@
#include "../core/slang-string-slice-pool.h"
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-diagnostic-util.h"
#include "slang-artifact-util.h"
namespace Slang
@@ -130,9 +131,9 @@ SlangResult GCCDownstreamCompilerUtil::calcVersion(const ExecutableLocation& exe
return SLANG_FAIL;
}
-static SlangResult _parseSeverity(const UnownedStringSlice& in, DownstreamDiagnostic::Severity& outSeverity)
+static SlangResult _parseSeverity(const UnownedStringSlice& in, ArtifactDiagnostic::Severity& outSeverity)
{
- typedef DownstreamDiagnostic::Severity Severity;
+ typedef ArtifactDiagnostic::Severity Severity;
if (in == "error" || in == "fatal error")
{
@@ -165,9 +166,9 @@ enum class LineParseResult
} // anonymous
-static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParseResult& outLineParseResult, DownstreamDiagnostic& outDiagnostic)
+static SlangResult _parseGCCFamilyLine(CharSliceAllocator& allocator, const UnownedStringSlice& line, LineParseResult& outLineParseResult, ArtifactDiagnostic& outDiagnostic)
{
- typedef DownstreamDiagnostic Diagnostic;
+ typedef ArtifactDiagnostic Diagnostic;
typedef Diagnostic::Severity Severity;
// Set to default case
@@ -238,7 +239,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
// We'll ignore for now
outDiagnostic.stage = Diagnostic::Stage::Link;
outDiagnostic.severity = Severity::Info;
- outDiagnostic.text = split[1].trim();
+ outDiagnostic.text = allocator.allocate(split[1].trim());
outLineParseResult = LineParseResult::Start;
return SLANG_OK;
}
@@ -247,7 +248,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
{
// Command line errors can be just contain 'error:' etc. Can be seen on apple/clang
outDiagnostic.stage = Diagnostic::Stage::Compile;
- outDiagnostic.text = split[1].trim();
+ outDiagnostic.text = allocator.allocate(split[1].trim());
outLineParseResult = LineParseResult::Single;
return SLANG_OK;
}
@@ -275,25 +276,25 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
outDiagnostic.stage = Diagnostic::Stage::Link;
}
- outDiagnostic.text = text;
+ outDiagnostic.text = allocator.allocate(text);
outLineParseResult = LineParseResult::Start;
return SLANG_OK;
}
else if (split1.startsWith("(.text"))
{
// This is a little weak... but looks like it's a link error
- outDiagnostic.filePath = split[0];
+ outDiagnostic.filePath = allocator.allocate(split[0]);
outDiagnostic.severity = Severity::Error;
outDiagnostic.stage = Diagnostic::Stage::Link;
- outDiagnostic.text = text;
+ outDiagnostic.text = allocator.allocate(text);
outLineParseResult = LineParseResult::Single;
return SLANG_OK;
}
else if (text.startsWith("ld returned"))
{
- outDiagnostic.stage = DownstreamDiagnostic::Stage::Link;
+ outDiagnostic.stage = ArtifactDiagnostic::Stage::Link;
SLANG_RETURN_ON_FAIL(_parseSeverity(split[1].trim(), outDiagnostic.severity));
- outDiagnostic.text = line;
+ outDiagnostic.text = allocator.allocate(line);
outLineParseResult = LineParseResult::Single;
return SLANG_OK;
}
@@ -317,11 +318,12 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
}
else
{
- outDiagnostic.filePath = split[1];
- outDiagnostic.fileLine = 0;
+ outDiagnostic.filePath = allocator.allocate(split[1]);
+ outDiagnostic.location.line = 0;
+ outDiagnostic.location.column = 0;
outDiagnostic.severity = Diagnostic::Severity::Error;
outDiagnostic.stage = Diagnostic::Stage::Link;
- outDiagnostic.text = split[3];
+ outDiagnostic.text = allocator.allocate(split[3]);
outLineParseResult = LineParseResult::Start;
return SLANG_OK;
@@ -332,11 +334,11 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
// Probably a regular error line
SLANG_RETURN_ON_FAIL(_parseSeverity(split[3].trim(), outDiagnostic.severity));
- outDiagnostic.filePath = split[0];
- SLANG_RETURN_ON_FAIL(StringUtil::parseInt(split[1], outDiagnostic.fileLine));
+ outDiagnostic.filePath = allocator.allocate(split[0]);
+ SLANG_RETURN_ON_FAIL(StringUtil::parseInt(split[1], outDiagnostic.location.line));
// Everything from 4 to the end is the error
- outDiagnostic.text = UnownedStringSlice(split[4].begin(), split.getLast().end());
+ outDiagnostic.text = allocator.allocate(split[4].begin(), split.getLast().end());
outLineParseResult = LineParseResult::Start;
return SLANG_OK;
@@ -347,35 +349,40 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
return SLANG_OK;
}
-/* static */SlangResult GCCDownstreamCompilerUtil::parseOutput(const ExecuteResult& exeRes, DownstreamDiagnostics& outOutput)
+/* static */SlangResult GCCDownstreamCompilerUtil::parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* diagnostics)
{
LineParseResult prevLineResult = LineParseResult::Ignore;
- outOutput.reset();
- outOutput.rawDiagnostics = exeRes.standardError;
+ CharSliceAllocator allocator;
+
+ diagnostics->reset();
+ diagnostics->setRaw(CharSliceCaster::asCharSlice(exeRes.standardError));
+
+ // We hold in workDiagnostics so as it is more convenient to append to the last with a continuation
+ // also means we don't hold the allocations of building up continuations, just the results when finally allocated at the end
+ List<ArtifactDiagnostic> workDiagnostics;
for (auto line : LineParser(exeRes.standardError.getUnownedSlice()))
{
- Diagnostic diagnostic;
- diagnostic.reset();
-
+ ArtifactDiagnostic diagnostic;
+
LineParseResult lineRes;
- SLANG_RETURN_ON_FAIL(_parseGCCFamilyLine(line, lineRes, diagnostic));
+ SLANG_RETURN_ON_FAIL(_parseGCCFamilyLine(allocator, line, lineRes, diagnostic));
switch (lineRes)
{
case LineParseResult::Start:
{
// It's start of a new message
- outOutput.diagnostics.add(diagnostic);
+ workDiagnostics.add(diagnostic);
prevLineResult = LineParseResult::Start;
break;
}
case LineParseResult::Single:
{
// It's a single message, without anything following
- outOutput.diagnostics.add(diagnostic);
+ workDiagnostics.add(diagnostic);
prevLineResult = LineParseResult::Ignore;
break;
}
@@ -383,12 +390,21 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
{
if (prevLineResult == LineParseResult::Start || prevLineResult == LineParseResult::Continuation)
{
- if (outOutput.diagnostics.getCount() > 0)
+ if (workDiagnostics.getCount() > 0)
{
+ auto& last = workDiagnostics.getLast();
+
+ // TODO(JS): Note that this is somewhat wasteful as every time we append we just allocate more memory
+ // to hold the result.
+ // If we had an allocator dedicated to 'text' we could perhaps just append to the end of the last allocation
+ //
// We are now in a continuation, add to the last
- auto& text = outOutput.diagnostics.getLast().text;
- text.append("\n");
- text.append(line);
+ StringBuilder buf;
+ buf.append(asStringSlice(last.text));
+ buf.append("\n");
+ buf.append(line);
+
+ last.text = allocator.allocate(buf);
}
prevLineResult = LineParseResult::Continuation;
}
@@ -403,9 +419,14 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
}
}
- if (outOutput.has(Diagnostic::Severity::Error) || exeRes.resultCode != 0)
+ for (const auto& diagnostic : workDiagnostics)
+ {
+ diagnostics->add(diagnostic);
+ }
+
+ if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error) || exeRes.resultCode != 0)
{
- outOutput.result = SLANG_FAIL;
+ diagnostics->setResult(SLANG_FAIL);
}
return SLANG_OK;
diff --git a/source/compiler-core/slang-gcc-compiler-util.h b/source/compiler-core/slang-gcc-compiler-util.h
index ec8b21e03..7f15f6701 100644
--- a/source/compiler-core/slang-gcc-compiler-util.h
+++ b/source/compiler-core/slang-gcc-compiler-util.h
@@ -19,7 +19,7 @@ struct GCCDownstreamCompilerUtil : public DownstreamCompilerBaseUtil
static SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine);
/// Parse ExecuteResult into diagnostics
- static SlangResult parseOutput(const ExecuteResult& exeRes, DownstreamDiagnostics& out);
+ static SlangResult parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* diagnostics);
/// Calculate the output module filename
static SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath);
@@ -46,7 +46,7 @@ public:
// CommandLineCPPCompiler impl - just forwards to the Util
virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) SLANG_OVERRIDE { return Util::calcArgs(options, cmdLine); }
- virtual SlangResult parseOutput(const ExecuteResult& exeResult, DownstreamDiagnostics& output) SLANG_OVERRIDE { return Util::parseOutput(exeResult, output); }
+ virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) SLANG_OVERRIDE { return Util::parseOutput(exeResult, diagnostics); }
virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) SLANG_OVERRIDE { return Util::calcModuleFilePath(options, outPath); }
virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags flags, List<String>& outPaths) SLANG_OVERRIDE { return Util::calcCompileProducts(options, flags, outPaths); }
diff --git a/source/compiler-core/slang-glslang-compiler.cpp b/source/compiler-core/slang-glslang-compiler.cpp
index b4e3d915d..5ae9419fd 100644
--- a/source/compiler-core/slang-glslang-compiler.cpp
+++ b/source/compiler-core/slang-glslang-compiler.cpp
@@ -14,6 +14,8 @@
#include "../core/slang-semantic-version.h"
#include "../core/slang-char-util.h"
+#include "slang-artifact-associated-impl.h"
+
#include "slang-include-system.h"
#include "slang-source-loc.h"
@@ -40,7 +42,7 @@ public:
typedef DownstreamCompilerBase Super;
// IDownstreamCompiler
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outResult) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL disassemble(SlangCompileTarget sourceBlobTarget, const void* blob, size_t blobSize, ISlangBlob** out) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE { return false; }
@@ -94,7 +96,7 @@ SlangResult GlslangDownstreamCompiler::_invoke(glslang_CompileRequest_1_1& reque
return err ? SLANG_FAIL : SLANG_OK;
}
-static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, DownstreamDiagnostic& outDiagnostic)
+static SlangResult _parseDiagnosticLine(CharSliceAllocator& allocator, const UnownedStringSlice& line, List<UnownedStringSlice>& lineSlices, ArtifactDiagnostic& outDiagnostic)
{
/* ERROR: tests/diagnostics/syntax-error-intrinsic.slang:13: '@' : unexpected token */
@@ -105,23 +107,23 @@ static SlangResult _parseDiagnosticLine(const UnownedStringSlice& line, List<Uno
{
const UnownedStringSlice severitySlice = lineSlices[0].trim();
- outDiagnostic.severity = DownstreamDiagnostic::Severity::Error;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Error;
if (severitySlice.caseInsensitiveEquals(UnownedStringSlice::fromLiteral("warning")))
{
- outDiagnostic.severity = DownstreamDiagnostic::Severity::Warning;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Warning;
}
}
- outDiagnostic.filePath = lineSlices[1];
+ outDiagnostic.filePath = allocator.allocate(lineSlices[1]);
- SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineSlices[2], outDiagnostic.fileLine));
- outDiagnostic.text = UnownedStringSlice(lineSlices[3].begin(), line.end());
+ SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineSlices[2], outDiagnostic.location.line));
+ outDiagnostic.text = allocator.allocate(lineSlices[3].begin(), line.end());
return SLANG_OK;
}
-SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult)
+SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& options, IArtifact** outArtifact)
{
// This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath
if (options.sourceFiles.getCount() > 0)
@@ -187,27 +189,31 @@ SlangResult GlslangDownstreamCompiler::compile(const CompileOptions& options, Re
const SlangResult invokeResult = _invoke(request);
- DownstreamDiagnostics diagnostics;
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType);
+
+ auto diagnostics = ArtifactDiagnostics::create();
// Set the diagnostics result
- diagnostics.result = invokeResult;
+ diagnostics->setResult(invokeResult);
+ artifact->addAssociated(diagnostics);
if (SLANG_FAILED(invokeResult))
{
- diagnostics.rawDiagnostics = diagnosticOutput;
+ diagnostics->setRaw(CharSliceCaster::asCharSlice(diagnosticOutput));
- SlangResult diagnosticParseRes = DownstreamDiagnostic::parseColonDelimitedDiagnostics(diagnosticOutput.getUnownedSlice(), 1, _parseDiagnosticLine, diagnostics.diagnostics);
- SLANG_UNUSED(diagnosticParseRes);
+ CharSliceAllocator allocator;
- diagnostics.requireErrorDiagnostic();
+ SlangResult diagnosticParseRes = ArtifactDiagnosticUtil::parseColonDelimitedDiagnostics(allocator, diagnosticOutput.getUnownedSlice(), 1, _parseDiagnosticLine, diagnostics);
+ SLANG_UNUSED(diagnosticParseRes);
- outResult = new BlobDownstreamCompileResult(diagnostics, nullptr);
- return SLANG_OK;
+ diagnostics->requireErrorDiagnostic();
+ }
+ else
+ {
+ artifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));
}
- ComPtr<ISlangBlob> spirvBlob = ListBlob::moveCreate(spirv);
- outResult = new BlobDownstreamCompileResult(diagnostics, spirvBlob);
-
+ *outArtifact = artifact.detach();
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-nvrtc-compiler.cpp b/source/compiler-core/slang-nvrtc-compiler.cpp
index 0cc208854..683aeaedc 100644
--- a/source/compiler-core/slang-nvrtc-compiler.cpp
+++ b/source/compiler-core/slang-nvrtc-compiler.cpp
@@ -15,6 +15,10 @@
#include "../core/slang-shared-library.h"
+#include "slang-artifact-diagnostic-util.h"
+#include "slang-artifact-util.h"
+#include "slang-artifact-associated-impl.h"
+
namespace nvrtc
{
@@ -98,7 +102,7 @@ public:
typedef DownstreamCompilerBase Super;
// IDownstreamCompiler
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, RefPtr<DownstreamCompileResult>& outResult) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL compile(const CompileOptions& options, IArtifact** outArtifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() SLANG_OVERRIDE { return false; }
/// Must be called before use
@@ -166,13 +170,13 @@ SlangResult NVRTCDownstreamCompiler::init(ISlangSharedLibrary* library)
return SLANG_OK;
}
-static SlangResult _parseLocation(const UnownedStringSlice& in, DownstreamDiagnostic& outDiagnostic)
+static SlangResult _parseLocation(CharSliceAllocator& allocator, const UnownedStringSlice& in, ArtifactDiagnostic& outDiagnostic)
{
const Index startIndex = in.indexOf('(');
if (startIndex >= 0)
{
- outDiagnostic.filePath = UnownedStringSlice(in.begin(), in.begin() + startIndex);
+ outDiagnostic.filePath = allocator.allocate(in.begin(), in.begin() + startIndex);
UnownedStringSlice remaining(in.begin() + startIndex + 1, in.end());
const Int endIndex = remaining.indexOf(')');
@@ -180,12 +184,12 @@ static SlangResult _parseLocation(const UnownedStringSlice& in, DownstreamDiagno
Int line;
SLANG_RETURN_ON_FAIL(StringUtil::parseInt(lineText, line));
- outDiagnostic.fileLine = line;
+ outDiagnostic.location.line = line;
}
else
{
- outDiagnostic.fileLine = 0;
- outDiagnostic.filePath = in;
+ outDiagnostic.location.line = 0;
+ outDiagnostic.filePath = allocator.allocate(in);
}
return SLANG_OK;
}
@@ -200,10 +204,10 @@ static bool _hasDriveLetter(const UnownedStringSlice& line)
return line.getLength() > 2 && line[1] == ':' && _isDriveLetter(line[0]);
}
-static SlangResult _parseNVRTCLine(const UnownedStringSlice& line, DownstreamDiagnostic& outDiagnostic)
+static SlangResult _parseNVRTCLine(CharSliceAllocator& allocator, const UnownedStringSlice& line, ArtifactDiagnostic& outDiagnostic)
{
- typedef DownstreamDiagnostic Diagnostic;
- typedef Diagnostic::Severity Severity;
+ typedef ArtifactDiagnostic Diagnostic;
+ typedef ArtifactDiagnostic::Severity Severity;
outDiagnostic.stage = Diagnostic::Stage::Compile;
@@ -234,9 +238,9 @@ static SlangResult _parseNVRTCLine(const UnownedStringSlice& line, DownstreamDia
{
outDiagnostic.severity = Severity::Warning;
}
- outDiagnostic.text = split[2].trim();
+ outDiagnostic.text = allocator.allocate(split[2].trim());
- SLANG_RETURN_ON_FAIL(_parseLocation(split[0], outDiagnostic));
+ SLANG_RETURN_ON_FAIL(_parseLocation(allocator, split[0], outDiagnostic));
return SLANG_OK;
}
@@ -637,7 +641,7 @@ SlangResult NVRTCDownstreamCompiler::_maybeAddHalfSupport(const DownstreamCompil
return SLANG_OK;
}
-SlangResult NVRTCDownstreamCompiler::compile(const DownstreamCompileOptions& options, RefPtr<DownstreamCompileResult>& outResult)
+SlangResult NVRTCDownstreamCompiler::compile(const DownstreamCompileOptions& options, IArtifact** outArtifact)
{
// This compiler doesn't read files, they should be read externally and stored in sourceContents/sourceContentsPath
if (options.sourceFiles.getCount() > 0)
@@ -833,10 +837,14 @@ SlangResult NVRTCDownstreamCompiler::compile(const DownstreamCompileOptions& opt
res = m_nvrtcCompileProgram(program, int(dstOptions.getCount()), dstOptions.getBuffer());
+ auto artifact = ArtifactUtil::createArtifactForCompileTarget(options.targetType);
+ auto diagnostics = ArtifactDiagnostics::create();
+
+ artifact->addAssociated(diagnostics);
+
ComPtr<ISlangBlob> blob;
- DownstreamDiagnostics diagnostics;
- diagnostics.result = _asResult(res);
+ diagnostics->setResult(_asResult(res));
{
String rawDiagnostics;
@@ -850,18 +858,20 @@ SlangResult NVRTCDownstreamCompiler::compile(const DownstreamCompileOptions& opt
SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetProgramLog(program, dst));
rawDiagnostics.appendInPlace(dst, Index(logSize));
- diagnostics.rawDiagnostics = rawDiagnostics;
+ diagnostics->setRaw(CharSliceCaster::asCharSlice(rawDiagnostics));
}
+ CharSliceAllocator allocator;
+
// Parse the diagnostics here
- for (auto line : LineParser(diagnostics.rawDiagnostics.getUnownedSlice()))
+ for (auto line : LineParser(rawDiagnostics.getUnownedSlice()))
{
- DownstreamDiagnostic diagnostic;
- SlangResult lineRes = _parseNVRTCLine(line, diagnostic);
+ ArtifactDiagnostic diagnostic;
+ SlangResult lineRes = _parseNVRTCLine(allocator, line, diagnostic);
if (SLANG_SUCCEEDED(lineRes))
{
- diagnostics.diagnostics.add(diagnostic);
+ diagnostics->add(diagnostic);
}
else if (lineRes != SLANG_E_NOT_FOUND)
{
@@ -870,9 +880,9 @@ SlangResult NVRTCDownstreamCompiler::compile(const DownstreamCompileOptions& opt
}
// if it has a compilation error.. set on output
- if (diagnostics.has(DownstreamDiagnostic::Severity::Error))
+ if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error))
{
- diagnostics.result = SLANG_FAIL;
+ diagnostics->setResult(SLANG_FAIL);
}
}
@@ -887,11 +897,10 @@ SlangResult NVRTCDownstreamCompiler::compile(const DownstreamCompileOptions& opt
SLANG_NVRTC_RETURN_ON_FAIL(m_nvrtcGetPTX(program, (char*)ptx.getBuffer()));
- blob = ListBlob::moveCreate(ptx);
+ artifact->addRepresentationUnknown(ListBlob::moveCreate(ptx));
}
- outResult = new BlobDownstreamCompileResult(diagnostics, blob);
-
+ *outArtifact = artifact.detach();
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp
index 21db9570a..4e703f58f 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.cpp
+++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp
@@ -14,6 +14,7 @@
#include "../core/slang-io.h"
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-diagnostic-util.h"
#include "slang-artifact-util.h"
namespace Slang
@@ -288,21 +289,21 @@ namespace Slang
return SLANG_OK;
}
-static SlangResult _parseSeverity(const UnownedStringSlice& in, DownstreamDiagnostics::Diagnostic::Severity& outSeverity)
+static SlangResult _parseSeverity(const UnownedStringSlice& in, ArtifactDiagnostic::Severity& outSeverity)
{
- typedef DownstreamDiagnostics::Diagnostic::Severity Type;
+ typedef ArtifactDiagnostic::Severity Severity;
if (in == "error" || in == "fatal error")
{
- outSeverity = Type::Error;
+ outSeverity = Severity::Error;
}
else if (in == "warning")
{
- outSeverity = Type::Warning;
+ outSeverity = Severity::Warning;
}
else if (in == "info")
{
- outSeverity = Type::Info;
+ outSeverity = Severity::Info;
}
else
{
@@ -311,22 +312,22 @@ static SlangResult _parseSeverity(const UnownedStringSlice& in, DownstreamDiagno
return SLANG_OK;
}
-static SlangResult _parseVisualStudioLine(const UnownedStringSlice& line, DownstreamDiagnostics::Diagnostic& outDiagnostic)
+static SlangResult _parseVisualStudioLine(CharSliceAllocator& allocator, const UnownedStringSlice& line, ArtifactDiagnostic& outDiagnostic)
{
- typedef DownstreamDiagnostics::Diagnostic Diagnostic;
+ typedef IArtifactDiagnostics::Diagnostic Diagnostic;
UnownedStringSlice linkPrefix = UnownedStringSlice::fromLiteral("LINK :");
if (line.startsWith(linkPrefix))
{
- outDiagnostic.stage = Diagnostic::Stage::Link;
- outDiagnostic.severity = Diagnostic::Severity::Info;
+ outDiagnostic.stage = ArtifactDiagnostic::Stage::Link;
+ outDiagnostic.severity = ArtifactDiagnostic::Severity::Info;
- outDiagnostic.text = UnownedStringSlice(line.begin() + linkPrefix.getLength(), line.end());
+ outDiagnostic.text = allocator.allocate(line.begin() + linkPrefix.getLength(), line.end());
return SLANG_OK;
}
- outDiagnostic.stage = Diagnostic::Stage::Compile;
+ outDiagnostic.stage = ArtifactDiagnostic::Stage::Compile;
const char*const start = line.begin();
const char*const end = line.end();
@@ -385,13 +386,13 @@ static SlangResult _parseVisualStudioLine(const UnownedStringSlice& line, Downst
return SLANG_FAIL;
}
- outDiagnostic.filePath = UnownedStringSlice(start, lineNoStart);
- outDiagnostic.fileLine = lineNo;
+ outDiagnostic.filePath = allocator.allocate(start, lineNoStart);
+ outDiagnostic.location.line = lineNo;
}
else
{
- outDiagnostic.filePath = UnownedStringSlice(start, cur + colonIndex);
- outDiagnostic.fileLine = 0;
+ outDiagnostic.filePath = allocator.allocate(start, cur + colonIndex);
+ outDiagnostic.location.line = 0;
}
// Save the remaining text in 'postPath'
@@ -417,8 +418,8 @@ static SlangResult _parseVisualStudioLine(const UnownedStringSlice& line, Downst
}
// Extract the code
- outDiagnostic.code = UnownedStringSlice(errorSection.begin() + errorCodeIndex + 1, errorSection.end());
- if (outDiagnostic.code.startsWith(UnownedStringSlice::fromLiteral("LNK")))
+ outDiagnostic.code = allocator.allocate(errorSection.begin() + errorCodeIndex + 1, errorSection.end());
+ if (asStringSlice(outDiagnostic.code).startsWith(UnownedStringSlice::fromLiteral("LNK")))
{
outDiagnostic.stage = Diagnostic::Stage::Link;
}
@@ -430,16 +431,18 @@ static SlangResult _parseVisualStudioLine(const UnownedStringSlice& line, Downst
postError = UnownedStringSlice(postPath.begin() + errorColonIndex + 1, end);
}
- outDiagnostic.text = postError;
+ outDiagnostic.text = allocator.allocate(postError);
return SLANG_OK;
}
-/* static */SlangResult VisualStudioCompilerUtil::parseOutput(const ExecuteResult& exeRes, DownstreamDiagnostics& outDiagnostics)
+/* static */SlangResult VisualStudioCompilerUtil::parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* diagnostics)
{
- outDiagnostics.reset();
+ diagnostics->reset();
- outDiagnostics.rawDiagnostics = exeRes.standardOutput;
+ diagnostics->setRaw(CharSliceCaster::asTerminatedCharSlice(exeRes.standardOutput));
+
+ CharSliceAllocator allocator;
for (auto line : LineParser(exeRes.standardOutput.getUnownedSlice()))
{
@@ -448,17 +451,17 @@ static SlangResult _parseVisualStudioLine(const UnownedStringSlice& line, Downst
fprintf(stdout, "\n");
#endif
- Diagnostic diagnostic;
- if (SLANG_SUCCEEDED(_parseVisualStudioLine(line, diagnostic)))
+ ArtifactDiagnostic diagnostic;
+ if (SLANG_SUCCEEDED(_parseVisualStudioLine(allocator, line, diagnostic)))
{
- outDiagnostics.diagnostics.add(diagnostic);
+ diagnostics->add(diagnostic);
}
}
// if it has a compilation error.. set on output
- if (outDiagnostics.has(Diagnostic::Severity::Error))
+ if (diagnostics->hasOfAtLeastSeverity(ArtifactDiagnostic::Severity::Error))
{
- outDiagnostics.result = SLANG_FAIL;
+ diagnostics->setResult(SLANG_FAIL);
}
return SLANG_OK;
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.h b/source/compiler-core/slang-visual-studio-compiler-util.h
index 6c3011e7c..74d7e6292 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.h
+++ b/source/compiler-core/slang-visual-studio-compiler-util.h
@@ -12,7 +12,7 @@ struct VisualStudioCompilerUtil : public DownstreamCompilerBaseUtil
/// Calculate Visual Studio family compilers cmdLine arguments from options
static SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine);
/// Parse Visual Studio exeRes into CPPCompiler::Output
- static SlangResult parseOutput(const ExecuteResult& exeRes, DownstreamDiagnostics& outOutput);
+ static SlangResult parseOutput(const ExecuteResult& exeRes, IArtifactDiagnostics* outOutput);
static SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath);
@@ -29,7 +29,7 @@ public:
// CommandLineDownstreamCompiler impl - just forwards to the Util
virtual SlangResult calcArgs(const CompileOptions& options, CommandLine& cmdLine) SLANG_OVERRIDE { return Util::calcArgs(options, cmdLine); }
- virtual SlangResult parseOutput(const ExecuteResult& exeResult, DownstreamDiagnostics& output) SLANG_OVERRIDE { return Util::parseOutput(exeResult, output); }
+ virtual SlangResult parseOutput(const ExecuteResult& exeResult, IArtifactDiagnostics* diagnostics) SLANG_OVERRIDE { return Util::parseOutput(exeResult, diagnostics); }
virtual SlangResult calcModuleFilePath(const CompileOptions& options, StringBuilder& outPath) SLANG_OVERRIDE { return Util::calcModuleFilePath(options, outPath); }
virtual SlangResult calcCompileProducts(const CompileOptions& options, DownstreamProductFlags productFlags, List<String>& outPaths) SLANG_OVERRIDE { return Util::calcCompileProducts(options, productFlags, outPaths); }