summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-03-17 11:05:15 -0400
committerGitHub <noreply@github.com>2023-03-17 11:05:15 -0400
commit8a61b9dd0ca729df894dad4c89c6ce3bf39ef0be (patch)
treeb7f3da5d30772ba1497f14cdeb39935225183bbb /source/compiler-core
parent9476d4543f4336a66308e55f722b0b0b2bd69dd2 (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.cpp11
-rw-r--r--source/compiler-core/slang-artifact.h2
-rw-r--r--source/compiler-core/slang-source-map.cpp80
-rw-r--r--source/compiler-core/slang-source-map.h25
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();