summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2023-07-18 18:45:38 -0400
committerGitHub <noreply@github.com>2023-07-18 15:45:38 -0700
commit1fe5e83f3dcc8ef0efa2dd083ebdfab5d0f101a9 (patch)
tree9ea88993d0b1f5cad76c21ae3a60ed561bdc3c83 /source
parent4cb3eeb832b5fb29a61f2934b3daa5e42a3d6cde (diff)
nsight Aftermath crash example (#2984)
* Small fixes and improvements around reflection tool. * Make PrettyWriter printing a class. * Aftermath crash demo WIP. * Enable aftermath in test project. * Setting failCount. * Dumping out of source maps. * Improve comments. Simplify handling of compile products. * Other small fixes to aftermath example. * Added Emit SourceLocType. Track sourcemap association meaning. Improved documentation. * Small improvements. * Capture debug information for D3D11/D3D12/Vulkan. * Enable debug info. * Small improvements. * Improve aftermath example README.md.
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-source-loc.cpp100
-rw-r--r--source/compiler-core/slang-source-loc.h20
-rwxr-xr-xsource/slang/slang-compiler.h30
-rw-r--r--source/slang/slang-emit-source-writer.cpp2
-rw-r--r--source/slang/slang-ir-obfuscate-loc.cpp4
-rw-r--r--source/slang/slang.cpp102
6 files changed, 228 insertions, 30 deletions
diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp
index 8710cf91f..f9014e0d8 100644
--- a/source/compiler-core/slang-source-loc.cpp
+++ b/source/compiler-core/slang-source-loc.cpp
@@ -190,12 +190,41 @@ void SourceView::addDefaultLineDirective(SourceLoc directiveLoc)
m_entries.add(entry);
}
-SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView* sourceView, SourceLoc loc, HandleSourceLoc& outLoc)
+// Nominal-like types take into account line directives, and potentially source maps
+static bool _isNominalLike(SourceLocType type)
+{
+ return type == SourceLocType::Nominal || type == SourceLocType::Emit;
+}
+
+static bool _canFollowSourceMap(SourceFile* sourceFile, SourceLocType type)
+{
+ // If we don't have a source map we have nothing to follow
+ if (!sourceFile->getSourceMap())
+ {
+ return false;
+ }
+
+ // If it's obfuscated we can't follow if we are emitting
+ if (sourceFile->getSourceMapKind() == SourceMapKind::Obfuscated &&
+ type == SourceLocType::Emit)
+ {
+ return false;
+ }
+
+ return _isNominalLike(type);
+}
+
+static SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView* sourceView, SourceLoc loc, SourceLocType type, HandleSourceLoc& outLoc)
{
auto sourceFile = sourceView->getSourceFile();
+ if (!_canFollowSourceMap(sourceFile, type))
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
// Hold a list of sourceFiles visited so we can't end up in a loop of lookups
- List<SourceFile*> sourceFiles;
+ ShortList<SourceFile*, 8> sourceFiles;
sourceFiles.add(sourceFile);
Index entryIndex = -1;
@@ -240,8 +269,10 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView
sourceFiles.add(foundSourceFile);
// If it has a source map, we try and look up the current location in it's source map
- if (auto foundSourceMap = foundSourceFile->getSourceMap())
+ if (_canFollowSourceMap(foundSourceFile, type))
{
+ auto foundSourceMap = foundSourceFile->getSourceMap();
+
const auto foundEntryIndex = foundSourceMap->get().findEntry(entry.sourceLine, entry.sourceColumn);
// If we found the entry repeat the lookup
@@ -273,18 +304,30 @@ SlangResult _findLocWithSourceMap(SourceManager* lookupSourceManager, SourceView
return SLANG_OK;
}
-HandleSourceLoc SourceView::getHandleLoc(SourceLoc loc, SourceLocType type)
+
+SlangResult SourceView::_findSourceMapLoc(SourceLoc loc, SourceLocType type, HandleSourceLoc& outLoc)
{
- // If it's nominal
- if (type == SourceLocType::Nominal && m_sourceFile->getSourceMap())
+ // We only do source map lookups with nominal
+ if (!_isNominalLike(type))
{
- // TODO(JS):
- // Ideally we'd do the lookup on the "current" source manager rather than the source manager on this
- // view, which may be a parent to the current one.
- auto lookupSourceManager = m_sourceFile->getSourceManager();
+ return SLANG_E_NOT_FOUND;
+ }
- HandleSourceLoc handleLoc;
- if (SLANG_SUCCEEDED(_findLocWithSourceMap(lookupSourceManager, this, loc, handleLoc)))
+ // TODO(JS):
+ // Ideally we'd do the lookup on the "current" source manager rather than the source manager on this
+ // view, which may be a parent to the current one.
+ auto lookupSourceManager = m_sourceFile->getSourceManager();
+
+ HandleSourceLoc handleLoc;
+ SLANG_RETURN_ON_FAIL(_findLocWithSourceMap(lookupSourceManager, this, loc, type, outLoc));
+
+ return SLANG_OK;
+}
+
+HandleSourceLoc SourceView::getHandleLoc(SourceLoc loc, SourceLocType type)
+{
+ { HandleSourceLoc handleLoc;
+ if (SLANG_SUCCEEDED(_findSourceMapLoc(loc, type, handleLoc)))
{
return handleLoc;
}
@@ -307,22 +350,21 @@ HandleSourceLoc SourceView::getHandleLoc(SourceLoc loc, SourceLocType type)
HandleSourceLoc handleLoc;
handleLoc.column = columnIndex + 1;
handleLoc.line = lineIndex + 1;
-
- // Make up a default entry
- StringSlicePool::Handle pathHandle = StringSlicePool::Handle(0);
-
- // Only bother looking up the entry information if we want a 'Normal' lookup
- const int entryIndex = (type == SourceLocType::Nominal) ? findEntryIndex(loc) : -1;
- if (entryIndex >= 0)
+
+ // Only bother looking up the entry information if we want a 'Norminal'-like lookup
+ if (_isNominalLike(type))
{
- const Entry& entry = m_entries[entryIndex];
- // Adjust the line
- handleLoc.line += entry.m_lineAdjust;
- // Get the pathHandle..
- pathHandle = entry.m_pathHandle;
+ const int entryIndex = findEntryIndex(loc);
+ if (entryIndex >= 0)
+ {
+ const Entry& entry = m_entries[entryIndex];
+ // Adjust the line
+ handleLoc.line += entry.m_lineAdjust;
+ // Get the pathHandle..
+ handleLoc.pathHandle = entry.m_pathHandle;
+ }
}
- handleLoc.pathHandle = pathHandle;
return handleLoc;
}
@@ -371,6 +413,14 @@ PathInfo SourceView::getPathInfo(SourceLoc loc, SourceLocType type)
return getViewPathInfo();
}
+ {
+ HandleSourceLoc handleLoc;
+ if (SLANG_SUCCEEDED(_findSourceMapLoc(loc, type, handleLoc)))
+ {
+ return _getPathInfoFromHandle(handleLoc.pathHandle);
+ }
+ }
+
const int entryIndex = findEntryIndex(loc);
return _getPathInfoFromHandle((entryIndex >= 0) ? m_entries[entryIndex].m_pathHandle : StringSlicePool::Handle(0));
}
diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h
index fafff7de6..5c78c4293 100644
--- a/source/compiler-core/slang-source-loc.h
+++ b/source/compiler-core/slang-source-loc.h
@@ -164,6 +164,16 @@ struct SourceRange
SourceLoc end;
};
+/// Source maps associated with files are could be of different uses. We use the SourceMapKind
+/// to indicate the usage.
+///
+/// If the source map is obfuscated reasonable/desirable to ignore them on emit (if we didn't we leak information,
+/// and we don't emit into the locations in the obfuscated intermediate "file").
+enum class SourceMapKind
+{
+ Normal, ///< A regular source map
+ Obfuscated, ///< Obfuscated source map
+};
// Pre-declare
struct SourceManager;
@@ -256,8 +266,11 @@ public:
/// Get the source map associated with this file. If it's set when doing
/// lookup for source locations, the source map will be used
IBoxValue<SourceMap>* getSourceMap() const { return m_sourceMap; }
+ /// Get the source map kind
+ SourceMapKind getSourceMapKind() const { return m_sourceMapKind; }
+
/// Set a source map
- void setSourceMap(IBoxValue<SourceMap>* sourceMap) { m_sourceMap = sourceMap; }
+ void setSourceMap(IBoxValue<SourceMap>* sourceMap, SourceMapKind sourceMapKind) { m_sourceMap = sourceMap; m_sourceMapKind = sourceMapKind; }
/// Ctor
SourceFile(SourceManager* sourceManager, const PathInfo& pathInfo, size_t contentSize);
@@ -281,12 +294,15 @@ public:
// If set then the locations in this file are really from locations from elsewhere,
// where the SourceMap specifies that mapping
ComPtr<IBoxValue<SourceMap>> m_sourceMap;
+ // What kind of source map it is (if there is one)
+ SourceMapKind m_sourceMapKind = SourceMapKind::Normal;
};
enum class SourceLocType
{
Nominal, ///< The normal interpretation which takes into account #line directives and source maps
Actual, ///< Ignores #line directives/source maps - and is the location as seen in the actual file
+ Emit, ///< Behaves the same as `Nominal` but ignores source maps. Used for Emit source locations.
};
// A source location in a format a human might like to see
@@ -395,6 +411,8 @@ class SourceView
/// Get the pathInfo from a string handle. If it's 0, it will return the _getPathInfo
PathInfo _getPathInfoFromHandle(StringSlicePool::Handle pathHandle) const;
+ SlangResult _findSourceMapLoc(SourceLoc loc, SourceLocType type, HandleSourceLoc& outLoc);
+
String m_viewPath; ///< Path to this view. If empty the path is the path to the SourceView
SourceLoc m_initiatingSourceLoc; ///< An optional source loc that defines where this view was initiated from. SourceLoc(0) if not defined.
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index ca16bfb94..7d73599ba 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -297,6 +297,12 @@ namespace Slang
SlangInt targetIndex,
slang::IBlob** outCode,
slang::IBlob** outDiagnostics) SLANG_OVERRIDE;
+
+ SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE;
+
SLANG_NO_THROW SlangResult SLANG_MCALL specialize(
slang::SpecializationArg const* specializationArgs,
SlangInt specializationArgCount,
@@ -851,6 +857,14 @@ namespace Slang
return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE
+ {
+ return Super::getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem);
+ }
+
SLANG_NO_THROW SlangResult SLANG_MCALL specialize(
slang::SpecializationArg const* specializationArgs,
SlangInt specializationArgCount,
@@ -1067,6 +1081,14 @@ namespace Slang
return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE
+ {
+ return Super::getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem);
+ }
+
SLANG_NO_THROW SlangResult SLANG_MCALL specialize(
slang::SpecializationArg const* specializationArgs,
SlangInt specializationArgCount,
@@ -1221,6 +1243,14 @@ namespace Slang
return Super::getEntryPointCode(entryPointIndex, targetIndex, outCode, outDiagnostics);
}
+ SLANG_NO_THROW SlangResult SLANG_MCALL getResultAsFileSystem(
+ SlangInt entryPointIndex,
+ SlangInt targetIndex,
+ ISlangMutableFileSystem** outFileSystem) SLANG_OVERRIDE
+ {
+ return Super::getResultAsFileSystem(entryPointIndex, targetIndex, outFileSystem);
+ }
+
SLANG_NO_THROW SlangResult SLANG_MCALL specialize(
slang::SpecializationArg const* specializationArgs,
SlangInt specializationArgCount,
diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp
index 72696c94a..4ff547119 100644
--- a/source/slang/slang-emit-source-writer.cpp
+++ b/source/slang/slang-emit-source-writer.cpp
@@ -311,7 +311,7 @@ void SourceWriter::advanceToSourceLocation(const SourceLoc& sourceLocation)
}
// Workout the humane source location.
- const HumaneSourceLoc humaneSourceLoc = getSourceManager()->getHumaneLoc(sourceLocation);
+ const HumaneSourceLoc humaneSourceLoc = getSourceManager()->getHumaneLoc(sourceLocation, SourceLocType::Emit);
// If the location is valid, mark need to update, and the new location
if (humaneSourceLoc.line > 0)
diff --git a/source/slang/slang-ir-obfuscate-loc.cpp b/source/slang/slang-ir-obfuscate-loc.cpp
index ecc16d2b2..860633106 100644
--- a/source/slang/slang-ir-obfuscate-loc.cpp
+++ b/source/slang/slang-ir-obfuscate-loc.cpp
@@ -362,8 +362,8 @@ SlangResult obfuscateModuleLocs(IRModule* module, SourceManager* sourceManager)
sourceMap->addEntry(entries[i]);
}
- // Associate the sourceMap with the obfuscated file
- obfuscatedFile->setSourceMap(boxedSourceMap);
+ // Associate the sourceMap with the obfuscated file.
+ obfuscatedFile->setSourceMap(boxedSourceMap, SourceMapKind::Obfuscated);
// Set the obfuscated map onto the module
module->setObfuscatedSourceMap(boxedSourceMap);
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 760a119d1..e08bb2a62 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -3464,6 +3464,106 @@ SLANG_NO_THROW slang::ProgramLayout* SLANG_MCALL ComponentType::getLayout(
return asExternal(programLayout);
}
+static ICastable* _findDiagnosticRepresentation(IArtifact* artifact)
+{
+ if (auto rep = findAssociatedRepresentation<IArtifactDiagnostics>(artifact))
+ {
+ return rep;
+ }
+
+ for (auto associated : artifact->getAssociated())
+ {
+ if (isDerivedFrom(associated->getDesc().payload, ArtifactPayload::Diagnostics))
+ {
+ return associated;
+ }
+ }
+ return nullptr;
+}
+
+static IArtifact* _findObfuscatedSourceMap(IArtifact* artifact)
+{
+ // If we find any obfuscated source maps, we are done
+ for (auto associated : artifact->getAssociated())
+ {
+ const auto desc = associated->getDesc();
+
+ if (isDerivedFrom(desc.payload, ArtifactPayload::SourceMap) &&
+ isDerivedFrom(desc.style, ArtifactStyle::Obfuscated))
+ {
+ return associated;
+ }
+ }
+ return nullptr;
+}
+
+SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getResultAsFileSystem(
+ SlangInt entryPointIndex,
+ Int targetIndex,
+ ISlangMutableFileSystem** outFileSystem)
+{
+ ComPtr<ISlangBlob> diagnostics;
+ ComPtr<ISlangBlob> code;
+
+ SLANG_RETURN_ON_FAIL(getEntryPointCode(entryPointIndex, targetIndex, diagnostics.writeRef(), code.writeRef()));
+
+ auto linkage = getLinkage();
+
+ auto target = linkage->targets[targetIndex];
+
+ auto targetProgram = getTargetProgram(target);
+
+ IArtifact* artifact = targetProgram->getExistingEntryPointResult(entryPointIndex);
+
+ // Add diagnostics id needs be...
+ if (diagnostics && !_findDiagnosticRepresentation(artifact))
+ {
+ // Add as an associated
+
+ auto diagnosticsArtifact = Artifact::create(ArtifactDesc::make(Artifact::Kind::HumanText, ArtifactPayload::Diagnostics));
+ diagnosticsArtifact->addRepresentationUnknown(diagnostics);
+
+ artifact->addAssociated(diagnosticsArtifact);
+
+ SLANG_ASSERT(diagnosticsArtifact == _findDiagnosticRepresentation(artifact));
+ }
+
+ // Add obfuscated source maps
+ if (!_findObfuscatedSourceMap(artifact))
+ {
+ List<IRModule*> irModules;
+ enumerateIRModules([&](IRModule* irModule) -> void { irModules.add(irModule); });
+
+ for (auto irModule : irModules)
+ {
+ if (auto obfuscatedSourceMap = irModule->getObfuscatedSourceMap())
+ {
+ auto artifactDesc = ArtifactDesc::make(ArtifactKind::Json, ArtifactPayload::SourceMap, ArtifactStyle::Obfuscated);
+
+ // Create the source map artifact
+ auto sourceMapArtifact = Artifact::create(artifactDesc, obfuscatedSourceMap->get().m_file.getUnownedSlice());
+
+ sourceMapArtifact->addRepresentation(obfuscatedSourceMap);
+
+ // associate with the artifact
+ artifact->addAssociated(sourceMapArtifact);
+ }
+ }
+ }
+
+ // Turn into a file system and return
+ ComPtr<ISlangMutableFileSystem> fileSystem(new MemoryFileSystem);
+
+ // Filter the containerArtifact into things that can be written
+ ComPtr<IArtifact> writeArtifact;
+ SLANG_RETURN_ON_FAIL(ArtifactContainerUtil::filter(artifact, writeArtifact));
+ SLANG_RETURN_ON_FAIL(ArtifactContainerUtil::writeContainer(writeArtifact, "", fileSystem));
+
+ *outFileSystem = fileSystem.detach();
+
+ return SLANG_OK;
+}
+
SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getEntryPointCode(
SlangInt entryPointIndex,
Int targetIndex,
@@ -4983,7 +5083,7 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac
if (name.getLength())
{
auto sourceFile = sourceManager->findSourceFileByPathRecursively(name);
- sourceFile->setSourceMap(sourceMap);
+ sourceFile->setSourceMap(sourceMap, SourceMapKind::Obfuscated);
}
}
}