summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp4
-rw-r--r--source/core/slang-file-system.h2
-rw-r--r--source/slang/slang-compiler.cpp2
-rwxr-xr-xsource/slang/slang-compiler.h5
-rw-r--r--source/slang/slang-options.cpp158
-rw-r--r--source/slang/slang-repro.cpp6
-rw-r--r--source/slang/slang-repro.h4
7 files changed, 116 insertions, 65 deletions
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index 6956a3627..fc42dfc40 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -133,8 +133,8 @@ public:
// If it starts with ./ then attempt to strip it
if (filePath.startsWith("./"))
{
- String remaining(filePath.subString(2, filePath.getLength() - 2));
-
+ const String remaining = filePath.getUnownedSlice().tail(2);
+
// Okay if we strip ./ and what we have is absolute, then it's the absolute path that we care about,
// otherwise we just leave as is.
if (Path::isAbsolute(remaining))
diff --git a/source/core/slang-file-system.h b/source/core/slang-file-system.h
index 93d0659ec..6e29e277c 100644
--- a/source/core/slang-file-system.h
+++ b/source/core/slang-file-system.h
@@ -172,7 +172,7 @@ class CacheFileSystem: public ISlangFileSystemExt, public ComBaseObject
void setInnerFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, PathStyle pathStyle = PathStyle::Default);
/// Ctor
- CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, PathStyle pathStyle = PathStyle::Default);
+ explicit CacheFileSystem(ISlangFileSystem* fileSystem, UniqueIdentityMode uniqueIdentityMode = UniqueIdentityMode::Default, PathStyle pathStyle = PathStyle::Default);
/// Dtor
virtual ~CacheFileSystem();
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index eecb86242..9b14fd2f7 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -1412,7 +1412,7 @@ namespace Slang
options.requiredCapabilityVersions = SliceUtil::asSlice(requiredCapabilityVersions);
options.libraries = SliceUtil::asSlice(libraries);
options.libraryPaths = allocator.allocate(libraryPaths);
-
+
// Compile
ComPtr<IArtifact> artifact;
auto downstreamStartTime = std::chrono::high_resolution_clock::now();
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 6e4d7ff17..95995349a 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -19,6 +19,8 @@
#include "../core/slang-std-writers.h"
#include "../core/slang-command-options.h"
+#include "../core/slang-file-system.h"
+
#include "../../slang-com-ptr.h"
#include "slang-capability.h"
@@ -2697,6 +2699,9 @@ namespace Slang
/// Holds the container as a file system
ComPtr<ISlangMutableFileSystem> m_containerFileSystem;
+ /// File system used by repro system if a file couldn't be found within the repro (or associated directory)
+ ComPtr<ISlangFileSystem> m_reproFallbackFileSystem = ComPtr<ISlangFileSystem>(OSFileSystem::getExtSingleton());
+
// Path to output container to
String m_containerOutputPath;
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index c911baea4..67f95df1e 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -96,7 +96,6 @@ enum class OptionKind
VulkanUseEntryPointName,
VulkanUseGLLayout,
-
GLSLForceScalarLayout,
EnableEffectAnnotations,
@@ -111,6 +110,15 @@ enum class OptionKind
DownstreamArgs,
PassThrough,
+ // Repro
+
+ DumpRepro,
+ DumpReproOnError,
+ ExtractRepro,
+ LoadRepro,
+ LoadReproDirectory,
+ ReproFallbackDirectory,
+
// Debugging
DumpAst,
@@ -118,12 +126,7 @@ enum class OptionKind
DumpIntermediates,
DumpIr,
DumpIrIds,
- DumpRepro,
- DumpReproOnError,
PreprocessorOutput,
- ExtractRepro,
- LoadRepro,
- LoadReproDirectory,
NoCodeGen,
OutputIncludes,
ReproFileSystem,
@@ -223,6 +226,7 @@ void initCommandOptions(CommandOptions& options)
options.addCategory(CategoryKind::Option, "Target", "Target code generation options");
options.addCategory(CategoryKind::Option, "Downstream", "Downstream compiler options");
options.addCategory(CategoryKind::Option, "Debugging", "Compiler debugging/instrumentation options");
+ options.addCategory(CategoryKind::Option, "Repro", "Slang repro system related");
options.addCategory(CategoryKind::Option, "Experimental", "Experimental options (use at your own risk)");
options.addCategory(CategoryKind::Option, "Internal", "Internal-use options (use at your own risk)");
options.addCategory(CategoryKind::Option, "Deprecated", "Deprecated options (allowed but ignored; may be removed in future)");
@@ -562,6 +566,28 @@ void initCommandOptions(CommandOptions& options)
_addOptions(makeConstArrayView(downstreamOpts), options);
+ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Repro !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+ options.setCategory("Repro");
+
+ const Option reproOpts[] =
+ {
+ { OptionKind::DumpReproOnError, "-dump-repro-on-error", nullptr, "Dump `.slang-repro` file on any compilation error." },
+ { OptionKind::ExtractRepro, "-extract-repro", "-extract-repro <name>", "Extract the repro files into a folder." },
+ { OptionKind::LoadReproDirectory, "-load-repro-directory", "-load-repro-directory <path>", "Use repro along specified path" },
+ { OptionKind::LoadRepro, "-load-repro", "-load-repro <name>", "Load repro"},
+ { OptionKind::ReproFileSystem, "-repro-file-system", "-repro-file-system <name>", "Use a repro as a file system" },
+ { OptionKind::DumpRepro, "-dump-repro", nullptr, "Dump a `.slang-repro` file that can be used to reproduce "
+ "a compilation on another machine.\n"},
+ { OptionKind::ReproFallbackDirectory, "-repro-fallback-directory <path>",
+ "Specify a directory to use if a file isn't found in a repro. Should be specified *before* any repro usage such as `load-repro`. \n"
+ "There are two *special* directories: \n\n"
+ " * 'none:' indicates no fallback, so if the file isn't found in the repro compliation will fail\n"
+ " * 'default:' is the default (which is the OS file system)"}
+ };
+
+ _addOptions(makeConstArrayView(reproOpts), options);
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Debugging !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
options.setCategory("Debugging");
@@ -574,16 +600,9 @@ void initCommandOptions(CommandOptions& options)
{ OptionKind::DumpIntermediates, "-dump-intermediates", nullptr, "Dump intermediate outputs for debugging." },
{ OptionKind::DumpIr, "-dump-ir", nullptr, "Dump the IR for debugging." },
{ OptionKind::DumpIrIds, "-dump-ir-ids", nullptr, "Dump the IDs with -dump-ir (debug builds only)" },
- { OptionKind::DumpRepro, "-dump-repro", nullptr, "Dump a `.slang-repro` file that can be used to reproduce "
- "a compilation on another machine.\n"},
- { OptionKind::DumpReproOnError, "-dump-repro-on-error", nullptr, "Dump `.slang-repro` file on any compilation error." },
{ OptionKind::PreprocessorOutput, "-E,-output-preprocessor", nullptr, "Output the preprocessing result and exit." },
- { OptionKind::ExtractRepro, "-extract-repro", "-extract-repro <name>", "Extract the repro files into a folder." },
- { OptionKind::LoadReproDirectory, "-load-repro-directory", "-load-repro-directory <path>", "Use repro along specified path" },
- { OptionKind::LoadRepro, "-load-repro", "-load-repro <name>", "Load repro"},
{ OptionKind::NoCodeGen, "-no-codegen", nullptr, "Skip the code generation step, just check the code and generate layout." },
{ OptionKind::OutputIncludes, "-output-includes", nullptr, "Print the hierarchy of the processed source files." },
- { OptionKind::ReproFileSystem, "-repro-file-system", "-repro-file-system <name>", "Use a repro as a file system" },
{ OptionKind::SerialIr, "-serial-ir", nullptr, "Serialize the IR between front-end and back-end." },
{ OptionKind::SkipCodeGen, "-skip-codegen", nullptr, "Skip the code generation phase." },
{ OptionKind::ValidateIr, "-validate-ir", nullptr, "Validate the IR between the phases." },
@@ -790,7 +809,6 @@ struct OptionsParser
static bool _passThroughRequiresStage(PassThroughMode passThrough);
-
SlangResult _compileReproDirectory(SlangSession* session, EndToEndCompileRequest* originalRequest, const String& dir);
// Pass Severity::Disabled to allow any original severity
@@ -1166,7 +1184,33 @@ void OptionsParser::setFloatingPointMode(RawTarget* rawTarget, FloatingPointMode
}
}
-/* static */SlangResult OptionsParser::_compileReproDirectory(SlangSession* session, EndToEndCompileRequest* originalRequest, const String& dir)
+static SlangResult _loadRepro(const String& path, DiagnosticSink* sink, EndToEndCompileRequest* request)
+{
+ List<uint8_t> buffer;
+ SLANG_RETURN_ON_FAIL(ReproUtil::loadState(path, sink, buffer));
+
+ auto requestState = ReproUtil::getRequest(buffer);
+ MemoryOffsetBase base;
+ base.set(buffer.getBuffer(), buffer.getCount());
+
+ // If we can find a directory, that exists, we will set up a file system to load from that directory
+ ComPtr<ISlangFileSystem> optionalFileSystem;
+ String dirPath;
+ if (SLANG_SUCCEEDED(ReproUtil::calcDirectoryPathFromFilename(path, dirPath)))
+ {
+ SlangPathType pathType;
+ if (SLANG_SUCCEEDED(Path::getPathType(dirPath, &pathType)) && pathType == SLANG_PATH_TYPE_DIRECTORY)
+ {
+ optionalFileSystem = new RelativeFileSystem(OSFileSystem::getExtSingleton(), dirPath);
+ }
+ }
+
+ SLANG_RETURN_ON_FAIL(ReproUtil::load(base, requestState, optionalFileSystem, request));
+
+ return SLANG_OK;
+}
+
+SlangResult OptionsParser::_compileReproDirectory(SlangSession* session, EndToEndCompileRequest* originalRequest, const String& dir)
{
auto stdOut = originalRequest->getWriter(WriterChannel::StdOutput);
@@ -1175,34 +1219,28 @@ void OptionsParser::setFloatingPointMode(RawTarget* rawTarget, FloatingPointMode
for (auto filename : visitor.m_filenames)
{
- auto path = Path::combine(dir, filename);
-
+ // Create a fresh request
ComPtr<slang::ICompileRequest> request;
SLANG_RETURN_ON_FAIL(session->createCompileRequest(request.writeRef()));
auto requestImpl = asInternal(request);
- List<uint8_t> buffer;
- SLANG_RETURN_ON_FAIL(ReproUtil::loadState(path, m_sink, buffer));
+ // Copy over the fallback file system
+ requestImpl->m_reproFallbackFileSystem = originalRequest->m_reproFallbackFileSystem;
- auto requestState = ReproUtil::getRequest(buffer);
- MemoryOffsetBase base;
- base.set(buffer.getBuffer(), buffer.getCount());
+ // Load the repro into it
+ auto path = Path::combine(dir, filename);
- // If we can find a directory, that exists, we will set up a file system to load from that directory
- ComPtr<ISlangFileSystem> fileSystem;
- String dirPath;
- if (SLANG_SUCCEEDED(ReproUtil::calcDirectoryPathFromFilename(path, dirPath)))
+ if (SLANG_FAILED(_loadRepro(path, m_sink, requestImpl)))
{
- SlangPathType pathType;
- if (SLANG_SUCCEEDED(Path::getPathType(dirPath, &pathType)) && pathType == SLANG_PATH_TYPE_DIRECTORY)
+ if (stdOut)
{
- fileSystem = new RelativeFileSystem(OSFileSystem::getExtSingleton(), dirPath);
+ StringBuilder buf;
+ buf << filename << " - Failed to load!\n";
}
+ continue;
}
- SLANG_RETURN_ON_FAIL(ReproUtil::load(base, requestState, fileSystem, requestImpl));
-
if (stdOut)
{
StringBuilder buf;
@@ -1616,34 +1654,12 @@ SlangResult OptionsParser::_parseLoadRepro(const CommandLineArg& arg)
CommandLineArg reproName;
SLANG_RETURN_ON_FAIL(m_reader.expectArg(reproName));
- List<uint8_t> buffer;
- {
- const Result res = ReproUtil::loadState(reproName.value, m_sink, buffer);
- if (SLANG_FAILED(res))
- {
- m_sink->diagnose(reproName.loc, Diagnostics::unableToReadFile, reproName.value);
- return res;
- }
- }
-
- auto requestState = ReproUtil::getRequest(buffer);
- MemoryOffsetBase base;
- base.set(buffer.getBuffer(), buffer.getCount());
-
- // If we can find a directory, that exists, we will set up a file system to load from that directory
- ComPtr<ISlangFileSystem> fileSystem;
- String dirPath;
- if (SLANG_SUCCEEDED(ReproUtil::calcDirectoryPathFromFilename(reproName.value, dirPath)))
+ if (SLANG_FAILED(_loadRepro(reproName.value, m_sink, m_requestImpl)))
{
- SlangPathType pathType;
- if (SLANG_SUCCEEDED(Path::getPathType(dirPath, &pathType)) && pathType == SLANG_PATH_TYPE_DIRECTORY)
- {
- fileSystem = new RelativeFileSystem(OSFileSystem::getExtSingleton(), dirPath);
- }
+ m_sink->diagnose(reproName.loc, Diagnostics::unableToReadFile, reproName.value);
+ return SLANG_FAIL;
}
- SLANG_RETURN_ON_FAIL(ReproUtil::load(base, requestState, fileSystem, m_requestImpl));
-
m_hasLoadedRepro = true;
return SLANG_OK;
}
@@ -1916,6 +1932,36 @@ SlangResult OptionsParser::_parse(
SLANG_RETURN_ON_FAIL(_compileReproDirectory(m_session, m_requestImpl, reproDirectory.value));
break;
}
+ case OptionKind::ReproFallbackDirectory:
+ {
+ CommandLineArg reproDirectory;
+ SLANG_RETURN_ON_FAIL(m_reader.expectArg(reproDirectory));
+
+ if (reproDirectory.value == toSlice("default:"))
+ {
+ // The default is to use the OS file system
+ m_requestImpl->m_reproFallbackFileSystem = OSFileSystem::getExtSingleton();
+ }
+ else if (reproDirectory.value == toSlice("none:"))
+ {
+ // None, means that there isn't a fallback
+ m_requestImpl->m_reproFallbackFileSystem.setNull();
+ }
+ else
+ {
+ auto osFileSystem = OSFileSystem::getExtSingleton();
+
+ SlangPathType pathType;
+ if (SLANG_FAILED(osFileSystem->getPathType(reproDirectory.value.getBuffer(), &pathType) )
+ || pathType != SLANG_PATH_TYPE_DIRECTORY)
+ {
+ return SLANG_FAIL;
+ }
+ // Make the fallback directory use a relative file system, to the specified directory
+ m_requestImpl->m_reproFallbackFileSystem = new RelativeFileSystem(osFileSystem, reproDirectory.value);
+ }
+ break;
+ }
case OptionKind::ReproFileSystem: SLANG_RETURN_ON_FAIL(_parseReproFileSystem(arg)); break;
case OptionKind::SerialIr: m_frontEndReq->useSerialIRBottleneck = true; break;
case OptionKind::DisableSpecialization: m_requestImpl->disableSpecialization = true; break;
diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp
index de698cf46..a19470ebf 100644
--- a/source/slang/slang-repro.cpp
+++ b/source/slang/slang-repro.cpp
@@ -888,7 +888,7 @@ struct LoadContext
return SLANG_OK;
}
-/* static */SlangResult ReproUtil::load(OffsetBase& base, RequestState* requestState, ISlangFileSystem* fileSystem, EndToEndCompileRequest* request)
+/* static */SlangResult ReproUtil::load(OffsetBase& base, RequestState* requestState, ISlangFileSystem* optionalFileSystem, EndToEndCompileRequest* request)
{
auto externalRequest = asExternal(request);
@@ -902,7 +902,7 @@ struct LoadContext
linkage->targets.clear();
}
- LoadContext context(linkage->getSourceManager(), fileSystem, &base);
+ LoadContext context(linkage->getSourceManager(), optionalFileSystem, &base);
// Try to set state through API - as doing so means if state stored in multiple places it will be ok
@@ -1046,7 +1046,7 @@ struct LoadContext
}
{
- auto cacheFileSystem = new CacheFileSystem(nullptr);
+ auto cacheFileSystem = new CacheFileSystem(request->m_reproFallbackFileSystem);
ComPtr<ISlangFileSystemExt> fileSystemExt(cacheFileSystem);
auto& dstUniqueMap = cacheFileSystem->getUniqueMap();
auto& dstPathMap = cacheFileSystem->getPathMap();
diff --git a/source/slang/slang-repro.h b/source/slang/slang-repro.h
index 03276d6d3..39efcabc0 100644
--- a/source/slang/slang-repro.h
+++ b/source/slang/slang-repro.h
@@ -174,9 +174,9 @@ struct ReproUtil
static SlangResult loadFileSystem(OffsetBase& base, RequestState* requestState, ISlangFileSystem* fileSystem, ComPtr<ISlangFileSystemExt>& outFileSystem);
/// Load the requestState into request
- /// The fileSystem is optional and can be passed as nullptr. If set, as each file is loaded
+ /// The overrideFileSystem is optional and can be passed as nullptr. If set, as each file is loaded
/// it will attempt to load from fileSystem the *uniqueName*
- static SlangResult load(OffsetBase& base, RequestState* requestState, ISlangFileSystem* fileSystem, EndToEndCompileRequest* request);
+ static SlangResult load(OffsetBase& base, RequestState* requestState, ISlangFileSystem* overrideFileSystem, EndToEndCompileRequest* request);
static SlangResult loadState(const String& filename, DiagnosticSink* sink, List<uint8_t>& outBuffer);
static SlangResult loadState(Stream* stream, DiagnosticSink* sink, List<uint8_t>& outBuffer);