summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.cpp2
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.h2
-rw-r--r--source/compiler-core/slang-include-system.cpp3
-rw-r--r--source/compiler-core/slang-source-loc.cpp63
-rw-r--r--source/compiler-core/slang-source-loc.h12
-rw-r--r--source/core/slang-blob.cpp29
-rw-r--r--source/core/slang-blob.h20
-rw-r--r--source/slang/slang-compiler.cpp50
-rwxr-xr-xsource/slang/slang-compiler.h56
-rw-r--r--source/slang/slang-preprocessor.cpp3
-rw-r--r--source/slang/slang-reflection-api.cpp2
-rw-r--r--source/slang/slang-repro.cpp19
-rw-r--r--source/slang/slang.cpp273
13 files changed, 328 insertions, 206 deletions
diff --git a/source/compiler-core/slang-artifact-representation-impl.cpp b/source/compiler-core/slang-artifact-representation-impl.cpp
index 9a5c13311..950ce5d7d 100644
--- a/source/compiler-core/slang-artifact-representation-impl.cpp
+++ b/source/compiler-core/slang-artifact-representation-impl.cpp
@@ -23,7 +23,7 @@ void* ExtFileArtifactRepresentation::getInterface(const Guid& guid)
guid == IPathArtifactRepresentation::getTypeGuid() ||
guid == IExtFileArtifactRepresentation::getTypeGuid())
{
- return static_cast<IPathArtifactRepresentation*>(this);
+ return static_cast<IExtFileArtifactRepresentation*>(this);
}
return nullptr;
}
diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h
index da21e30bc..880a90c18 100644
--- a/source/compiler-core/slang-artifact-representation-impl.h
+++ b/source/compiler-core/slang-artifact-representation-impl.h
@@ -108,7 +108,7 @@ protected:
/* This allows wrapping any object to be an artifact representation.
-NOTE! Only allows casting from a single guid. Passing a RefObject across an ABI bounday remains risky!
+NOTE! Only allows casting from a single guid. Passing a RefObject across an ABI boundary remains risky!
*/
class ObjectArtifactRepresentation : public ComBaseObject, public IArtifactRepresentation
{
diff --git a/source/compiler-core/slang-include-system.cpp b/source/compiler-core/slang-include-system.cpp
index 9cd193ec6..ebfc8db05 100644
--- a/source/compiler-core/slang-include-system.cpp
+++ b/source/compiler-core/slang-include-system.cpp
@@ -132,8 +132,6 @@ SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>
sourceFile = m_sourceManager->createSourceFileWithBlob(pathInfo, foundSourceBlob);
m_sourceManager->addSourceFile(pathInfo.uniqueIdentity, sourceFile);
- sourceFile->maybeAddArtifact(nullptr, m_fileSystemExt);
-
outBlob = foundSourceBlob;
return SLANG_OK;
}
@@ -152,7 +150,6 @@ SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>
}
sourceFile->setContents(foundSourceBlob);
- sourceFile->maybeAddArtifact(nullptr, m_fileSystemExt);
outBlob = foundSourceBlob;
return SLANG_OK;
diff --git a/source/compiler-core/slang-source-loc.cpp b/source/compiler-core/slang-source-loc.cpp
index 6b4c5654d..ac6589e76 100644
--- a/source/compiler-core/slang-source-loc.cpp
+++ b/source/compiler-core/slang-source-loc.cpp
@@ -434,69 +434,6 @@ String SourceFile::calcVerbosePath() const
return m_pathInfo.foundPath;
}
-void SourceFile::maybeAddArtifact(const ArtifactDesc* inArtifactDesc, ISlangFileSystemExt* ext)
-{
- if (!m_contentBlob)
- {
- return;
- }
-
- // If there already is an artifact, we don't need to create one
- if (m_artifact)
- {
- // Check it has a blob and the blob is the same as the content blob
- SLANG_ASSERT(m_contentBlob == findRepresentation<ISlangBlob>(m_artifact));
- return;
- }
-
- ArtifactDesc artifactDesc;
-
- if (inArtifactDesc)
- {
- artifactDesc = *inArtifactDesc;
- }
- else
- {
- // Set the default
- artifactDesc = ArtifactDesc::make(ArtifactKind::Source, ArtifactPayload::Unknown, ArtifactStyle::Unknown);
-
- // Let's work out from the
- // We could try and work it out
- if (getPathInfo().foundPath.getLength())
- {
- // Let's work out what kind of source it is from the this
- auto desc = ArtifactDescUtil::getDescFromPath(getPathInfo().foundPath.getUnownedSlice());
-
- // If found something just use that
- if (desc.kind == ArtifactKind::Source)
- {
- artifactDesc = desc;
- }
- }
- }
-
- // We don't know how the source will be used
- m_artifact = Artifact::create(artifactDesc);
-
- // Add the blob as a representation.
- m_artifact->addRepresentationUnknown(m_contentBlob);
-
- // If we have the file system, set up the rep to that
- if (ext)
- {
- // Add the representation on the file system
- auto extRep = new ExtFileArtifactRepresentation(getPathInfo().foundPath.getUnownedSlice(), ext);
- m_artifact->addRepresentation(extRep);
- }
-
- // Get the name
- auto name = getPathInfo().getName();
- if (name.getLength())
- {
- m_artifact->setName(name.getBuffer());
- }
-}
-
/* !!!!!!!!!!!!!!!!!!!!!!!!! SourceManager !!!!!!!!!!!!!!!!!!!!!!!!!!!! */
void SourceManager::initialize(
diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h
index 29ed9dfbb..66e4c0475 100644
--- a/source/compiler-core/slang-source-loc.h
+++ b/source/compiler-core/slang-source-loc.h
@@ -9,8 +9,6 @@
#include "../../slang-com-ptr.h"
#include "../../slang.h"
-#include "slang-artifact-representation.h"
-
namespace Slang {
/** Overview:
@@ -236,20 +234,11 @@ public:
/// Get path info
const PathInfo& getPathInfo() const { return m_pathInfo; }
- /// Get the (optional) assoicated artifact. Note its desc might be Source/Unknown
- IArtifact* getArtifact() const { return m_artifact; }
- /// Set the artifact
- void setArtifact(IArtifact* artifact) { m_artifact = artifact; }
-
/// Set the content as a blob
void setContents(ISlangBlob* blob);
/// Set the content as a string
void setContents(const String& content);
- /// If the desc isn't set, will use Unknown source type
- /// If artifact isn't defined will try and associate one.
- void maybeAddArtifact(const ArtifactDesc* desc, ISlangFileSystemExt* ext);
-
/// Calculate a display path -> can canonicalize if necessary
String calcVerbosePath() const;
@@ -266,7 +255,6 @@ public:
SourceManager* m_sourceManager; ///< The source manager this belongs to
PathInfo m_pathInfo; ///< The path The logical file path to report for locations inside this span.
- ComPtr<IArtifact> m_artifact; ///< Optional artifact
ComPtr<ISlangBlob> m_contentBlob; ///< A blob that owns the storage for the file contents. If nullptr, there is no contents
UnownedStringSlice m_content; ///< The actual contents of the file.
size_t m_contentSize; ///< The size of the actual contents
diff --git a/source/core/slang-blob.cpp b/source/core/slang-blob.cpp
index 6cf5214cc..a4acb98cb 100644
--- a/source/core/slang-blob.cpp
+++ b/source/core/slang-blob.cpp
@@ -35,6 +35,25 @@ void* BlobBase::castAs(const SlangUUID& guid)
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StringBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+StringBlob::StringBlob(MoveUnique, String& in)
+{
+ auto rep = in.getStringRepresentation();
+ if (rep && !rep->isUniquelyReferenced())
+ {
+ // Make a new unique copy
+ m_string = in.getUnownedSlice();
+
+ // Move out of in
+ String tmp;
+ tmp.swapWith(in);
+ }
+ else
+ {
+ // Must either not have a rep or be unique
+ m_string.swapWith(in);
+ }
+}
+
void* StringBlob::castAs(const SlangUUID& guid)
{
if (auto intf = getInterface(guid))
@@ -59,6 +78,16 @@ void* StringBlob::getObject(const Guid& guid)
return nullptr;
}
+/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String& in)
+{
+ return ComPtr<ISlangBlob>(new StringBlob(MoveUnique{}, in));
+}
+
+/* static */ComPtr<ISlangBlob> StringBlob::moveCreate(String&& in)
+{
+ return ComPtr<ISlangBlob>(new StringBlob(MoveUnique{}, in));
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! RawBlob !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* RawBlob::castAs(const SlangUUID& guid)
diff --git a/source/core/slang-blob.h b/source/core/slang-blob.h
index 1acf279ef..e528f55a8 100644
--- a/source/core/slang-blob.h
+++ b/source/core/slang-blob.h
@@ -50,17 +50,25 @@ public:
SLANG_NO_THROW size_t SLANG_MCALL getBufferSize() SLANG_OVERRIDE { return m_string.getLength(); }
static ComPtr<ISlangBlob> create(const String& in) { return ComPtr<ISlangBlob>(new StringBlob(in)); }
- static ComPtr<ISlangBlob> moveCreate(String& in)
- {
- auto blob = new StringBlob;
- blob->m_string.swapWith(in);
- return ComPtr<ISlangBlob>(blob);
- }
+
+ /// Moves from in into the created blob.
+ /// NOTE! That will only use the representation from in, if it is *unique*
+ /// otherwise it will make a new copy.
+ /// This is so that StringBlob won't hold a reference count via a string held externally.
+ /// In contrast StringBlob::create *may* share the representation.
+ static ComPtr<ISlangBlob> moveCreate(String& in);
+ static ComPtr<ISlangBlob> moveCreate(String&& in);
protected:
+ /// A type that is only used to differentiate a constructor. Can construct with
+ /// MoveUnique{}
+ struct MoveUnique {};
+
explicit StringBlob(String const& string)
: m_string(string)
{}
+
+ StringBlob(MoveUnique, String& string);
StringBlob() {}
/// Get the contained string
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index ce380681e..06cc9d759 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -578,6 +578,22 @@ namespace Slang
}
}
+ SlangResult CodeGenContext::requireTranslationUnitSourceFiles()
+ {
+ if (auto endToEndReq = isPassThroughEnabled())
+ {
+ for (auto entryPointIndex : getEntryPointIndices())
+ {
+ auto translationUnit = getPassThroughTranslationUnit(endToEndReq, entryPointIndex);
+ SLANG_ASSERT(translationUnit);
+ /// Make sure we have the source files
+ SLANG_RETURN_ON_FAIL(translationUnit->requireSourceFiles());
+ }
+ }
+
+ return SLANG_OK;
+ }
+
#if SLANG_VC
// TODO(JS): This is a workaround
// In debug VS builds there is a warning on line about it being unreachable.
@@ -587,9 +603,11 @@ namespace Slang
# pragma warning(disable:4702)
#endif
SlangResult CodeGenContext::emitEntryPointsSource(ComPtr<IArtifact>& outArtifact)
- {
+ {
outArtifact.setNull();
+ SLANG_RETURN_ON_FAIL(requireTranslationUnitSourceFiles());
+
auto endToEndReq = isPassThroughEnabled();
if(endToEndReq)
{
@@ -597,6 +615,10 @@ namespace Slang
{
auto translationUnit = getPassThroughTranslationUnit(endToEndReq, entryPointIndex);
SLANG_ASSERT(translationUnit);
+
+ /// Make sure we have the source files
+ SLANG_RETURN_ON_FAIL(translationUnit->requireSourceFiles());
+
// Generate a string that includes the content of
// the source file(s), along with a line directive
// to ensure that we get reasonable messages
@@ -835,23 +857,7 @@ namespace Slang
if (compiler->isFileBased())
{
// It can only have *one* source file as otherwise we have to combine to make a new source file anyway
- const auto& sourceFiles = translationUnit->getSourceFiles();
-
- // The *assumption* here is that if it's file based that assuming it can find the file with the same contents
- // it can compile directly without having to save off as a file
- if (sourceFiles.getCount() == 1)
- {
- const SourceFile* sourceFile = sourceFiles[0];
- // We need the path to be found and set
- //
- // NOTE! That the downstream compiler can determine if the path and contents match such that it can be used
- // without writing file
- const PathInfo& pathInfo = sourceFile->getPathInfo();
- if ((pathInfo.type == PathInfo::Type::FoundPath || pathInfo.type == PathInfo::Type::Normal) && pathInfo.foundPath.getLength())
- {
- return false;
- }
- }
+ return translationUnit->getSourceArtifacts().getCount() != 1;
}
return true;
}
@@ -1066,12 +1072,10 @@ namespace Slang
else
{
// Special case if we have a single file, so that we pass the path, and the contents as is.
- const auto& sourceFiles = translationUnit->getSourceFiles();
- SLANG_ASSERT(sourceFiles.getCount() == 1);
-
- SourceFile* sourceFile = sourceFiles[0];
+ const auto& sourceArtifacts = translationUnit->getSourceArtifacts();
+ SLANG_ASSERT(sourceArtifacts.getCount() == 1);
- sourceArtifact = sourceFile->getArtifact();
+ sourceArtifact = sourceArtifacts[0];
SLANG_ASSERT(sourceArtifact);
}
}
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index 4c6b0a6b1..8aba89677 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -1381,19 +1381,33 @@ namespace Slang
// The parent compile request
FrontEndCompileRequest* compileRequest = nullptr;
- // The language in which the source file(s)
- // are assumed to be written
+ // The language in which the source file(s)
+ // are assumed to be written
SourceLanguage sourceLanguage = SourceLanguage::Unknown;
- // The source file(s) that will be compiled to form this translation unit
- //
- // Usually, for HLSL or GLSL there will be only one file.
- List<SourceFile*> m_sourceFiles;
+ /// Makes any source artifact available as a SourceFile.
+ /// If successful any of the source artifacts will be represented by the same index
+ /// of sourceArtifacts
+ SlangResult requireSourceFiles();
+
+ /// Get the source files.
+ /// Since lazily evaluated requires calling requireSourceFiles to know it's in sync
+ /// with sourceArtifacts.
+ List<SourceFile*> const& getSourceFiles();
+
+ /// Get the source artifacts associated
+ const List<ComPtr<IArtifact>>& getSourceArtifacts() const { return m_sourceArtifacts; }
+
+ /// Clear all of the source
+ void clearSource() { m_sourceArtifacts.clear(); m_sourceFiles.clear(); }
+
+ /// Add a source artifact
+ void addSourceArtifact(IArtifact* sourceArtifact);
- List<SourceFile*> const& getSourceFiles() { return m_sourceFiles; }
- void addSourceFile(SourceFile* sourceFile);
+ /// Add both the artifact and the sourceFile.
+ void addSource(IArtifact* sourceArtifact, SourceFile* sourceFile);
- // The entry points associated with this translation unit
+ // The entry points associated with this translation unit
List<RefPtr<EntryPoint>> const& getEntryPoints() { return module->getEntryPoints(); }
void _addEntryPoint(EntryPoint* entryPoint) { module->_addEntryPoint(entryPoint); }
@@ -1414,6 +1428,17 @@ namespace Slang
Session* getSession();
NamePool* getNamePool();
SourceManager* getSourceManager();
+
+ protected:
+ void _addSourceFile(SourceFile* sourceFile);
+
+ List<ComPtr<IArtifact>> m_sourceArtifacts;
+ // The source file(s) that will be compiled to form this translation unit
+ //
+ // Usually, for HLSL or GLSL there will be only one file.
+ // NOTE! This member is generated lazily from m_sourceArtifacts
+ // it is *necessary* to call requireSourceFiles to ensure it's in sync.
+ List<SourceFile*> m_sourceFiles;
};
enum class FloatingPointMode : SlangFloatingPointModeIntegral
@@ -2007,20 +2032,15 @@ namespace Slang
int addTranslationUnit(TranslationUnitRequest* translationUnit);
- void addTranslationUnitSourceFile(
+ void addTranslationUnitSourceArtifact(
int translationUnitIndex,
- SourceFile* sourceFile);
+ IArtifact* sourceArtifact);
void addTranslationUnitSourceBlob(
int translationUnitIndex,
String const& path,
ISlangBlob* sourceBlob);
- void addTranslationUnitSourceString(
- int translationUnitIndex,
- String const& path,
- String const& source);
-
void addTranslationUnitSourceFile(
int translationUnitIndex,
String const& path);
@@ -2386,6 +2406,8 @@ namespace Slang
bool isSpecializationDisabled();
+ SlangResult requireTranslationUnitSourceFiles();
+
//
SlangResult emitEntryPoints(ComPtr<IArtifact>& outArtifact);
@@ -2890,7 +2912,7 @@ namespace Slang
void addBuiltinSource(
Scope* scope,
String const& path,
- String const& source);
+ ISlangBlob* sourceBlob);
~Session();
void addDownstreamCompileTime(double time) { m_downstreamCompileTime += time; }
diff --git a/source/slang/slang-preprocessor.cpp b/source/slang/slang-preprocessor.cpp
index 739860915..fca8f5029 100644
--- a/source/slang/slang-preprocessor.cpp
+++ b/source/slang/slang-preprocessor.cpp
@@ -3057,9 +3057,6 @@ static void HandleIncludeDirective(PreprocessorDirectiveContext* context)
sourceFile = sourceManager->createSourceFileWithBlob(filePathInfo, foundSourceBlob);
- auto fileSystemExt = context->m_preprocessor->fileSystem;
- sourceFile->maybeAddArtifact(nullptr, fileSystemExt);
-
sourceManager->addSourceFile(filePathInfo.uniqueIdentity, sourceFile);
}
diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp
index ae43f9113..eb2b9aff9 100644
--- a/source/slang/slang-reflection-api.cpp
+++ b/source/slang/slang-reflection-api.cpp
@@ -1245,7 +1245,7 @@ namespace Slang
auto access = resourceType->getAccess();
auto mutableFlag = access != SLANG_RESOURCE_ACCESS_READ ? SLANG_BINDING_TYPE_MUTABLE_FLAG : 0;
- switch( shape )
+ switch(SlangResourceShape(shape ))
{
default:
return SlangBindingType(SLANG_BINDING_TYPE_TEXTURE | mutableFlag);
diff --git a/source/slang/slang-repro.cpp b/source/slang/slang-repro.cpp
index aa4dc92fc..1597366d6 100644
--- a/source/slang/slang-repro.cpp
+++ b/source/slang/slang-repro.cpp
@@ -10,6 +10,9 @@
#include "slang-options.h"
+#include "../compiler-core/slang-artifact-util.h"
+#include "../compiler-core/slang-artifact-desc-util.h"
+
#include "../compiler-core/slang-source-loc.h"
namespace Slang {
@@ -996,15 +999,25 @@ struct LoadContext
dstTranslationUnit->moduleName = moduleName;
const auto& srcSourceFiles = srcTranslationUnit.sourceFiles;
- auto& dstSourceFiles = dstTranslationUnit->m_sourceFiles;
- dstSourceFiles.clear();
+ dstTranslationUnit->clearSource();
+
+ const auto sourceDesc = ArtifactDescUtil::makeDescForSourceLanguage(asExternal(dstTranslationUnit->sourceLanguage));
for (Index j = 0; j < srcSourceFiles.getCount(); ++j)
{
+ // Create the source file
SourceFile* sourceFile = context.getSourceFile(base.asRaw(base.asRaw(srcSourceFiles[i])));
+
+ // Create the artifact
+ auto sourceArtifact = ArtifactUtil::createArtifact(sourceDesc, sourceFile->getPathInfo().getName().getBuffer());
+ if (sourceFile->getContentBlob())
+ {
+ sourceArtifact->addRepresentationUnknown(sourceFile->getContentBlob());
+ }
+
// Add to translation unit
- dstTranslationUnit->addSourceFile(sourceFile);
+ dstTranslationUnit->addSource(sourceArtifact, sourceFile);
}
}
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index a7a4fc8dc..18b9b3c99 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -249,13 +249,15 @@ void Session::_initCodeGenTransitionMap()
void Session::addBuiltins(
char const* sourcePath,
- char const* sourceString)
+ char const* source)
{
+ auto sourceBlob = StringBlob::moveCreate(String(source));
+
// TODO(tfoley): Add ability to directly new builtins to the appropriate scope
addBuiltinSource(
coreLanguageScope,
sourcePath,
- sourceString);
+ sourceBlob);
}
void Session::setSharedLibraryLoader(ISlangSharedLibraryLoader* loader)
@@ -295,9 +297,9 @@ SlangResult Session::compileStdLib(slang::CompileStdLibFlags compileFlags)
}
// TODO(JS): Could make this return a SlangResult as opposed to exception
- addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode());
- addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode());
- addBuiltinSource(autodiffLanguageScope, "diff", getAutodiffLibraryCode());
+ addBuiltinSource(coreLanguageScope, "core", StringBlob::moveCreate(getCoreLibraryCode()));
+ addBuiltinSource(hlslLanguageScope, "hlsl", StringBlob::moveCreate(getHLSLLibraryCode()));
+ addBuiltinSource(autodiffLanguageScope, "diff", StringBlob::moveCreate(getAutodiffLibraryCode()));
if (compileFlags & slang::CompileStdLibFlag::WriteDocumentation)
{
@@ -1489,7 +1491,120 @@ SourceManager* TranslationUnitRequest::getSourceManager()
return compileRequest->getSourceManager();
}
-void TranslationUnitRequest::addSourceFile(SourceFile* sourceFile)
+void TranslationUnitRequest::addSourceArtifact(IArtifact* sourceArtifact)
+{
+ SLANG_ASSERT(sourceArtifact);
+ m_sourceArtifacts.add(ComPtr<IArtifact>(sourceArtifact));
+}
+
+
+void TranslationUnitRequest::addSource(IArtifact* sourceArtifact, SourceFile* sourceFile)
+{
+ SLANG_ASSERT(sourceArtifact && sourceFile);
+ // Must be in sync!
+ SLANG_ASSERT(m_sourceFiles.getCount() == m_sourceArtifacts.getCount());
+
+ addSourceArtifact(sourceArtifact);
+ _addSourceFile(sourceFile);
+}
+
+SlangResult TranslationUnitRequest::requireSourceFiles()
+{
+ SLANG_ASSERT(m_sourceFiles.getCount() <= m_sourceArtifacts.getCount());
+
+ if (m_sourceFiles.getCount() == m_sourceArtifacts.getCount())
+ {
+ return SLANG_OK;
+ }
+
+ auto sink = compileRequest->getSink();
+ SourceManager* sourceManager = compileRequest->getSourceManager();
+
+ // Get he linkage file system
+ //ISlangFileSystemExt* linkageFileSystem = compileRequest->getLinkage()->getFileSystemExt();
+
+ for (Index i = m_sourceFiles.getCount(); i < m_sourceArtifacts.getCount(); ++i)
+ {
+ IArtifact* artifact = m_sourceArtifacts[i];
+
+ PathInfo pathInfo = PathInfo::makeUnknown();
+
+ if (auto extRep = findRepresentation<IExtFileArtifactRepresentation>(artifact))
+ {
+ auto extFileSystem = extRep->getFileSystem();
+
+ // TODO(JS):
+ // Ideally we'd confirm that the file system was the same, such we could know that the unique
+ // identity is appropriate for the current file system.
+ //
+ // We just assume compatibility for the moment, because repro will be a different file system
+ // but we need to use the unique identity that is there.
+
+ //if (extFileSystem == linkageFileSystem)
+ {
+ // Get the unique identity
+ ComPtr<ISlangBlob> uniqueIdentityBlob;
+ if (SLANG_SUCCEEDED(extFileSystem->getFileUniqueIdentity(extRep->getPath(), uniqueIdentityBlob.writeRef())) && uniqueIdentityBlob)
+ {
+ auto uniqueIdentity = StringUtil::getString(uniqueIdentityBlob);
+
+ // See if this an already loaded source file
+ if (auto sourceFile = sourceManager->findSourceFileRecursively(uniqueIdentity))
+ {
+ // If the source file has a blob, and the artifact doesn't copy over that representation
+ if (sourceFile->getContentBlob() && findRepresentation<ISlangBlob>(artifact) == nullptr)
+ {
+ artifact->addRepresentationUnknown(sourceFile->getContentBlob());
+ }
+
+ _addSourceFile(sourceFile);
+ continue;
+ }
+
+ pathInfo = PathInfo::makeNormal(extRep->getPath(), uniqueIdentity);
+ }
+ else
+ {
+ pathInfo = PathInfo::makePath(extRep->getPath());
+ }
+ }
+ }
+
+ if (pathInfo.type == PathInfo::Type::Unknown)
+ {
+ const auto path = ArtifactUtil::findPath(artifact);
+
+ // If has a path representation we'll make it a FoundPath
+ if (findRepresentation<IPathArtifactRepresentation>(artifact))
+ {
+ pathInfo = PathInfo::makePath(path);
+ }
+ else
+ {
+ // Otherwise we'll assume it's created from a 'String' even if that's not quite the case
+ pathInfo = PathInfo::makeFromString(path);
+ }
+ }
+
+ ComPtr<ISlangBlob> blob;
+ const SlangResult blobRes = artifact->loadBlob(ArtifactKeep::Yes, blob.writeRef());
+ if (SLANG_FAILED(blobRes))
+ {
+ // Report couldn't load
+ sink->diagnose(SourceLoc(),
+ Diagnostics::cannotOpenFile,
+ pathInfo.getName());
+ return blobRes;
+ }
+
+ auto sourceFile = sourceManager->createSourceFileWithBlob(pathInfo, blob);
+ _addSourceFile(sourceFile);
+ }
+
+ return SLANG_OK;
+}
+
+void TranslationUnitRequest::_addSourceFile(SourceFile* sourceFile)
{
m_sourceFiles.add(sourceFile);
@@ -1505,6 +1620,12 @@ void TranslationUnitRequest::addSourceFile(SourceFile* sourceFile)
}
}
+List<SourceFile*> const& TranslationUnitRequest::getSourceFiles()
+{
+ SLANG_ASSERT(m_sourceArtifacts.getCount() == m_sourceFiles.getCount());
+ return m_sourceFiles;
+}
+
EndToEndCompileRequest::~EndToEndCompileRequest()
{
// Flush any writers associated with the request
@@ -2246,8 +2367,11 @@ SlangResult FrontEndCompileRequest::executeActionsInner()
// We currently allow GlSL files on the command line so that we can
// drive our "pass-through" mode, but we really want to issue an error
// message if the user is seriously asking us to compile them.
- for (auto& translationUnit : translationUnits)
+ for (TranslationUnitRequest* translationUnit : translationUnits)
{
+ // Make sure SourceFile representation is available for all translationUnits
+ SLANG_RETURN_ON_FAIL(translationUnit->requireSourceFiles());
+
switch(translationUnit->sourceLanguage)
{
default:
@@ -2261,9 +2385,9 @@ SlangResult FrontEndCompileRequest::executeActionsInner()
// Parse everything from the input files requested
- for (auto& translationUnit : translationUnits)
+ for (TranslationUnitRequest* translationUnit : translationUnits)
{
- parseTranslationUnit(translationUnit.Ptr());
+ parseTranslationUnit(translationUnit);
}
if (outputPreprocessor)
@@ -2559,47 +2683,14 @@ int FrontEndCompileRequest::addTranslationUnit(TranslationUnitRequest* translati
return (int) result;
}
-
-void FrontEndCompileRequest::addTranslationUnitSourceFile(
+void FrontEndCompileRequest::addTranslationUnitSourceArtifact(
int translationUnitIndex,
- SourceFile* sourceFile)
+ IArtifact* sourceArtifact)
{
auto translationUnit = translationUnits[translationUnitIndex];
- // TODO(JS):
- // The larger problem here is that a file on a file system *could* be interpretted in different ways.
- // When the user supplies the source as a string, we use the source type specified for the translation unit.
- //
- // If it's on the file system it could be (say) compiled as HLSL or some other way. A *downstream* compiler
- // that used the file system may care.
- //
- // We will assume here, that if it's loaded from the file system, it's path extension defines how it should be interpretted
- // If that wasn't the case we'd have to either *copy*, or do some command line fiddling to tell it for the downstream compiler
- // what the file is.
-
- const auto& pathInfo = sourceFile->getPathInfo();
- const auto pathType = pathInfo.type;
-
- switch (pathType)
- {
- case PathInfo::Type::FromString:
- {
- // Set the artifact type from the the source language type
- auto sourceDesc = ArtifactDescUtil::makeDescForSourceLanguage(asExternal(translationUnit->sourceLanguage));
- sourceFile->maybeAddArtifact(&sourceDesc, nullptr);
- break;
- }
- case PathInfo::Type::FoundPath:
- case PathInfo::Type::Normal:
- {
- // We'll *not* use the source for the artifact type. Doing so will lead to the type being determined via extension
- sourceFile->maybeAddArtifact(nullptr, getLinkage()->getFileSystemExt());
- break;
- }
- }
-
// Add the source file
- translationUnit->addSourceFile(sourceFile);
+ translationUnit->addSourceArtifact(sourceArtifact);
}
void FrontEndCompileRequest::addTranslationUnitSourceBlob(
@@ -2607,21 +2698,13 @@ void FrontEndCompileRequest::addTranslationUnitSourceBlob(
String const& path,
ISlangBlob* sourceBlob)
{
- // The path specified may or may not be a file path - mark as being constructed 'FromString'.
- SourceFile* sourceFile = getSourceManager()->createSourceFileWithBlob(PathInfo::makeFromString(path), sourceBlob);
-
- addTranslationUnitSourceFile(translationUnitIndex, sourceFile);
-}
+ auto translationUnit = translationUnits[translationUnitIndex];
+ auto sourceDesc = ArtifactDescUtil::makeDescForSourceLanguage(asExternal(translationUnit->sourceLanguage));
-void FrontEndCompileRequest::addTranslationUnitSourceString(
- int translationUnitIndex,
- String const& path,
- String const& source)
-{
- // The path specified may or may not be a file path - mark as being constructed 'FromString'.
- SourceFile* sourceFile = getSourceManager()->createSourceFileWithString(PathInfo::makeFromString(path), source);
+ auto artifact = ArtifactUtil::createArtifact(sourceDesc, path.getBuffer());
+ artifact->addRepresentationUnknown(sourceBlob);
- addTranslationUnitSourceFile(translationUnitIndex, sourceFile);
+ translationUnit->addSourceArtifact(artifact);
}
void FrontEndCompileRequest::addTranslationUnitSourceFile(
@@ -2636,11 +2719,35 @@ void FrontEndCompileRequest::addTranslationUnitSourceFile(
// paths were not taken into account by this function.
//
- PathInfo pathInfo;
+ auto fileSystemExt = getLinkage()->getFileSystemExt();
+ auto translationUnit = getTranslationUnit(translationUnitIndex);
+
+ auto sourceDesc = ArtifactDescUtil::makeDescForSourceLanguage(asExternal(translationUnit->sourceLanguage));
+
+ auto sourceArtifact = ArtifactUtil::createArtifact(sourceDesc);
- ComPtr<ISlangBlob> sourceBlob;
- SlangResult result = loadFile(path, pathInfo, sourceBlob.writeRef());
- if(SLANG_FAILED(result))
+ auto extRep = new ExtFileArtifactRepresentation(path.getUnownedSlice(), fileSystemExt);
+ sourceArtifact->addRepresentation(extRep);
+
+ SlangResult existsRes = SLANG_OK;
+
+ // If we require caching, we demand it's loaded here.
+ //
+ // In practice this probably means repro capture is enabled. So we want to
+ // load the blob such that it's in the cache, even if it doesn't actually
+ // have to be loaded for the compilation.
+ if (getLinkage()->m_requireCacheFileSystem)
+ {
+ ComPtr<ISlangBlob> blob;
+ // If we can load the blob, then it exists
+ existsRes = sourceArtifact->loadBlob(ArtifactKeep::Yes, blob.writeRef());
+ }
+ else
+ {
+ existsRes = sourceArtifact->exists() ? SLANG_OK : SLANG_E_NOT_FOUND;
+ }
+
+ if (SLANG_FAILED(existsRes))
{
// Emit a diagnostic!
getSink()->diagnose(
@@ -2650,10 +2757,7 @@ void FrontEndCompileRequest::addTranslationUnitSourceFile(
return;
}
- // Was loaded from the specified path
- SourceFile* sourceFile = getSourceManager()->createSourceFileWithBlob(pathInfo, sourceBlob);
-
- addTranslationUnitSourceFile(translationUnitIndex, sourceFile);
+ translationUnit->addSourceArtifact(sourceArtifact);
}
int FrontEndCompileRequest::addEntryPoint(
@@ -2808,10 +2912,29 @@ RefPtr<Module> Linkage::loadModule(
name,
srcLoc);
+ // Create an artifact for the source
+ auto sourceArtifact = ArtifactUtil::createArtifact(ArtifactDesc::make(ArtifactKind::Source, ArtifactPayload::Slang, ArtifactStyle::Unknown));
+
// Create with the 'friendly' name
- SourceFile* sourceFile = getSourceManager()->createSourceFileWithBlob(filePathInfo, sourceBlob);
-
- translationUnit->addSourceFile(sourceFile);
+ if (filePathInfo.type == PathInfo::Type::Normal ||
+ filePathInfo.type == PathInfo::Type::FoundPath)
+ {
+ // We create that it was loaded from the file system
+ sourceArtifact->addRepresentation(new ExtFileArtifactRepresentation(filePathInfo.foundPath.getUnownedSlice(), getFileSystemExt()));
+ }
+ else
+ {
+ // Else we say we don't know and just add the blob
+ sourceArtifact->addRepresentationUnknown(sourceBlob);
+ }
+
+ translationUnit->addSourceArtifact(sourceArtifact);
+
+ if (SLANG_FAILED(translationUnit->requireSourceFiles()))
+ {
+ // Some problem accessing source files
+ return nullptr;
+ }
int errorCountBefore = sink->getErrorCount();
frontEndReq->parseTranslationUnit(translationUnit);
@@ -4234,7 +4357,7 @@ RefPtr<Module> findOrImportModule(
void Session::addBuiltinSource(
Scope* scope,
String const& path,
- String const& source)
+ ISlangBlob* sourceBlob)
{
SourceManager* sourceManager = getBuiltinSourceManager();
@@ -4254,10 +4377,10 @@ void Session::addBuiltinSource(
Name* moduleName = getNamePool()->getName(path);
auto translationUnitIndex = compileRequest->addTranslationUnit(SourceLanguage::Slang, moduleName);
- compileRequest->addTranslationUnitSourceString(
+ compileRequest->addTranslationUnitSourceBlob(
translationUnitIndex,
path,
- source);
+ sourceBlob);
SlangResult res = compileRequest->executeActionsInner();
if (SLANG_FAILED(res))
@@ -4637,7 +4760,11 @@ void EndToEndCompileRequest::addTranslationUnitSourceStringSpan(int translationU
if (!path) path = "";
- frontEndReq->addTranslationUnitSourceString(translationUnitIndex, path, UnownedStringSlice(sourceBegin, sourceEnd));
+ const auto slice = UnownedStringSlice(sourceBegin, sourceEnd);
+
+ auto blob = RawBlob::create(slice.begin(), slice.getLength());
+
+ frontEndReq->addTranslationUnitSourceBlob(translationUnitIndex, path, blob);
}
void EndToEndCompileRequest::addTranslationUnitSourceBlob(int translationUnitIndex, char const* path, ISlangBlob* sourceBlob)