diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2023-03-17 11:05:15 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-17 11:05:15 -0400 |
| commit | 8a61b9dd0ca729df894dad4c89c6ce3bf39ef0be (patch) | |
| tree | b7f3da5d30772ba1497f14cdeb39935225183bbb /source/compiler-core | |
| parent | 9476d4543f4336a66308e55f722b0b0b2bd69dd2 (diff) | |
Support for producing SourceMap on emit (#2707)
* #include an absolute path didn't work - because paths were taken to always be relative.
* WIP source map.
* Split out handling of RttiTypeFuncs to a map type.
* Make RttiTypeFuncsMap hold default impls.
* Slightly more sophisticated RttiTypeFuncsMap
* Source map decoding.
* Fix tabs.
* Fix asserts due to negative values.
* Use less obscure mechanisms in SourceMap.
* Source map decoding.
Simplifying SourceMap usage.
* First attempt at ouputting a source map as part of emit.
* Added support for -source-map option. SourceMap is added to the artifact.
Diffstat (limited to 'source/compiler-core')
| -rw-r--r-- | source/compiler-core/slang-artifact-desc-util.cpp | 11 | ||||
| -rw-r--r-- | source/compiler-core/slang-artifact.h | 2 | ||||
| -rw-r--r-- | source/compiler-core/slang-source-map.cpp | 80 | ||||
| -rw-r--r-- | source/compiler-core/slang-source-map.h | 25 |
4 files changed, 116 insertions, 2 deletions
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp index fff68738c..ee014daf0 100644 --- a/source/compiler-core/slang-artifact-desc-util.cpp +++ b/source/compiler-core/slang-artifact-desc-util.cpp @@ -223,7 +223,8 @@ SLANG_HIERARCHICAL_ENUM(ArtifactKind, SLANG_ARTIFACT_KIND, SLANG_ARTIFACT_KIND_E x(Diagnostics, Metadata) \ x(Miscellaneous, Base) \ x(Log, Miscellaneous) \ - x(Lock, Miscellaneous) + x(Lock, Miscellaneous) \ + x(SourceMap, Base) #define SLANG_ARTIFACT_PAYLOAD_ENTRY(TYPE, PARENT) { Index(ArtifactPayload::TYPE), Index(ArtifactPayload::PARENT), #TYPE }, @@ -550,6 +551,13 @@ static const KindExtension g_cpuKindExts[] = return ArtifactDesc::make(ArtifactKind::Assembly, ArtifactPayload::HostCPU); } + // TODO(JS): Unfortunately map extension is also used from output for linkage from + // Visual Studio. It's used here for source map. + if (slice == toSlice("map")) + { + return ArtifactDesc::make(ArtifactKind::Text, ArtifactPayload::SourceMap); + } + if (slice == toSlice("pdb")) { // Program database @@ -621,6 +629,7 @@ static UnownedStringSlice _getPayloadExtension(ArtifactPayload payload) case Payload::MetalAIR: return toSlice("air"); case Payload::PdbDebugInfo: return toSlice("pdb"); + case Payload::SourceMap: return toSlice("map"); default: break; } diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h index df0bb21d5..c51ee729a 100644 --- a/source/compiler-core/slang-artifact.h +++ b/source/compiler-core/slang-artifact.h @@ -180,6 +180,8 @@ enum class ArtifactPayload : uint8_t PdbDebugInfo, ///< PDB debug info + SourceMap, ///< SourceMap + CountOf, }; diff --git a/source/compiler-core/slang-source-map.cpp b/source/compiler-core/slang-source-map.cpp index 413c32108..830314008 100644 --- a/source/compiler-core/slang-source-map.cpp +++ b/source/compiler-core/slang-source-map.cpp @@ -199,6 +199,86 @@ void SourceMap::clear() m_slicePool.clear(); } +void SourceMap::advanceToLine(Index nextLineIndex) +{ + const Count currentLineIndex = getGeneratedLineCount(); + + SLANG_ASSERT(nextLineIndex >= currentLineIndex); + + if (nextLineIndex <= currentLineIndex) + { + return; + } + + const auto lastEntryIndex = m_lineEntries.getCount(); + + // For all the new entries they will need to point to the end + m_lineStarts.setCount(nextLineIndex + 1); + + Index* starts = m_lineStarts.getBuffer() + currentLineIndex; + const Count startsCount = nextLineIndex + 1 - currentLineIndex; + + for (Index i = 0; i < startsCount; ++i) + { + starts[i] = lastEntryIndex; + } +} + +void SourceMap::addEntry(const Entry& entry) +{ + m_lineEntries.add(entry); + ++m_lineStarts.getLast(); + + // Check things seem normal... + SLANG_ASSERT(m_lineStarts.getLast() == m_lineEntries.getCount()); +} + +Index SourceMap::getNameIndex(const UnownedStringSlice& slice) +{ + StringSlicePool::Handle handle; + + if (!m_slicePool.findOrAdd(slice, handle)) + { + // We know it can't possibly be used, so must be new (!) + + m_names.add(handle); + return m_names.getCount() - 1; + } + + // Okay, could already be in the list + const auto index = m_names.indexOf(handle); + if (index >= 0) + { + return index; + } + + m_names.add(handle); + return m_names.getCount() - 1; +} + +Index SourceMap::getSourceFileIndex(const UnownedStringSlice& slice) +{ + StringSlicePool::Handle handle; + + if (!m_slicePool.findOrAdd(slice, handle)) + { + // We know it can't possibly be used, so must be new (!) + + m_sources.add(handle); + return m_sources.getCount() - 1; + } + + // Okay, could already be in the list + const auto index = m_sources.indexOf(handle); + if (index >= 0) + { + return index; + } + + m_sources.add(handle); + return m_sources.getCount() - 1; +} + SlangResult SourceMap::decode(JSONContainer* container, JSONValue root, DiagnosticSink* sink) { clear(); diff --git a/source/compiler-core/slang-source-map.h b/source/compiler-core/slang-source-map.h index 7fd64510a..739cf1992 100644 --- a/source/compiler-core/slang-source-map.h +++ b/source/compiler-core/slang-source-map.h @@ -15,10 +15,19 @@ namespace Slang { -struct SourceMap +struct SourceMap : public RefObject { struct Entry { + void init() + { + generatedColumn = 0; + sourceFileIndex = 0; + sourceLine = 0; + sourceColumn = 0; + nameIndex = 0; + } + // Note! All column/line are zero indexed Index generatedColumn; ///< The generated column Index sourceFileIndex; ///< The index into the source name/contents @@ -38,6 +47,20 @@ struct SourceMap /// Get the entries on the line SLANG_FORCE_INLINE ConstArrayView<Entry> getEntriesForLine(Index generatedLine) const; + /// Advance to the specified line index. + /// It is an error to specify a line *before* the current line. It should either be the current + /// output line or a later output line. Interveining lines will be set as empty + void advanceToLine(Index lineIndex); + + /// Add an entry to the current line + void addEntry(const Entry& entry); + + /// Given the slice returns the index + Index getSourceFileIndex(const UnownedStringSlice& slice); + + /// Get the name index + Index getNameIndex(const UnownedStringSlice& slice); + /// Clear the contents of the source map void clear(); |
