summaryrefslogtreecommitdiffstats
path: root/source/compiler-core
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2022-08-16 03:39:41 -0400
committerGitHub <noreply@github.com>2022-08-16 00:39:41 -0700
commitac71724c03392b429e44641a3641b2bcf7cc55fc (patch)
tree8f7ffa61329dd24bc9be551e293840b6b94aab36 /source/compiler-core
parent786f48d32340c36a06865a333ff9066033b5b2bc (diff)
Remove CompileResult to use IArtifact (#2357)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP with hierarchical enums. * Some small fixes and improvements around artifact desc related types. * Improvements around hierarchical enum. * Fixes to get Artifact types refactor to be able to execute tests. * Attempt to better categorize PTX. * Work around for potentially unused function warning. * Typo fix. * Simplify Artifact header. * Small improvements around Artifact kind/payload/style. * Added IDestroyable/ICastable * Add IArtifactList. * First impl of IArtifactUtil. * Use the ICastable interface for IArtifactRepresentation. * Added IArtifactRepresentation & IArtifactAssociated. * Add SLANG_OVERRIDE to avoid gcc/clang warning. * Fix calling convention issue on win32. * Fix missing SLANG_OVERRIDE. * First attempt at file abstraction around Artifact. * Added creation of lock file. * Move functionality for determining file paths to the IArtifactUtil. Add casting to ICastable. * Added some casting/finding mechanisms. * Simplify IArtifact interface, and use Items for file reps. * Fix problem with libraries on DXIL. * Split out ArtifactRepresentation. * Move ArtifactDesc functionality to ArtifactDescUtil. ArtifactInfoUtil becomes ArtifactDescUtil. * Split implementations from the interfaces for Artifact. * Use TypeTextUtil for target name outputting. * Add artifact impls. * Add ICastableList * Added UnknownCastableAdapter * Make ISlangSharedLibrary derive from ICastable, and remain backwards compatible with slang-llvm. * Refactor Representation on Artifact. * Make our ISlangBlobs also derive from ICastable. Make ISlangBlob atomic ref counted. * Split out CastableList and related types, and placed in core. * Small fixes around IArtifact. Improve IArtifact docs. First impl of getChildren for IArtifact. * Documentation improvements for Artifact related types. * Fix typo. * Special case adding a ICastableList to a LazyCastableList. * Small simplification of LazyCastableList, by adding State member. * Removed the ILockFile interface because IFileArtifactRepresentation can be used. * Implement DiagnosticsArtifactRepresentation. * Added PostEmitMetadataArtifactRepresentation * Add searching by predicate. Added handling of accessing Artifact as ISharedLibrary * Fix typo. * Add find to IArtifacgtList. Fix some missing SLANG_NO_THROW. * Small improvements around ArtifactDesc types. * Another small change around ArtifactKind. * Some more shuffling of ArtifactDesc. * Make IArtifact castable Remove IArtifactList Made IArtifactContainer derive from IArtifact Made ModuleLibrary atomic ref counted/given IModuleLibrary interface. * Must call _requireChildren before any children access. * Fix missing SLANG_MCALL on castAs. * Fix missing SLANG_OVERRIDE. * Added IArtifactHandler * Use ICastable for basis of scope/lookup. * WIP first attempt to remove CompileResult. * Fix support for for downstream compiler shared library adapter. * Fix issues found when replacing CompileResult. * Fix typo. * Fix getting items form 'significant' member of an Artifact. * Split out ArtifactUtil & ArtifactHandler. * Work around for problem on Visual studio. * Improve searching. * Add missing files.
Diffstat (limited to 'source/compiler-core')
-rw-r--r--source/compiler-core/slang-artifact-desc-util.cpp33
-rw-r--r--source/compiler-core/slang-artifact-desc-util.h22
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.cpp380
-rw-r--r--source/compiler-core/slang-artifact-handler-impl.h45
-rw-r--r--source/compiler-core/slang-artifact-helper.cpp124
-rw-r--r--source/compiler-core/slang-artifact-helper.h84
-rw-r--r--source/compiler-core/slang-artifact-impl.cpp125
-rw-r--r--source/compiler-core/slang-artifact-impl.h26
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.cpp52
-rw-r--r--source/compiler-core/slang-artifact-representation-impl.h43
-rw-r--r--source/compiler-core/slang-artifact-util.cpp396
-rw-r--r--source/compiler-core/slang-artifact-util.h107
-rw-r--r--source/compiler-core/slang-artifact.h35
-rw-r--r--source/compiler-core/slang-downstream-compiler.h3
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp4
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp3
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.cpp4
17 files changed, 948 insertions, 538 deletions
diff --git a/source/compiler-core/slang-artifact-desc-util.cpp b/source/compiler-core/slang-artifact-desc-util.cpp
index 314703c0b..2c2b177c2 100644
--- a/source/compiler-core/slang-artifact-desc-util.cpp
+++ b/source/compiler-core/slang-artifact-desc-util.cpp
@@ -122,7 +122,7 @@ struct HierarchicalEnumTable
return true;
}
type = m_parents[Index(type)];
- } while (Index(type) > Index(T::Base));
+ } while (Index(type) >= Index(T::Base));
return false;
}
@@ -620,31 +620,6 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des
return getBaseNameFromPath(desc, path);
}
-/* static */String ArtifactDescUtil::getBaseName(IArtifact* artifact)
-{
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
- {
- return getBaseName(artifact->getDesc(), fileRep);
- }
- // Else use the name
- return artifact->getName();
-}
-
-/* static */String ArtifactDescUtil::getParentPath(IFileArtifactRepresentation* fileRep)
-{
- UnownedStringSlice path(fileRep->getPath());
- return Path::getParentDirectory(path);
-}
-
-/* static */String ArtifactDescUtil::getParentPath(IArtifact* artifact)
-{
- if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
- {
- return getParentPath(fileRep);
- }
- return String();
-}
-
/* static */SlangResult ArtifactDescUtil::calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath)
{
outPath.Clear();
@@ -690,10 +665,4 @@ UnownedStringSlice ArtifactDescUtil::getDefaultExtension(const ArtifactDesc& des
return SLANG_OK;
}
-/* static */ComPtr<IArtifactContainer> ArtifactDescUtil::createContainer(const ArtifactDesc& desc)
-{
- const auto containerDesc = ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults, desc.style);
- return ArtifactContainer::create(containerDesc);
-}
-
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-desc-util.h b/source/compiler-core/slang-artifact-desc-util.h
index 604d5a4ce..e3d1e6478 100644
--- a/source/compiler-core/slang-artifact-desc-util.h
+++ b/source/compiler-core/slang-artifact-desc-util.h
@@ -75,23 +75,29 @@ struct ArtifactDescUtil
/// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
/// Else if there is an explicit name set, this is returned.
/// Else returns the empty string
- static String getBaseName(IArtifact* artifact);
+
static String getBaseName(const ArtifactDesc& desc, IFileArtifactRepresentation* fileRep);
- /// Get the parent path (empty if there isn't one)
- static String getParentPath(IArtifact* artifact);
- static String getParentPath(IFileArtifactRepresentation* fileRep);
-
/// Given a desc, and a basePath returns a suitable path for a entity of specified desc
static SlangResult calcPathForDesc(const ArtifactDesc& desc, const UnownedStringSlice& basePath, StringBuilder& outPath);
- /// Make ArtifactDesc from target
+ /// Given a target returns the ArtifactDesc
static ArtifactDesc makeDescFromCompileTarget(SlangCompileTarget target);
- /// Create an empty container which is compatible with the desc
- static ComPtr<IArtifactContainer> createContainer(const ArtifactDesc& desc);
+ /// Make ArtifactDesc from target
+ static bool isDescDerivedFrom(const ArtifactDesc& desc, const ArtifactDesc& from);
};
+// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+inline /* static */bool ArtifactDescUtil::isDescDerivedFrom(const ArtifactDesc& desc, const ArtifactDesc& from)
+{
+ // TODO(JS): Currently this ignores flags in desc. That may or may not be right
+ // long term.
+ return isDerivedFrom(desc.kind, from.kind) &&
+ isDerivedFrom(desc.payload, from.payload) &&
+ isDerivedFrom(desc.style, from.style);
+}
+
} // namespace Slang
#endif
diff --git a/source/compiler-core/slang-artifact-handler-impl.cpp b/source/compiler-core/slang-artifact-handler-impl.cpp
new file mode 100644
index 000000000..c93a4907b
--- /dev/null
+++ b/source/compiler-core/slang-artifact-handler-impl.cpp
@@ -0,0 +1,380 @@
+// slang-artifact-handler-impl.cpp
+#include "slang-artifact-handler-impl.h"
+
+#include "slang-artifact-impl.h"
+#include "slang-artifact-representation-impl.h"
+
+#include "slang-artifact-desc-util.h"
+
+#include "slang-artifact-helper.h"
+
+#include "../core/slang-castable-list-impl.h"
+
+#include "../core/slang-file-system.h"
+#include "../core/slang-io.h"
+#include "../core/slang-shared-library.h"
+
+// For workaround for DownstreamResult
+#include "slang-downstream-compiler.h"
+
+namespace Slang {
+
+// A temporary class that adapts `ISlangSharedLibrary_Dep1` to ISlangSharedLibrary
+
+class SharedLibraryDep1Adapter : public ComBaseObject, public ISlangSharedLibrary
+{
+public:
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const SlangUUID& guid) SLANG_OVERRIDE;
+
+ // ISlangSharedLibrary
+ virtual SLANG_NO_THROW void* SLANG_MCALL findSymbolAddressByName(char const* name) SLANG_OVERRIDE { return m_contained->findSymbolAddressByName(name); }
+
+ SharedLibraryDep1Adapter(ISlangSharedLibrary_Dep1* dep1) :
+ m_contained(dep1)
+ {
+ }
+
+protected:
+ void* getInterface(const Guid& guid)
+ {
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == ISlangSharedLibrary::getTypeGuid())
+ {
+ return static_cast<ISlangSharedLibrary*>(this);
+ }
+ return nullptr;
+ }
+ void* getObject(const Guid& guid)
+ {
+ SLANG_UNUSED(guid);
+ return nullptr;
+ }
+
+ ComPtr<ISlangSharedLibrary_Dep1> m_contained;
+};
+
+void* SharedLibraryDep1Adapter::castAs(const SlangUUID& guid)
+{
+ if (auto intf = getInterface(guid))
+ {
+ return intf;
+ }
+ return getObject(guid);
+}
+
+/* Hack to take into account downstream compilers shared library interface might need an adapter */
+static SlangResult _getDownstreamSharedLibrary(DownstreamCompileResult* downstreamResult, ComPtr<ISlangSharedLibrary>& outSharedLibrary)
+{
+ ComPtr<ISlangSharedLibrary> lib;
+ SLANG_RETURN_ON_FAIL(downstreamResult->getHostCallableSharedLibrary(lib));
+
+ if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary::getTypeGuid(), (void**)outSharedLibrary.writeRef())))
+ {
+ return SLANG_OK;
+ }
+
+ ComPtr<ISlangSharedLibrary_Dep1> libDep1;
+ if (SLANG_SUCCEEDED(lib->queryInterface(ISlangSharedLibrary_Dep1::getTypeGuid(), (void**)libDep1.writeRef())))
+ {
+ // Okay, we need to adapt for now
+ outSharedLibrary = new SharedLibraryDep1Adapter(libDep1);
+ return SLANG_OK;
+ }
+ return SLANG_E_NOT_FOUND;
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */DefaultArtifactHandler DefaultArtifactHandler::g_singleton;
+
+SlangResult DefaultArtifactHandler::queryInterface(SlangUUID const& uuid, void** outObject)
+{
+ if (auto ptr = getInterface(uuid))
+ {
+ addRef();
+ *outObject = static_cast<IArtifactHandler*>(this);
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+}
+
+void* DefaultArtifactHandler::castAs(const Guid& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* DefaultArtifactHandler::getInterface(const Guid& uuid)
+{
+ if (uuid == ISlangUnknown::getTypeGuid() ||
+ uuid == ICastable::getTypeGuid() ||
+ uuid == IArtifactHandler::getTypeGuid())
+ {
+ return static_cast<IArtifactHandler*>(this);
+ }
+
+ return nullptr;
+}
+
+void* DefaultArtifactHandler::getObject(const Guid& uuid)
+{
+ SLANG_UNUSED(uuid);
+ return nullptr;
+}
+
+SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable)
+{
+ SLANG_ASSERT(rep);
+
+ // See if it implements ICastable
+ {
+ ComPtr<ICastable> castable;
+ if (SLANG_SUCCEEDED(rep->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
+ {
+ return _addRepresentation(artifact, keep, castable, outCastable);
+ }
+ }
+
+ // We have to wrap
+ ComPtr<IUnknownCastableAdapter> adapter(new UnknownCastableAdapter(rep));
+ return _addRepresentation(artifact, keep, adapter, outCastable);
+}
+
+SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable)
+{
+ SLANG_ASSERT(castable);
+
+ if (canKeep(keep))
+ {
+ artifact->addRepresentation(castable);
+ }
+
+ castable->addRef();
+ *outCastable = castable;
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHandler::expandChildren(IArtifactContainer* container)
+{
+ SlangResult res = container->getExpandChildrenResult();
+ if (res != SLANG_E_UNINITIALIZED)
+ {
+ // It's already expanded
+ return res;
+ }
+
+ // For the generic container type, we just expand as empty
+ const auto desc = container->getDesc();
+ if (desc.kind == ArtifactKind::Container)
+ {
+ container->setChildren(nullptr, 0);
+ return SLANG_OK;
+ }
+ // TODO(JS):
+ // Proper implementation should (for example) be able to expand a Zip file etc.
+ return SLANG_E_NOT_IMPLEMENTED;
+}
+
+
+
+SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable)
+{
+ // See if we already have a rep of this type
+ {
+ for (ICastable* rep : artifact->getRepresentations())
+ {
+ if (rep->castAs(guid))
+ {
+ rep->addRef();
+ *outCastable = rep;
+ return SLANG_OK;
+ }
+ }
+ }
+
+ // TODO(JS): Temporary whilst DownstreamCompileResult is
+ // Special handling for DownstreamCompileResult
+ if (auto downstreamResult = findRepresentation<DownstreamCompileResult>(artifact))
+ {
+ if (guid == ISlangBlob::getTypeGuid())
+ {
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(downstreamResult->getBinary(blob));
+ return _addRepresentation(artifact, keep, blob, outCastable);
+ }
+ else if (guid == ISlangSharedLibrary::getTypeGuid())
+ {
+ ComPtr<ISlangSharedLibrary> lib;
+ SLANG_RETURN_ON_FAIL(_getDownstreamSharedLibrary(downstreamResult, lib));
+ return _addRepresentation(artifact, keep, lib, outCastable);
+ }
+ }
+
+ // Normal construction
+ if (guid == ISlangBlob::getTypeGuid())
+ {
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(_loadBlob(artifact, keep, blob.writeRef()));
+ return _addRepresentation(artifact, keep, blob, outCastable);
+ }
+ else if (guid == ISlangSharedLibrary::getTypeGuid())
+ {
+ ComPtr<ISlangSharedLibrary> sharedLib;
+ SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, keep, sharedLib.writeRef()));
+ return _addRepresentation(artifact, keep, sharedLib, outCastable);
+ }
+
+ return SLANG_E_NOT_AVAILABLE;
+}
+
+static bool _isFileSystemFile(ICastable* castable, void* data)
+{
+ if (auto fileRep = as<IFileArtifactRepresentation>(castable))
+ {
+ ISlangMutableFileSystem* fileSystem = (ISlangMutableFileSystem*)data;
+ if (fileRep->getFileSystem() == fileSystem)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep)
+{
+ // See if we already have it
+ if (auto fileRep = as<IFileArtifactRepresentation>(artifact->findRepresentationWithPredicate(&_isFileSystemFile, fileSystem)))
+ {
+ fileRep->addRef();
+ *outFileRep = fileRep;
+ return SLANG_OK;
+ }
+
+ auto helper = DefaultArtifactHelper::getSingleton();
+
+ // If we are going to access as a file we need to be able to write it, and to do that we need a blob
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(artifact->loadBlob(getIntermediateKeep(keep), blob.writeRef()));
+
+ // Okay we need to store as a temporary. Get a lock file.
+ ComPtr<IFileArtifactRepresentation> lockFile;
+ SLANG_RETURN_ON_FAIL(helper->createLockFile(artifact->getName(), fileSystem, lockFile.writeRef()));
+
+ // Now we need the appropriate name for this item
+ ComPtr<ISlangBlob> pathBlob;
+ SLANG_RETURN_ON_FAIL(helper->calcArtifactPath(artifact->getDesc(), lockFile->getPath(), pathBlob.writeRef()));
+
+ const auto path = StringUtil::getString(pathBlob);
+
+ // Write the contents
+ SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize()));
+
+ ComPtr<IFileArtifactRepresentation> fileRep;
+
+ // TODO(JS): This path comparison is perhaps not perfect, in that it assumes the path is not changed
+ // in any way. For example an impl of calcArtifactPath that changed slashes or used a canonical path
+ // might mean the lock file and the rep have the same path.
+ // As it stands calcArtifactPath impl doesn't do that, but that is perhaps somewhatfragile
+
+ // If the paths are identical, we can just use the lock file for the rep
+ if (UnownedStringSlice(lockFile->getPath()) == path.getUnownedSlice())
+ {
+ fileRep.swap(lockFile);
+ }
+ else
+ {
+ // Create a new rep that references the lock file
+ fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, lockFile->getFileSystem());
+ }
+
+ // Create the rep
+ if (canKeep(keep))
+ {
+ artifact->addRepresentation(fileRep);
+ }
+
+ // Return the file
+ *outFileRep = fileRep.detach();
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary)
+{
+ // If it is 'shared library' for a CPU like thing, we can try and load it
+ const auto desc = artifact->getDesc();
+ if ((isDerivedFrom(desc.kind, ArtifactKind::HostCallable) ||
+ isDerivedFrom(desc.kind, ArtifactKind::SharedLibrary)) &&
+ isDerivedFrom(desc.payload, ArtifactPayload::CPULike))
+ {
+ // Get as a file represenation on the OS file system
+ ComPtr<IFileArtifactRepresentation> fileRep;
+ SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::No, nullptr, fileRep.writeRef()));
+
+ // We requested on the OS file system, just check that's what we got...
+ SLANG_ASSERT(fileRep->getFileSystem() == nullptr);
+
+ // Try loading the shared library
+ SharedLibrary::Handle handle;
+ if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(fileRep->getPath(), handle)))
+ {
+ return SLANG_FAIL;
+ }
+
+ // The ScopeSharedLibrary will keep the fileRep in scope as long as is needed
+ auto sharedLibrary = new ScopeSharedLibrary(handle, fileRep);
+
+ if (canKeep(keep))
+ {
+ // We want to keep the fileRep, as that is necessary for the sharedLibrary to even work
+ artifact->addRepresentation(fileRep);
+ // Keep the shared library
+ artifact->addRepresentation(sharedLibrary);
+ }
+
+ // Output
+ sharedLibrary->addRef();
+ *outSharedLibrary = sharedLibrary;
+
+ return SLANG_OK;
+ }
+
+ return SLANG_FAIL;
+}
+
+SlangResult DefaultArtifactHandler::_loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob)
+{
+ SLANG_UNUSED(keep);
+
+ ComPtr<ISlangBlob> blob;
+
+ // Look for a representation that we can serialize into a blob
+ for (auto rep : artifact->getRepresentations())
+ {
+ if (auto artifactRep = as<IArtifactRepresentation>(rep))
+ {
+ SlangResult res = artifactRep->writeToBlob(blob.writeRef());
+ if (SLANG_SUCCEEDED(res) && blob)
+ {
+ break;
+ }
+ }
+ }
+
+ // Wasn't able to construct
+ if (!blob)
+ {
+ return SLANG_E_NOT_FOUND;
+ }
+
+ *outBlob = blob.detach();
+ return SLANG_OK;
+}
+
+} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-handler-impl.h b/source/compiler-core/slang-artifact-handler-impl.h
new file mode 100644
index 000000000..c7861b598
--- /dev/null
+++ b/source/compiler-core/slang-artifact-handler-impl.h
@@ -0,0 +1,45 @@
+// slang-artifact-handler-impl.h
+#ifndef SLANG_ARTIFACT_HANDLER_IMPL_H
+#define SLANG_ARTIFACT_HANDLER_IMPL_H
+
+#include "slang-artifact.h"
+#include "slang-artifact-representation.h"
+
+#include "../core/slang-com-object.h"
+
+namespace Slang
+{
+
+class DefaultArtifactHandler : public ComBaseObject, public IArtifactHandler
+{
+public:
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactHandler
+ SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren(IArtifactContainer* container) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
+
+ static IArtifactHandler* getSingleton() { return &g_singleton; }
+protected:
+
+ SlangResult _loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary);
+ SlangResult _loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob);
+
+ void* getInterface(const Guid& uuid);
+ void* getObject(const Guid& uuid);
+
+ SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable);
+ SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable);
+
+ static DefaultArtifactHandler g_singleton;
+};
+
+} // namespace Slang
+
+#endif
diff --git a/source/compiler-core/slang-artifact-helper.cpp b/source/compiler-core/slang-artifact-helper.cpp
new file mode 100644
index 000000000..ce6fab7d9
--- /dev/null
+++ b/source/compiler-core/slang-artifact-helper.cpp
@@ -0,0 +1,124 @@
+// slang-artifact-helper.cpp
+#include "slang-artifact-helper.h"
+
+#include "slang-artifact-impl.h"
+#include "slang-artifact-representation-impl.h"
+
+#include "slang-artifact-desc-util.h"
+
+#include "../core/slang-castable-list-impl.h"
+
+#include "../core/slang-file-system.h"
+#include "../core/slang-io.h"
+#include "../core/slang-shared-library.h"
+
+namespace Slang {
+
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHelper !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+/* static */DefaultArtifactHelper DefaultArtifactHelper::g_singleton;
+
+SlangResult DefaultArtifactHelper::queryInterface(SlangUUID const& uuid, void** outObject)
+{
+ if (auto intf = getInterface(uuid))
+ {
+ *outObject = intf;
+ return SLANG_OK;
+ }
+ return SLANG_E_NO_INTERFACE;
+}
+
+void* DefaultArtifactHelper::castAs(const Guid& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* DefaultArtifactHelper::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == IArtifactHelper::getTypeGuid())
+ {
+ return static_cast<IArtifactHelper*>(this);
+ }
+ return nullptr;
+}
+
+void* DefaultArtifactHelper::getObject(const Guid& guid)
+{
+ SLANG_UNUSED(guid);
+ return nullptr;
+}
+
+SlangResult DefaultArtifactHelper::createArtifact(const ArtifactDesc& desc, const char* inName, IArtifact** outArtifact)
+{
+ *outArtifact = inName ?
+ Artifact::create(desc, inName).detach() :
+ Artifact::create(desc).detach();
+
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHelper::createArtifactContainer(const ArtifactDesc& desc, const char* inName, IArtifactContainer** outArtifactContainer)
+{
+ *outArtifactContainer = inName ?
+ ArtifactContainer::create(desc, inName).detach() :
+ ArtifactContainer::create(desc).detach();
+
+ return SLANG_OK;
+}
+
+ArtifactKind DefaultArtifactHelper::getKindParent(ArtifactKind kind) { return getParent(kind); }
+UnownedStringSlice DefaultArtifactHelper::getKindName(ArtifactKind kind) { return getName(kind); }
+bool DefaultArtifactHelper::isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) { return isDerivedFrom(kind, base); }
+
+ArtifactPayload DefaultArtifactHelper::getPayloadParent(ArtifactPayload payload) { return getParent(payload); }
+UnownedStringSlice DefaultArtifactHelper::getPayloadName(ArtifactPayload payload) { return getName(payload); }
+bool DefaultArtifactHelper::isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) { return isDerivedFrom(payload, base); }
+
+ArtifactStyle DefaultArtifactHelper::getStyleParent(ArtifactStyle style) { return getParent(style); }
+UnownedStringSlice DefaultArtifactHelper::getStyleName(ArtifactStyle style) { return getName(style); }
+bool DefaultArtifactHelper::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
+
+SlangResult DefaultArtifactHelper::createLockFile(const char* inNameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile)
+{
+ if (fileSystem)
+ {
+ if (fileSystem != OSFileSystem::getMutableSingleton())
+ {
+ // We can only create lock files, on the global OS file system
+ return SLANG_E_NOT_AVAILABLE;
+ }
+ fileSystem = nullptr;
+ }
+
+ const UnownedStringSlice nameBase = (inNameBase && inNameBase[0] != 0) ? UnownedStringSlice(inNameBase) : UnownedStringSlice("unknown");
+
+ String lockPath;
+ SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath));
+
+ ComPtr<IFileArtifactRepresentation> lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath, nullptr, fileSystem));
+
+ *outLockFile = lockFile.detach();
+ return SLANG_OK;
+}
+
+SlangResult DefaultArtifactHelper::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath)
+{
+ UnownedStringSlice basePath(inBasePath);
+ StringBuilder path;
+ SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, basePath, path));
+ *outPath = StringBlob::create(path).detach();
+ return SLANG_OK;
+}
+
+ArtifactDesc DefaultArtifactHelper::makeDescFromCompileTarget(SlangCompileTarget target)
+{
+ return ArtifactDescUtil::makeDescFromCompileTarget(target);
+}
+
+} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-helper.h b/source/compiler-core/slang-artifact-helper.h
new file mode 100644
index 000000000..41bf0f2c9
--- /dev/null
+++ b/source/compiler-core/slang-artifact-helper.h
@@ -0,0 +1,84 @@
+// slang-artifact-helper.h
+#ifndef SLANG_ARTIFACT_HELPER_H
+#define SLANG_ARTIFACT_HELPER_H
+
+#include "slang-artifact.h"
+#include "slang-artifact-representation.h"
+
+#include "../core/slang-com-object.h"
+
+namespace Slang
+{
+
+class IArtifactHelper : public ICastable
+{
+ SLANG_COM_INTERFACE(0x882b25d7, 0xe300, 0x4b20, { 0xbe, 0xb, 0x26, 0xd2, 0x52, 0x3e, 0x70, 0x20 })
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) = 0;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) = 0;
+
+ virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) = 0;
+
+ virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) = 0;
+
+ virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) = 0;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) = 0;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) = 0;
+
+ /// Given a desc and a basePath returns a suitable name
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0;
+
+ virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) = 0;
+};
+
+class DefaultArtifactHelper : public IArtifactHelper
+{
+public:
+ // ISlangUnknown
+ SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
+ SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+
+ // IArtifactInterface
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) SLANG_OVERRIDE;
+
+ virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) SLANG_OVERRIDE;
+
+ static IArtifactHelper* getSingleton() { return &g_singleton; }
+
+protected:
+ void* getInterface(const Guid& guid);
+ void* getObject(const Guid& guid);
+
+ static DefaultArtifactHelper g_singleton;
+};
+
+} // namespace Slang
+
+#endif
diff --git a/source/compiler-core/slang-artifact-impl.cpp b/source/compiler-core/slang-artifact-impl.cpp
index 061aa9ee7..ed952e72c 100644
--- a/source/compiler-core/slang-artifact-impl.cpp
+++ b/source/compiler-core/slang-artifact-impl.cpp
@@ -6,10 +6,21 @@
#include "slang-artifact-util.h"
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-handler-impl.h"
+
#include "../core/slang-castable-list-impl.h"
namespace Slang {
+static bool _checkSelf(IArtifact::FindStyle findStyle)
+{
+ return Index(findStyle) <= Index(IArtifact::FindStyle::SelfOrChildren);
+}
+
+static bool _checkChildren(IArtifact::FindStyle findStyle)
+{
+ return Index(findStyle) >= Index(IArtifact::FindStyle::SelfOrChildren);
+}
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Artifact !!!!!!!!!!!!!!!!!!!!!!!!!!! */
@@ -187,6 +198,26 @@ ICastableList* Artifact::getRepresentationList()
return m_representations.requireList();
}
+IArtifact* Artifact::findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& from)
+{
+ return (_checkSelf(findStyle) && ArtifactDescUtil::isDescDerivedFrom(m_desc, from)) ? this : nullptr;
+}
+
+IArtifact* Artifact::findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data)
+{
+ return (_checkSelf(findStyle) && func(this, data)) ? this : nullptr;
+}
+
+IArtifact* Artifact::findArtifactByName(FindStyle findStyle, const char* name)
+{
+ return (_checkSelf(findStyle) && m_name == name) ? this : nullptr;
+}
+
+IArtifact* Artifact::findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc)
+{
+ return (_checkSelf(findStyle) && m_desc == desc) ? this : nullptr;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactContainer !!!!!!!!!!!!!!!!!!!!!!!!!!! */
void* ArtifactContainer::getInterface(const Guid& guid)
@@ -267,67 +298,79 @@ void ArtifactContainer::clearChildren()
m_children.clearAndDeallocate();
}
-IArtifact* ArtifactContainer::findChildByDesc(const ArtifactDesc& desc)
+static bool _isDerivedDesc(IArtifact* artifact, void* data)
{
- _requireChildren();
-
- for (IArtifact* artifact : m_children)
- {
- if (artifact->getDesc() == desc)
- {
- return artifact;
- }
- }
- return nullptr;
+ const ArtifactDesc& from = *(const ArtifactDesc*)data;
+ return ArtifactDescUtil::isDescDerivedFrom(artifact->getDesc(), from);
}
-IArtifact* ArtifactContainer::findChildByDerivedDesc(const ArtifactDesc& desc)
+static bool _isDesc(IArtifact* artifact, void* data)
{
- _requireChildren();
+ const ArtifactDesc& desc = *(const ArtifactDesc*)data;
+ return desc == artifact->getDesc();
+}
- for (IArtifact* artifact : m_children)
+static bool _isName(IArtifact* artifact, void* data)
+{
+ const char* name = (const char*)data;
+ const char* artifactName = artifact->getName();
+ if (artifactName == nullptr)
{
- const ArtifactDesc artifactDesc = artifact->getDesc();
- // TODO(JS): Currently this ignores flags in desc. That may or may not be right
- // long term.
- if (isDerivedFrom(artifactDesc.kind, desc.kind) &&
- isDerivedFrom(artifactDesc.payload, desc.payload) &&
- isDerivedFrom(artifactDesc.style, desc.style))
- {
- return artifact;
- }
+ return false;
}
- return nullptr;
+ return ::strcmp(name, artifactName) == 0;
}
-IArtifact* ArtifactContainer::findChildByName(const char* name)
+
+IArtifact* ArtifactContainer::findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& from)
{
- _requireChildren();
+ return findArtifactByPredicate(findStyle, _isDerivedDesc, const_cast<ArtifactDesc*>(&from));
+}
- for (IArtifact* artifact : m_children)
- {
- const char* artifactName = artifact->getName();
+IArtifact* ArtifactContainer::findArtifactByName(FindStyle findStyle, const char* name)
+{
+ return findArtifactByPredicate(findStyle, _isName, const_cast<char*>(name));
+}
- if (artifactName == name ||
- ::strcmp(artifactName, name) == 0)
- {
- return artifact;
- }
- }
- return nullptr;
+IArtifact* ArtifactContainer::findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc)
+{
+ return findArtifactByPredicate(findStyle, _isDesc, const_cast<ArtifactDesc*>(&desc));
}
-IArtifact* ArtifactContainer::findChildByPredicate(FindFunc func, void* data)
+IArtifact* ArtifactContainer::findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data)
{
- _requireChildren();
+ if (_checkSelf(findStyle) && func(this, data))
+ {
+ return this;
+ }
- for (IArtifact* artifact : m_children)
+ if (_checkChildren(findStyle))
{
- if (func(artifact, data))
+ auto children = getChildren();
+
+ // First search the children
+ for (auto child : children)
{
- return artifact;
+ if (func(child, data))
+ {
+ return child;
+ }
+ }
+
+ // Then the childrens recursively
+ if (findStyle == FindStyle::Recursive ||
+ findStyle == FindStyle::ChildrenRecursive)
+ {
+ for (auto child : children)
+ {
+ if (auto found = child->findArtifactByPredicate(FindStyle::ChildrenRecursive, func, data))
+ {
+ return found;
+ }
+ }
}
}
+
return nullptr;
}
diff --git a/source/compiler-core/slang-artifact-impl.h b/source/compiler-core/slang-artifact-impl.h
index 8b15d0664..e0a976929 100644
--- a/source/compiler-core/slang-artifact-impl.h
+++ b/source/compiler-core/slang-artifact-impl.h
@@ -61,18 +61,20 @@ public:
virtual SLANG_NO_THROW ICastable* SLANG_MCALL findRepresentationWithPredicate(ICastableList::FindFunc findFunc, void* data) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(const Guid& typeGuid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE { return Slice<IArtifact*>(nullptr, 0); }
+
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByName(FindStyle findStyle, const char* name) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+
// IArtifactCollection (Not implemented)
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getExpandChildrenResult() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL setChildren(IArtifact** children, Count count) SLANG_OVERRIDE { SLANG_UNUSED(children); SLANG_UNUSED(count); SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL addChild(IArtifact* artifact) SLANG_OVERRIDE { SLANG_UNUSED(artifact); SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL removeChildAt(Index index) SLANG_OVERRIDE { SLANG_UNUSED(index); SLANG_UNREACHABLE("Not implemented"); }
virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() SLANG_OVERRIDE { SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDesc(const ArtifactDesc& desc) SLANG_OVERRIDE { SLANG_UNUSED(desc); SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDerivedDesc(const ArtifactDesc& desc) SLANG_OVERRIDE { SLANG_UNUSED(desc); SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByName(const char* name) SLANG_OVERRIDE { SLANG_UNUSED(name); SLANG_UNREACHABLE("Not implemented"); }
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByPredicate(FindFunc func, void* data) SLANG_OVERRIDE { SLANG_UNUSED(func); SLANG_UNUSED(data); SLANG_UNREACHABLE("Not implemented"); }
static ComPtr<IArtifact> create(const Desc& desc) { return ComPtr<IArtifact>(new Artifact(desc)); }
static ComPtr<IArtifact> create(const Desc& desc, const String& name) { return ComPtr<IArtifact>(new Artifact(desc, name)); }
@@ -115,19 +117,21 @@ public:
/// ICastable
virtual SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+ /// IArtifact
+ virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByName(FindStyle findStyle, const char* name) SLANG_OVERRIDE;
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) SLANG_OVERRIDE;
+
// IArtifactCollection
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getExpandChildrenResult() SLANG_OVERRIDE { return m_expandResult; }
virtual SLANG_NO_THROW void SLANG_MCALL setChildren(IArtifact** children, Count count) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL addChild(IArtifact* artifact) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL removeChildAt(Index index) SLANG_OVERRIDE;
virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDesc(const ArtifactDesc& desc) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDerivedDesc(const ArtifactDesc& desc) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByName(const char* name) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByPredicate(FindFunc func, void* data) SLANG_OVERRIDE;
-
+
static ComPtr<IArtifactContainer> create(const Desc& desc) { return ComPtr<IArtifactContainer>(new ArtifactContainer(desc)); }
static ComPtr<IArtifactContainer> create(const Desc& desc, const String& name) { return ComPtr<IArtifactContainer>(new ArtifactContainer(desc, name)); }
diff --git a/source/compiler-core/slang-artifact-representation-impl.cpp b/source/compiler-core/slang-artifact-representation-impl.cpp
index 6ae2d646f..32ec055d8 100644
--- a/source/compiler-core/slang-artifact-representation-impl.cpp
+++ b/source/compiler-core/slang-artifact-representation-impl.cpp
@@ -178,10 +178,58 @@ void* PostEmitMetadataArtifactRepresentation::getObject(const Guid& uuid)
return nullptr;
}
+void* PostEmitMetadataArtifactRepresentation::castAs(const Guid& guid)
+{
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+
Slice<ShaderBindingRange> PostEmitMetadataArtifactRepresentation::getBindingRanges()
{
- return Slice<ShaderBindingRange>(m_usedBindings.getBuffer(), m_usedBindings.getCount());
+ return Slice<ShaderBindingRange>(m_metadata.usedBindings.getBuffer(), m_metadata.usedBindings.getCount());
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PostEmitMetadataArtifactRepresentation !!!!!!!!!!!!!!!!!!!!!!!!!!! */
+
+void* ObjectArtifactRepresentation::castAs(const Guid& guid)
+{
+
+ if (auto ptr = getInterface(guid))
+ {
+ return ptr;
+ }
+ return getObject(guid);
+}
+
+void* ObjectArtifactRepresentation::getInterface(const Guid& guid)
+{
+ if (guid == ISlangUnknown::getTypeGuid() ||
+ guid == ICastable::getTypeGuid() ||
+ guid == IArtifactRepresentation::getTypeGuid())
+ {
+ return static_cast<IArtifactRepresentation*>(this);
+ }
+ return nullptr;
+}
+
+void* ObjectArtifactRepresentation::getObject(const Guid& guid)
+{
+ if (guid == getTypeGuid())
+ {
+ return this;
+ }
+
+ // If matches the guid saved in the object, we return that
+ if (m_object && m_typeGuid == guid)
+ {
+ return m_object;
+ }
+
+ return nullptr;
}
-
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-representation-impl.h b/source/compiler-core/slang-artifact-representation-impl.h
index 00d36ab49..fb2e37c76 100644
--- a/source/compiler-core/slang-artifact-representation-impl.h
+++ b/source/compiler-core/slang-artifact-representation-impl.h
@@ -10,8 +10,6 @@
#include "../core/slang-com-object.h"
#include "../core/slang-memory-arena.h"
-//#include "../core/slang-string-slice-pool.h"
-
namespace Slang
{
@@ -172,7 +170,10 @@ struct ShaderBindingRange
}
};
-typedef List<ShaderBindingRange> ShaderBindingRanges;
+struct PostEmitMetadata
+{
+ List<ShaderBindingRange> usedBindings;
+};
class PostEmitMetadataArtifactRepresentation : public ComBaseObject, public IPostEmitMetadataArtifactRepresentation
{
@@ -184,15 +185,45 @@ public:
// ICastable
SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
// IArtifactRepresentation
- SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** blob) SLANG_OVERRIDE;
- SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** outBlob) SLANG_OVERRIDE { SLANG_UNUSED(outBlob); return SLANG_E_NOT_AVAILABLE; }
+ SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; }
// IPostEmitMetadataArtifactRepresentation
SLANG_NO_THROW virtual Slice<ShaderBindingRange> SLANG_MCALL getBindingRanges() SLANG_OVERRIDE;
void* getInterface(const Guid& uuid);
void* getObject(const Guid& uuid);
- ShaderBindingRanges m_usedBindings;
+ PostEmitMetadata m_metadata;
+};
+
+/* 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!
+*/
+class ObjectArtifactRepresentation : public ComBaseObject, public IArtifactRepresentation
+{
+public:
+ SLANG_CLASS_GUID(0xb9d5af57, 0x725b, 0x45f8, { 0xac, 0xed, 0x18, 0xf4, 0xa8, 0x4b, 0xf4, 0x73 })
+
+ SLANG_COM_BASE_IUNKNOWN_ALL
+
+ // ICastable
+ SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
+ // IArtifactRepresentation
+ SLANG_NO_THROW SlangResult SLANG_MCALL writeToBlob(ISlangBlob** outBlob) SLANG_OVERRIDE { SLANG_UNUSED(outBlob); return SLANG_E_NOT_AVAILABLE; }
+ SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return m_object; }
+
+ ObjectArtifactRepresentation(const Guid& typeGuid, RefObject* obj):
+ m_typeGuid(typeGuid),
+ m_object(obj)
+ {
+ }
+
+ void* getInterface(const Guid& uuid);
+ void* getObject(const Guid& uuid);
+
+ Guid m_typeGuid; ///< Will return m_object if a cast to m_typeGuid is given
+ RefPtr<RefObject> m_object; ///< The object
};
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.cpp b/source/compiler-core/slang-artifact-util.cpp
index 366ab4111..f93924afb 100644
--- a/source/compiler-core/slang-artifact-util.cpp
+++ b/source/compiler-core/slang-artifact-util.cpp
@@ -8,370 +8,100 @@
#include "../core/slang-castable-list-impl.h"
-#include "../core/slang-file-system.h"
#include "../core/slang-io.h"
-#include "../core/slang-shared-library.h"
namespace Slang {
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! DefaultArtifactHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-/* static */DefaultArtifactHandler DefaultArtifactHandler::g_singleton;
-
-SlangResult DefaultArtifactHandler::queryInterface(SlangUUID const& uuid, void** outObject)
-{
- if (auto ptr = getInterface(uuid))
- {
- addRef();
- *outObject = static_cast<IArtifactHandler*>(this);
- return SLANG_OK;
- }
- return SLANG_E_NO_INTERFACE;
-}
-
-void* DefaultArtifactHandler::castAs(const Guid& guid)
-{
- if (auto ptr = getInterface(guid))
- {
- return ptr;
- }
- return getObject(guid);
-}
-
-void* DefaultArtifactHandler::getInterface(const Guid& uuid)
-{
- if (uuid == ISlangUnknown::getTypeGuid() ||
- uuid == ICastable::getTypeGuid() ||
- uuid == IArtifactHandler::getTypeGuid())
- {
- return static_cast<IArtifactHandler*>(this);
- }
-
- return nullptr;
-}
-
-void* DefaultArtifactHandler::getObject(const Guid& uuid)
-{
- SLANG_UNUSED(uuid);
- return nullptr;
-}
-
-SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable)
-{
- SLANG_ASSERT(rep);
-
- // See if it implements ICastable
- {
- ComPtr<ICastable> castable;
- if (SLANG_SUCCEEDED(rep->queryInterface(ICastable::getTypeGuid(), (void**)castable.writeRef())) && castable)
- {
- return _addRepresentation(artifact, keep, castable, outCastable);
- }
- }
-
- // We have to wrap
- ComPtr<IUnknownCastableAdapter> adapter(new UnknownCastableAdapter(rep));
- return _addRepresentation(artifact, keep, adapter, outCastable);
-}
-
-SlangResult DefaultArtifactHandler::_addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable)
+/* static */ComPtr<IArtifactContainer> ArtifactUtil::createContainer(const ArtifactDesc& desc)
{
- SLANG_ASSERT(castable);
-
- if (canKeep(keep))
- {
- artifact->addRepresentation(castable);
- }
-
- castable->addRef();
- *outCastable = castable;
- return SLANG_OK;
+ const auto containerDesc = ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults, desc.style);
+ return ArtifactContainer::create(containerDesc);
}
-SlangResult DefaultArtifactHandler::expandChildren(IArtifactContainer* container)
+/* static */ComPtr<IArtifactContainer> ArtifactUtil::createResultsContainer()
{
- SlangResult res = container->getExpandChildrenResult();
- if (res != SLANG_E_UNINITIALIZED)
- {
- // It's already expanded
- return res;
- }
-
- // For the generic container type, we just expand as empty
- const auto desc = container->getDesc();
- if (desc.kind == ArtifactKind::Container)
- {
- container->setChildren(nullptr, 0);
- return SLANG_OK;
- }
- // TODO(JS):
- // Proper implementation should (for example) be able to expand a Zip file etc.
- return SLANG_E_NOT_IMPLEMENTED;
+ return ArtifactContainer::create(ArtifactDesc::make(ArtifactKind::Container, ArtifactPayload::CompileResults));
}
-SlangResult DefaultArtifactHandler::getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable)
+/* static */ComPtr<IArtifact> ArtifactUtil::createArtifactForCompileTarget(SlangCompileTarget target)
{
-
- // See if we already have a rep of this type
- {
- for (ICastable* rep : artifact->getRepresentations())
- {
- if (rep->castAs(guid))
- {
- rep->addRef();
- *outCastable = rep;
- return SLANG_OK;
- }
- }
- }
+ auto desc = ArtifactDescUtil::makeDescFromCompileTarget(target);
- if (guid == ISlangBlob::getTypeGuid())
- {
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(_loadBlob(artifact, keep, blob.writeRef()));
- return _addRepresentation(artifact, keep, blob, outCastable);
- }
- else if (guid == ISlangSharedLibrary::getTypeGuid())
- {
- ComPtr<ISlangSharedLibrary> sharedLib;
- SLANG_RETURN_ON_FAIL(_loadSharedLibrary(artifact, keep, sharedLib.writeRef()));
- return _addRepresentation(artifact, keep, sharedLib, outCastable);
- }
+ if (isDerivedFrom(desc.kind, ArtifactKind::Container))
+ {
+ auto container = ArtifactContainer::create(desc);
- return SLANG_E_NOT_AVAILABLE;
+ ComPtr<IArtifact> artifact;
+ artifact.attach(container.detach());
+ return artifact;
+ }
+ else
+ {
+ return Artifact::create(desc);
+ }
}
-static bool _isFileSystemFile(ICastable* castable, void* data)
+/* static */bool ArtifactUtil::isSignificant(IArtifact* artifact, void* data)
{
- if (auto fileRep = as<IFileArtifactRepresentation>(castable))
- {
- ISlangMutableFileSystem* fileSystem = (ISlangMutableFileSystem*)data;
- if (fileRep->getFileSystem() == fileSystem)
- {
- return true;
- }
- }
- return false;
-}
-
-SlangResult DefaultArtifactHandler::getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep)
-{
- // See if we already have it
- if (auto fileRep = as<IFileArtifactRepresentation>(artifact->findRepresentationWithPredicate(&_isFileSystemFile, fileSystem)))
- {
- fileRep->addRef();
- *outFileRep = fileRep;
- return SLANG_OK;
- }
-
- auto util = ArtifactUtilImpl::getSingleton();
+ SLANG_UNUSED(data);
- // If we are going to access as a file we need to be able to write it, and to do that we need a blob
- ComPtr<ISlangBlob> blob;
- SLANG_RETURN_ON_FAIL(artifact->loadBlob(getIntermediateKeep(keep), blob.writeRef()));
+ const auto desc = artifact->getDesc();
- // Okay we need to store as a temporary. Get a lock file.
- ComPtr<IFileArtifactRepresentation> lockFile;
- SLANG_RETURN_ON_FAIL(util->createLockFile(artifact->getName(), fileSystem, lockFile.writeRef()));
+ // Containers are not significant as of themselves, they may contain something tho
+ if (isDerivedFrom(desc.kind, ArtifactKind::Container))
+ {
+ return false;
+ }
- // Now we need the appropriate name for this item
- ComPtr<ISlangBlob> pathBlob;
- SLANG_RETURN_ON_FAIL(util->calcArtifactPath(artifact->getDesc(), lockFile->getPath(), pathBlob.writeRef()));
+ // If it has no payload.. we are done
+ if (desc.payload == ArtifactPayload::None ||
+ desc.payload == ArtifactPayload::Invalid)
+ {
+ return false;
+ }
- const auto path = StringUtil::getString(pathBlob);
+ // If it's binary like or assembly/source we it's significant
+ if (isDerivedFrom(desc.kind, ArtifactKind::BinaryLike) ||
+ desc.kind == ArtifactKind::Assembly ||
+ desc.kind == ArtifactKind::Source)
+ {
+ return true;
+ }
- // Write the contents
- SLANG_RETURN_ON_FAIL(File::writeAllBytes(path, blob->getBufferPointer(), blob->getBufferSize()));
+ /* Hmm, we might want to have a base class for 'signifiant' payloads,
+ where signifiance here means somewhat approximately 'the meat' of a compilation result,
+ as contrasted with 'meta data', 'diagnostics etc'*/
+ if (isDerivedFrom(desc.payload, ArtifactPayload::MetaData))
+ {
+ return false;
+ }
- ComPtr<IFileArtifactRepresentation> fileRep;
-
- // TODO(JS): This path comparison is perhaps not perfect, in that it assumes the path is not changed
- // in any way. For example an impl of calcArtifactPath that changed slashes or used a canonical path
- // might mean the lock file and the rep have the same path.
- // As it stands calcArtifactPath impl doesn't do that, but that is perhaps somewhatfragile
-
- // If the paths are identical, we can just use the lock file for the rep
- if (UnownedStringSlice(lockFile->getPath()) == path.getUnownedSlice())
- {
- fileRep.swap(lockFile);
- }
- else
- {
- // Create a new rep that references the lock file
- fileRep = new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Owned, path, lockFile, lockFile->getFileSystem());
- }
-
- // Create the rep
- if (canKeep(keep))
- {
- artifact->addRepresentation(fileRep);
- }
-
- // Return the file
- *outFileRep = fileRep.detach();
- return SLANG_OK;
+ return true;
}
-SlangResult DefaultArtifactHandler::_loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary)
+/* static */String ArtifactUtil::getBaseName(IArtifact* artifact)
{
- // If it is 'shared library' for a CPU like thing, we can try and load it
- const auto desc = artifact->getDesc();
- if ((isDerivedFrom(desc.kind, ArtifactKind::HostCallable) ||
- isDerivedFrom(desc.kind, ArtifactKind::SharedLibrary)) &&
- isDerivedFrom(desc.payload, ArtifactPayload::CPULike))
- {
- // Get as a file represenation on the OS file system
- ComPtr<IFileArtifactRepresentation> fileRep;
- SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::No, nullptr, fileRep.writeRef()));
-
- // We requested on the OS file system, just check that's what we got...
- SLANG_ASSERT(fileRep->getFileSystem() == nullptr);
-
- // Try loading the shared library
- SharedLibrary::Handle handle;
- if (SLANG_FAILED(SharedLibrary::loadWithPlatformPath(fileRep->getPath(), handle)))
- {
- return SLANG_FAIL;
- }
-
- // The ScopeSharedLibrary will keep the fileRep in scope as long as is needed
- auto sharedLibrary = new ScopeSharedLibrary(handle, fileRep);
-
- if (canKeep(keep))
- {
- // We want to keep the fileRep, as that is necessary for the sharedLibrary to even work
- artifact->addRepresentation(fileRep);
- // Keep the shared library
- artifact->addRepresentation(sharedLibrary);
- }
-
- // Output
- sharedLibrary->addRef();
- *outSharedLibrary = sharedLibrary;
-
- return SLANG_OK;
- }
-
- return SLANG_FAIL;
-}
-
-SlangResult DefaultArtifactHandler::_loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob)
-{
- SLANG_UNUSED(keep);
-
- ComPtr<ISlangBlob> blob;
-
- // Look for a representation that we can serialize into a blob
- for (auto rep : artifact->getRepresentations())
- {
- if (auto artifactRep = as<IArtifactRepresentation>(rep))
- {
- SlangResult res = artifactRep->writeToBlob(blob.writeRef());
- if (SLANG_SUCCEEDED(res) && blob)
- {
- break;
- }
- }
- }
-
- // Wasn't able to construct
- if (!blob)
- {
- return SLANG_E_NOT_FOUND;
- }
-
- *outBlob = blob.detach();
- return SLANG_OK;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactUtilImpl !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-/* static */ArtifactUtilImpl ArtifactUtilImpl::g_singleton;
-
-SlangResult ArtifactUtilImpl::queryInterface(SlangUUID const& uuid, void** outObject)
-{
- if (auto intf = getInterface(uuid))
- {
- *outObject = intf;
- return SLANG_OK;
- }
- return SLANG_E_NO_INTERFACE;
-}
-
-void* ArtifactUtilImpl::getInterface(const Guid& guid)
-{
- if (guid == ISlangUnknown::getTypeGuid() || guid == IArtifactUtil::getTypeGuid())
- {
- return static_cast<IArtifactUtil*>(this);
- }
- return nullptr;
-}
-
-SlangResult ArtifactUtilImpl::createArtifact(const ArtifactDesc& desc, const char* inName, IArtifact** outArtifact)
-{
- *outArtifact = inName ?
- Artifact::create(desc, inName).detach() :
- Artifact::create(desc).detach();
-
- return SLANG_OK;
-}
-
-SlangResult ArtifactUtilImpl::createArtifactContainer(const ArtifactDesc& desc, const char* inName, IArtifactContainer** outArtifactContainer)
-{
- *outArtifactContainer = inName ?
- ArtifactContainer::create(desc, inName).detach() :
- ArtifactContainer::create(desc).detach();
-
- return SLANG_OK;
-}
-
-ArtifactKind ArtifactUtilImpl::getKindParent(ArtifactKind kind) { return getParent(kind); }
-UnownedStringSlice ArtifactUtilImpl::getKindName(ArtifactKind kind) { return getName(kind); }
-bool ArtifactUtilImpl::isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) { return isDerivedFrom(kind, base); }
-
-ArtifactPayload ArtifactUtilImpl::getPayloadParent(ArtifactPayload payload) { return getParent(payload); }
-UnownedStringSlice ArtifactUtilImpl::getPayloadName(ArtifactPayload payload) { return getName(payload); }
-bool ArtifactUtilImpl::isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) { return isDerivedFrom(payload, base); }
-
-ArtifactStyle ArtifactUtilImpl::getStyleParent(ArtifactStyle style) { return getParent(style); }
-UnownedStringSlice ArtifactUtilImpl::getStyleName(ArtifactStyle style) { return getName(style); }
-bool ArtifactUtilImpl::isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) { return isDerivedFrom(style, base); }
-
-SlangResult ArtifactUtilImpl::createLockFile(const char* inNameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile)
-{
- if (fileSystem)
- {
- if (fileSystem != OSFileSystem::getMutableSingleton())
- {
- // We can only create lock files, on the global OS file system
- return SLANG_E_NOT_AVAILABLE;
- }
- fileSystem = nullptr;
- }
-
- const UnownedStringSlice nameBase = (inNameBase && inNameBase[0] != 0) ? UnownedStringSlice(inNameBase) : UnownedStringSlice("unknown");
-
- String lockPath;
- SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, lockPath));
-
- ComPtr<IFileArtifactRepresentation> lockFile(new FileArtifactRepresentation(IFileArtifactRepresentation::Kind::Lock, lockPath, nullptr, fileSystem));
-
- *outLockFile = lockFile.detach();
- return SLANG_OK;
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
+ {
+ return ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep);
+ }
+ // Else use the name
+ return artifact->getName();
}
-SlangResult ArtifactUtilImpl::calcArtifactPath(const ArtifactDesc& desc, const char* inBasePath, ISlangBlob** outPath)
+/* static */String ArtifactUtil::getParentPath(IFileArtifactRepresentation* fileRep)
{
- UnownedStringSlice basePath(inBasePath);
- StringBuilder path;
- SLANG_RETURN_ON_FAIL(ArtifactDescUtil::calcPathForDesc(desc, basePath, path));
- *outPath = StringBlob::create(path).detach();
- return SLANG_OK;
+ UnownedStringSlice path(fileRep->getPath());
+ return Path::getParentDirectory(path);
}
-ArtifactDesc ArtifactUtilImpl::makeDescFromCompileTarget(SlangCompileTarget target)
+/* static */String ArtifactUtil::getParentPath(IArtifact* artifact)
{
- return ArtifactDescUtil::makeDescFromCompileTarget(target);
+ if (auto fileRep = findRepresentation<IFileArtifactRepresentation>(artifact))
+ {
+ return getParentPath(fileRep);
+ }
+ return String();
}
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact-util.h b/source/compiler-core/slang-artifact-util.h
index 5e44b7565..541a1f058 100644
--- a/source/compiler-core/slang-artifact-util.h
+++ b/source/compiler-core/slang-artifact-util.h
@@ -5,104 +5,35 @@
#include "slang-artifact.h"
#include "slang-artifact-representation.h"
-#include "../core/slang-com-object.h"
-
namespace Slang
{
-class DefaultArtifactHandler : public ComBaseObject, public IArtifactHandler
-{
-public:
- SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
-
- // ICastable
- SLANG_NO_THROW void* SLANG_MCALL castAs(const Guid& guid) SLANG_OVERRIDE;
-
- // IArtifactHandler
- SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren(IArtifactContainer* container) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(IArtifact* artifact, const Guid& guid, ArtifactKeep keep, ICastable** outCastable) SLANG_OVERRIDE;
- SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateFileRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outFileRep) SLANG_OVERRIDE;
-
- static IArtifactHandler* getSingleton() { return &g_singleton; }
-protected:
-
- SlangResult _loadSharedLibrary(IArtifact* artifact, ArtifactKeep keep, ISlangSharedLibrary** outSharedLibrary);
- SlangResult _loadBlob(IArtifact* artifact, ArtifactKeep keep, ISlangBlob** outBlob);
-
- void* getInterface(const Guid& uuid);
- void* getObject(const Guid& uuid);
-
- SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ISlangUnknown* rep, ICastable** outCastable);
- SlangResult _addRepresentation(IArtifact* artifact, ArtifactKeep keep, ICastable* castable, ICastable** outCastable);
-
- static DefaultArtifactHandler g_singleton;
-};
-
-class IArtifactUtil : public ISlangUnknown
-{
- SLANG_COM_INTERFACE(0x882b25d7, 0xe300, 0x4b20, { 0xbe, 0xb, 0x26, 0xd2, 0x52, 0x3e, 0x70, 0x20 })
-
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) = 0;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) = 0;
-
- virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) = 0;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) = 0;
- virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) = 0;
-
- virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) = 0;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) = 0;
- virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) = 0;
-
- virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) = 0;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) = 0;
- virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) = 0;
-
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) = 0;
-
- /// Given a desc and a basePath returns a suitable name
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) = 0;
-
- virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) = 0;
-};
-
-class ArtifactUtilImpl : public IArtifactUtil
+struct ArtifactUtil
{
-public:
- // ISlangUnknown
- SLANG_NO_THROW uint32_t SLANG_MCALL addRef() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE { return 1; }
- SLANG_NO_THROW SlangResult SLANG_MCALL queryInterface(SlangUUID const& uuid, void** outObject) SLANG_OVERRIDE;
-
- // IArtifactInterface
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifact(const ArtifactDesc& desc, const char* name, IArtifact** outArtifact) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createArtifactContainer(const ArtifactDesc& desc, const char* name, IArtifactContainer** outArtifactContainer) SLANG_OVERRIDE;
-
- virtual SLANG_NO_THROW ArtifactKind SLANG_MCALL getKindParent(ArtifactKind kind) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getKindName(ArtifactKind kind) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW bool SLANG_MCALL isKindDerivedFrom(ArtifactKind kind, ArtifactKind base) SLANG_OVERRIDE;
-
- virtual SLANG_NO_THROW ArtifactPayload SLANG_MCALL getPayloadParent(ArtifactPayload payload) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getPayloadName(ArtifactPayload payload) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW bool SLANG_MCALL isPayloadDerivedFrom(ArtifactPayload payload, ArtifactPayload base) SLANG_OVERRIDE;
-
- virtual SLANG_NO_THROW ArtifactStyle SLANG_MCALL getStyleParent(ArtifactStyle style) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW UnownedStringSlice SLANG_MCALL getStyleName(ArtifactStyle style) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW bool SLANG_MCALL isStyleDerivedFrom(ArtifactStyle style, ArtifactStyle base) SLANG_OVERRIDE;
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL createLockFile(const char* nameBase, ISlangMutableFileSystem* fileSystem, IFileArtifactRepresentation** outLockFile) SLANG_OVERRIDE;
+ /// Get the base name of this artifact.
+ /// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
+ /// Else if there is an explicit name set, this is returned.
+ /// Else returns the empty string
+ static String getBaseName(IArtifact* artifact);
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL calcArtifactPath(const ArtifactDesc& desc, const char* basePath, ISlangBlob** outPath) SLANG_OVERRIDE;
+ /// Get the parent path (empty if there isn't one)
+ static String getParentPath(IArtifact* artifact);
+ static String getParentPath(IFileArtifactRepresentation* fileRep);
- virtual SLANG_NO_THROW ArtifactDesc SLANG_MCALL makeDescFromCompileTarget(SlangCompileTarget target) SLANG_OVERRIDE;
+ /// Create an empty container which is compatible with the desc
+ static ComPtr<IArtifactContainer> createContainer(const ArtifactDesc& desc);
- static IArtifactUtil* getSingleton() { return &g_singleton; }
+ /// Create a generic container
+ static ComPtr<IArtifactContainer> createResultsContainer();
-protected:
- void* getInterface(const Guid& guid);
+ /// Creates an empty artifact for a type
+ static ComPtr<IArtifact> createArtifactForCompileTarget(SlangCompileTarget target);
- static ArtifactUtilImpl g_singleton;
+ /// Returns true if an artifact is 'significant'
+ static bool isSignificant(IArtifact* artifact, void* data = nullptr);
+ /// Find a significant artifact
+ static IArtifact* findSignificant(IArtifact* artifact) { return artifact->findArtifactByPredicate(IArtifact::FindStyle::SelfOrChildren, &isSignificant, nullptr); }
};
} // namespace Slang
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index e399578a9..bde7f9a08 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -307,6 +307,16 @@ class IArtifact : public ICastable
public:
SLANG_COM_INTERFACE(0x57375e20, 0xbed, 0x42b6, { 0x9f, 0x5e, 0x59, 0x4f, 0x6, 0x2b, 0xe6, 0x90 })
+ typedef bool (*FindFunc)(IArtifact* artifact, void* data);
+ enum class FindStyle : uint8_t
+ {
+ Self, ///< Just on self
+ SelfOrChildren, ///< Self, or if container just the children
+ Recursive, ///< On self plus any children recursively
+ Children, ///< Only on children
+ ChildrenRecursive, ///< Only on children recursively
+ };
+
typedef ArtifactDesc Desc;
typedef ArtifactKind Kind;
@@ -361,6 +371,18 @@ public:
/// Given a typeGuid representing the desired type get or create the representation.
/// If found outCastable holds an entity that *must* be castable to typeGuid
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getOrCreateRepresentation(const Guid& typeGuid, ArtifactKeep keep, ICastable** outCastable) = 0;
+
+ /// Get the children, will only remain valid if no mutation of children list
+ virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() = 0;
+
+ /// Find an artifact that matches desc allowing derivations. Flags is ignored
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDerivedDesc(FindStyle findStyle, const ArtifactDesc& desc) = 0;
+ /// Find an artifact that predicate matches
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByPredicate(FindStyle findStyle, FindFunc func, void* data) = 0;
+ /// Find by name
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByName(FindStyle findStyle, const char* name) = 0;
+ /// Find by desc exactly
+ virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findArtifactByDesc(FindStyle findStyle, const ArtifactDesc& desc) = 0;
};
class IArtifactContainer : public IArtifact
@@ -368,30 +390,19 @@ class IArtifactContainer : public IArtifact
public:
SLANG_COM_INTERFACE(0xa96e29bd, 0xb546, 0x4e79, { 0xa0, 0xdc, 0x67, 0x49, 0x22, 0x2c, 0x39, 0xad })
- typedef bool (*FindFunc)(IArtifact* artifact, void* data);
-
/// Returns the result of expansion. Will return SLANG_E_UNINITIALIZED if expansion hasn't happened
virtual SLANG_NO_THROW SlangResult SLANG_MCALL getExpandChildrenResult() = 0;
/// Sets all of the children, will set the expansion state to SLANG_OK
virtual SLANG_NO_THROW void SLANG_MCALL setChildren(IArtifact**children, Count count) = 0;
/// Will be called implicitly on access to children
virtual SLANG_NO_THROW SlangResult SLANG_MCALL expandChildren() = 0;
- /// Get the children, will only remain valid if no mutation of children list
- virtual SLANG_NO_THROW Slice<IArtifact*> SLANG_MCALL getChildren() = 0;
+
/// Add the artifact to the list
virtual SLANG_NO_THROW void SLANG_MCALL addChild(IArtifact* artifact) = 0;
/// Removes the child at index, keeps other artifacts in the same order
virtual SLANG_NO_THROW void SLANG_MCALL removeChildAt(Index index) = 0;
/// Clear the list
virtual SLANG_NO_THROW void SLANG_MCALL clearChildren() = 0;
- /// Find an artifact which is an exact match for the desc
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDesc(const ArtifactDesc& desc) = 0;
- /// Find an artifact that matches desc allowing derivations. Flags is ignored
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByDerivedDesc(const ArtifactDesc& desc) = 0;
- /// Find by name
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByName(const char* name) = 0;
- /// Find via predicate function
- virtual SLANG_NO_THROW IArtifact* SLANG_MCALL findChildByPredicate(FindFunc func, void* data) = 0;
};
template <typename T>
diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h
index 9d58f6678..666ca5568 100644
--- a/source/compiler-core/slang-downstream-compiler.h
+++ b/source/compiler-core/slang-downstream-compiler.h
@@ -120,7 +120,8 @@ struct DownstreamDiagnostics
class DownstreamCompileResult : public RefObject
{
public:
-
+ SLANG_CLASS_GUID(0xdfc5d318, 0x8675, 0x40ef, { 0xbd, 0x7b, 0x4, 0xa4, 0xff, 0x66, 0x11, 0x30 })
+
virtual SlangResult getHostCallableSharedLibrary(ComPtr<ISlangSharedLibrary>& outLibrary) = 0;
virtual SlangResult getBinary(ComPtr<ISlangBlob>& outBlob) = 0;
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index 8467cbbdc..771aa870a 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -19,7 +19,7 @@
#include "../core/slang-shared-library.h"
-#include "../compiler-core/slang-artifact-desc-util.h"
+#include "../compiler-core/slang-artifact-util.h"
// Enable calling through to `dxc` to
// generate code on Windows.
@@ -83,7 +83,7 @@ static UnownedStringSlice _addName(const UnownedStringSlice& inSlice, StringSlic
static UnownedStringSlice _addName(IArtifact* artifact, StringSlicePool& pool)
{
- return _addName(ArtifactDescUtil::getBaseName(artifact).getUnownedSlice(), pool);
+ return _addName(ArtifactUtil::getBaseName(artifact).getUnownedSlice(), pool);
}
class DxcIncludeHandler : public IDxcIncludeHandler
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 3a0217d86..c1e6e8fbc 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -11,6 +11,7 @@
#include "../core/slang-string-slice-pool.h"
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-util.h"
namespace Slang
{
@@ -649,7 +650,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
// Get the name and path (can be empty) to the library
SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
- libPathPool.add(ArtifactDescUtil::getParentPath(fileRep));
+ libPathPool.add(ArtifactUtil::getParentPath(fileRep));
cmdLine.addPrefixPathArg("-l", ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep));
}
}
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp
index 43c991337..21db9570a 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.cpp
+++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp
@@ -12,7 +12,9 @@
#endif
#include "../core/slang-io.h"
+
#include "slang-artifact-desc-util.h"
+#include "slang-artifact-util.h"
namespace Slang
{
@@ -270,7 +272,7 @@ namespace Slang
ComPtr<IFileArtifactRepresentation> fileRep;
SLANG_RETURN_ON_FAIL(artifact->requireFile(ArtifactKeep::Yes, nullptr, fileRep.writeRef()));
- libPathPool.add(ArtifactDescUtil::getParentPath(fileRep));
+ libPathPool.add(ArtifactUtil::getParentPath(fileRep));
// We need the extension for windows
cmdLine.addArg(ArtifactDescUtil::getBaseName(artifact->getDesc(), fileRep) + ".lib");
}