summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-06-24 10:00:23 -0400
committerGitHub <noreply@github.com>2021-06-24 10:00:23 -0400
commit542741143b69c248ab457d1f767b0895430e9f90 (patch)
tree5a3592ae41ad240aa3ef3c0dcd7ca7bff39af346
parent353777ec33b5b097e0d0f4bc602811a9775ef237 (diff)
Remove StructTag and associated systems (#1895)
* #include an absolute path didn't work - because paths were taken to always be relative. * Remove StructTag and associated systems. * Fix typo and remove unit test for StructTag.
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj4
-rw-r--r--build/visual-studio/compiler-core/compiler-core.vcxproj.filters12
-rw-r--r--build/visual-studio/slang-test/slang-test.vcxproj1
-rw-r--r--build/visual-studio/slang-test/slang-test.vcxproj.filters3
-rw-r--r--slang.h183
-rw-r--r--source/compiler-core/slang-misc-diagnostic-defs.h5
-rw-r--r--source/compiler-core/slang-struct-tag-converter.cpp538
-rw-r--r--source/compiler-core/slang-struct-tag-converter.h153
-rw-r--r--source/compiler-core/slang-struct-tag-system.cpp126
-rw-r--r--source/compiler-core/slang-struct-tag-system.h259
-rwxr-xr-xsource/slang/slang-compiler.h7
-rw-r--r--source/slang/slang.cpp65
-rw-r--r--tools/slang-test/unit-test-struct-tag.cpp255
13 files changed, 23 insertions, 1588 deletions
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj b/build/visual-studio/compiler-core/compiler-core.vcxproj
index da485b602..d472270cb 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj
@@ -191,8 +191,6 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-name.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-nvrtc-compiler.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-source-loc.h" />
- <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-converter.h" />
- <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-system.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-token-defs.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-token.h" />
<ClInclude Include="..\..\..\source\compiler-core\slang-visual-studio-compiler-util.h" />
@@ -217,8 +215,6 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-name.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-nvrtc-compiler.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-source-loc.cpp" />
- <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-converter.cpp" />
- <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-system.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-token.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\slang-visual-studio-compiler-util.cpp" />
<ClCompile Include="..\..\..\source\compiler-core\windows\slang-win-visual-studio-util.cpp" />
diff --git a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
index 2d88ae29d..da0ca5d63 100644
--- a/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
+++ b/build/visual-studio/compiler-core/compiler-core.vcxproj.filters
@@ -72,12 +72,6 @@
<ClInclude Include="..\..\..\source\compiler-core\slang-source-loc.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-converter.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\source\compiler-core\slang-struct-tag-system.h">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\source\compiler-core\slang-token-defs.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -146,12 +140,6 @@
<ClCompile Include="..\..\..\source\compiler-core\slang-source-loc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-converter.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\source\compiler-core\slang-struct-tag-system.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\source\compiler-core\slang-token.cpp">
<Filter>Source Files</Filter>
</ClCompile>
diff --git a/build/visual-studio/slang-test/slang-test.vcxproj b/build/visual-studio/slang-test/slang-test.vcxproj
index a8c9506a8..a0b7eb825 100644
--- a/build/visual-studio/slang-test/slang-test.vcxproj
+++ b/build/visual-studio/slang-test/slang-test.vcxproj
@@ -189,7 +189,6 @@
<ClCompile Include="..\..\..\tools\slang-test\unit-test-riff.cpp" />
<ClCompile Include="..\..\..\tools\slang-test\unit-test-short-list.cpp" />
<ClCompile Include="..\..\..\tools\slang-test\unit-test-string.cpp" />
- <ClCompile Include="..\..\..\tools\slang-test\unit-test-struct-tag.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\core\core.vcxproj">
diff --git a/build/visual-studio/slang-test/slang-test.vcxproj.filters b/build/visual-studio/slang-test/slang-test.vcxproj.filters
index 99735f156..1e5b6e4af 100644
--- a/build/visual-studio/slang-test/slang-test.vcxproj.filters
+++ b/build/visual-studio/slang-test/slang-test.vcxproj.filters
@@ -86,8 +86,5 @@
<ClCompile Include="..\..\..\tools\slang-test\unit-test-string.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\tools\slang-test\unit-test-struct-tag.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/slang.h b/slang.h
index 944e42b0e..4f9cb69ce 100644
--- a/slang.h
+++ b/slang.h
@@ -450,178 +450,6 @@ convention for interface methods.
#include <stddef.h>
#endif // ! SLANG_NO_STDDEF
-namespace slang
-{
-
-/* Slang provides a mechanism for value types (such as structures) to be able to provide forward and backward
-ABI compatibility through.
-
-The type is made up of several parts.
-0) The kind primary or extension
-1) The category the type is in
-2) An id for the type in the category
-3) The major semantic version
-4) The minor semantic version
-
-Within the 'semantic versioning' a structure that has only a larger minor semantic version can be used (with some
-caveats) as is when being passed to a previous version of Slang. It may contain more fields.
-*/
-
-enum class StructTagKind : uint8_t
-{
- Primary, ///< A primary struct (contains optional extensions)
- Extension, ///< An extension struct
-};
-
-#define SLANG_STRUCT_TAG_ENUM(x) x,
-
-#define SLANG_STRUCT_TAG_CATEGORIES(x) \
- x(Core) \
- x(Slang) \
- x(Gfx)
-
-
-enum class StructTagCategory : uint8_t
-{
- SLANG_STRUCT_TAG_CATEGORIES(SLANG_STRUCT_TAG_ENUM)
- CountOf,
-};
-
-/* AbiStructType is laid out as follows
-
- |Primary | Category | Type | Major version | Minor Version
------|--------|--------------|-----------|---------------|----------------
-Bits | 31 | 30-24 | 23-16 | 15-8 | 0-7
-Type | | AbiCategory | Cat Spec | |
-
-Type will be specified as something specific for the category. A typical implementation will have an enum that lists
-types for that category.
-
-TODO(JS): This layout may need to be altered - too may bits are perhaps used by major/minor version for example. This should
-be fine for the immediate future though.
-*/
-
-typedef uint32_t StructTagInt;
-typedef uint32_t StructSize;
-
-enum class StructTag : StructTagInt;
-
-enum : uint32_t
-{
- kStructTagPrimaryMask = 0x80000000,
-
- kStructTagCategoryMask = 0x7f000000,
- kStructTagCategoryShift = 24,
-
- // Combination of category and TypeIndex
- kStructTagCategoryTypeIndexMask = 0x7fff0000,
- kStructTagCategoryTypeIndexShift = 16,
-
- kStructTagCategoryTypeMajorMask = 0xffffff00,
-
- kStructTagTypeIndexMask = 0x00ff0000,
- kStructTagTypeIndexShift = 16,
-
- kStructTagVersionMask = 0x0000ffff,
- kStructTagVersionShift = 0,
-
- kStructTagMajorMask = 0x0000ff00,
- kStructTagMajorShift = 8,
-
- kStructTagMinorMask = 0x000000ff,
- kStructTagMinorShift = 0,
-};
-
-// Types purely for use in template type identification
-// Any Primary or Extension TaggedStruct must have a typedef of one of these as Tag.
-enum class PrimaryTag;
-enum class ExtensionTag;
-
-#define SLANG_MAKE_PRIMARY_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR) slang::StructTag(slang::StructTagInt(slang::kStructTagPrimaryMask) | (slang::StructTagInt(CATEGORY) << 24) | (slang::StructTagInt(TYPE_ID) << 16) | (slang::StructTagInt(MAJOR) << 8) | slang::StructTagInt(MINOR))
-#define SLANG_MAKE_EXTENSION_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR) slang::StructTag((slang::StructTagInt(CATEGORY) << 24) | (slang::StructTagInt(TYPE_ID) << 16) | (slang::StructTagInt(MAJOR) << 8) | slang::StructTagInt(MINOR))
-
-/*
-`PrimaryStruct`s are structs that are passed directly into API calls. They always contain a 'structType' that identifies the exact version
-and type of that is being passed in. `PrimaryStruct`s can also specify optional `ExtensionStruct` types that modify and/or add to the values
-in the `PrimaryStruct`.
-
-`ExtensionStruct` cannot contain optional other extensions as PrimaryStructs do - all required extensions have to be specified via the list set on the
-`PrimaryStruct`.
-
-`ExtensionStruct` is typically used when it is necessary to provide some special additional information that is not appropriate to place within
-the `PrimaryStruct`. This also provides a mechanism such that a `PrimaryStruct` derived type does not need to include all the fields that will
-every be needed. Cross cutting aspects can have their own uniquely identified structs.
-
-As a mechanism to provide extensibility without having to modify a struct or to allow optional and/or additional information through
-ExtensionStruct set via the `exts` and `extsCount` members.
-
-A type that is ABI compatible with this mechanism must start with exactly the same fields as specified.
-When using extensions, the exts and extsCount should be set. `exts` points to the extension ids (which must be at the start of the types)
-to provide some kind of type safely without requiring inheritance.
-*/
-
-#define SLANG_EXTENSION_TAGGED_STRUCT_IMPL(TYPE_NAME, CATEGORY, TYPE_ID, MAJOR, MINOR) \
- typedef TYPE_NAME ThisType; \
- typedef slang::ExtensionTag Tag; \
- static const slang::StructTag kStructTag = SLANG_MAKE_EXTENSION_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR); \
- slang::StructTag structTag = kStructTag; \
- slang::StructSize structSize = slang::StructSize(sizeof(ThisType));
-
-#define SLANG_PRIMARY_TAGGED_STRUCT_IMPL(TYPE_NAME, CATEGORY, TYPE_ID, MAJOR, MINOR) \
- typedef TYPE_NAME ThisType; \
- typedef ::slang::PrimaryTag Tag; \
- static const ::slang::StructTag kStructTag = SLANG_MAKE_PRIMARY_STRUCT_TAG(CATEGORY, TYPE_ID, MAJOR, MINOR); \
- slang::StructTag structTag = kStructTag; \
- slang::StructSize structSize = slang::StructSize(sizeof(ThisType)); \
- const slang::StructTag** exts = nullptr; \
- int32_t extsCount = 0;
-
-#define SLANG_API_TYPE_ENUM(x) x,
-
-struct TaggedStructBase
-{
- StructTag structTag; ///< Identity for the type
- StructSize structSize; ///< Size of the type in bytes
-};
-
-/* Layout for a PrimaryTaggedStruct */
-struct PrimaryTaggedStruct
-{
- StructTag structTag; ///< Identity for the type
- StructSize structSize; ///< Size of the type in bytes
- const StructTag** exts; ///< Extensions - StructTag type should be the first member of Extension structs
- int32_t extsCount = 0; ///< The number of extensions
-};
-
-/* Layout for a Extension TaggedStruct */
-struct ExtensionTaggedStruct
-{
- StructTag structTag; ///< Identity for the type
- StructSize structSize; ///< Size of the type in bytes
-};
-
-// Enumerate all of the types that want ABI handling as part of Slang API.
-//
-// NOTE! That care is needed using the enumeration, because we want IDs to remain stable.
-// New types should be added to the end. Removed types should become Depreciated_Name (say).
-//
-// NOTE! The names must match the type name for an active type exactly for the SLANG_PRIMARY_TAGGED_STRUCT and SLANG_EXTENSION_TAGGED_STRUCT
-// macros to work.
-#define SLANG_TAGGED_STRUCTS(x) \
- x(TargetDesc) \
- x(SessionDesc)
-
-// Define Slangs types in the enum
-enum class SlangTaggedStruct
-{
- SLANG_TAGGED_STRUCTS(SLANG_STRUCT_TAG_ENUM)
-};
-
-#define SLANG_PRIMARY_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_PRIMARY_TAGGED_STRUCT_IMPL(TYPE_NAME, StructTagCategory::Slang, SlangTaggedStruct::TYPE_NAME, MAJOR, MINOR)
-#define SLANG_EXTENSION_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_EXTENSION_TAGGED_STRUCT_IMPL(TYPE_NAME, StructTagCategory::Slang, SlangTaggedStruct::TYPE_NAME, MAJOR, MINOR)
-
-} // namespace slang
-
#ifdef __cplusplus
extern "C"
{
@@ -1003,9 +831,6 @@ extern "C"
//! Could not complete because some underlying feature (hardware or software) was not available
#define SLANG_E_NOT_AVAILABLE SLANG_MAKE_CORE_ERROR(7)
- //! A type specified is StructTag incompatible with this version of slang
-#define SLANG_E_STRUCT_TAG_INCOMPATIBLE SLANG_MAKE_CORE_ERROR(8)
-
/** A "Universally Unique Identifier" (UUID)
The Slang API uses UUIDs to identify interfaces when
@@ -3979,7 +3804,9 @@ namespace slang
*/
struct TargetDesc
{
- SLANG_PRIMARY_TAGGED_STRUCT(TargetDesc, 0, 0)
+ /** The size of this structure, in bytes.
+ */
+ size_t structureSize = sizeof(TargetDesc);
/** The target format to generate code for (e.g., SPIR-V, DXIL, etc.)
*/
@@ -4029,7 +3856,9 @@ namespace slang
struct SessionDesc
{
- SLANG_PRIMARY_TAGGED_STRUCT(SessionDesc, 0, 0)
+ /** The size of this structure, in bytes.
+ */
+ size_t structureSize = sizeof(SessionDesc);
/** Code generation targets to include in the session.
*/
diff --git a/source/compiler-core/slang-misc-diagnostic-defs.h b/source/compiler-core/slang-misc-diagnostic-defs.h
index f3ac0bae5..aa87f02f9 100644
--- a/source/compiler-core/slang-misc-diagnostic-defs.h
+++ b/source/compiler-core/slang-misc-diagnostic-defs.h
@@ -30,11 +30,6 @@ DIAGNOSTIC(100002, Error, unbalancedDownstreamArguments, "unbalanced downstream
DIAGNOSTIC(100003, Error, closeOfUnopenDownstreamArgs, "close of an unopen downstream argument scope")
DIAGNOSTIC(100004, Error, downstreamToolNameNotDefined, "downstream tool name not defined")
-DIAGNOSTIC(110001, Error, structTagConversionFailureNoArena, "StructTag conversion failed - no arena")
-DIAGNOSTIC(110002, Error, unknownStructTag, "unknown StructTag $0")
-DIAGNOSTIC(110003, Error, cannotConvertStructTag, "cannot convert StructTag $0 to $1")
-DIAGNOSTIC(110004, Error, cannotConvertDifferentStructTag, "cannot convert different StructTag types $0 to $1")
-
DIAGNOSTIC(99999, Note, noteLocationOfInternalError, "an internal error threw an exception while working on code near this location")
#undef DIAGNOSTIC
diff --git a/source/compiler-core/slang-struct-tag-converter.cpp b/source/compiler-core/slang-struct-tag-converter.cpp
deleted file mode 100644
index 9e891e642..000000000
--- a/source/compiler-core/slang-struct-tag-converter.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-#include "slang-struct-tag-converter.h"
-
-#include "slang-core-diagnostics.h"
-
-namespace Slang {
-
-static Index _getCount(const StructTagType::Field& field, const void* in)
-{
- typedef StructTagField::Type FieldType;
-
- const uint8_t* ptr = (const uint8_t*)in;
-
- switch (field.m_countType)
- {
- case FieldType::I32: return Index(*(const int32_t*)(ptr + field.m_countOffset));
- case FieldType::I64: return Index(*(const int64_t*)(ptr + field.m_countOffset));
- default: break;
- }
-
- SLANG_ASSERT(!"Cannot access as count");
- return -1;
-}
-
-SlangResult StructTagConverterBase::_requireArena()
-{
- if (!m_arena)
- {
- if (m_sink)
- {
- // Diagnose that we need an arena
- m_sink->diagnose(SourceLoc(), MiscDiagnostics::structTagConversionFailureNoArena);
- }
- return SLANG_FAIL;
- }
-
- return SLANG_OK;
-}
-
-SlangResult StructTagConverterBase::_diagnoseCantConvert(slang::StructTag tag, StructTagType* structType)
-{
- SLANG_UNUSED(tag);
- SLANG_UNUSED(structType);
-
- if (m_sink)
- {
- // Diagnose why the tag couldn't be converted
- StringBuilder from, to;
- m_system->appendName(tag, from);
- m_system->appendName(structType->m_tag, to);
-
- m_sink->diagnose(SourceLoc(), MiscDiagnostics::cannotConvertStructTag, from, to);
- }
-
- return SLANG_E_STRUCT_TAG_INCOMPATIBLE;
-}
-
-SlangResult StructTagConverterBase::_diagnoseUnknownType(slang::StructTag tag)
-{
- SLANG_UNUSED(tag);
-
- if (m_sink)
- {
- StringBuilder buf;
- m_system->appendName(tag, buf);
- m_sink->diagnose(SourceLoc(), MiscDiagnostics::unknownStructTag, buf);
- }
-
- // Perhaps this isn't quite right - but it's probably the most suitable error
- return SLANG_E_STRUCT_TAG_INCOMPATIBLE;
-}
-
-SlangResult StructTagConverterBase::_diagnoseDifferentTypes(slang::StructTag tagA, slang::StructTag tagB)
-{
- if (m_sink)
- {
- StringBuilder a, b;
- m_system->appendName(tagA, a);
- m_system->appendName(tagB, b);
-
- m_sink->diagnose(SourceLoc(), MiscDiagnostics::cannotConvertDifferentStructTag, a, b);
- }
-
- // Perhaps this isn't quite right - but it's probably the most suitable error
- return SLANG_E_STRUCT_TAG_INCOMPATIBLE;
-}
-
-bool StructTagConverterBase::canConvertToCurrent(slang::StructTag tag, StructTagType* type) const
-{
- // Means can be used without any modification
- if (StructTagUtil::isReadCompatible(tag, type->m_tag))
- {
- return true;
- }
-
- // We may want to allow zero extension, or initialization
- // We can accept for conversion if it's the same type with only difference being the minor version.
- return StructTagUtil::areSameMajorType(tag, type->m_tag);
-}
-
-void StructTagConverterBase::copy(const StructTagType* structType, const void* src, void* dst)
-{
- const slang::TaggedStructBase* srcBase = reinterpret_cast<const slang::TaggedStructBase*>(src);
-
- const slang::StructSize size = std::min(structType->m_sizeInBytes, srcBase->structSize);
-
- // Copy
- ::memcpy(dst, src, size);
-
- // TODO(JS): Alternatively if we have the default set on the structType, we could initialize
- // other fields with the default values. For the moment we zero
-
- // Zero any extra
- if (size < structType->m_sizeInBytes)
- {
- ::memset((char*)dst + size, 0, structType->m_sizeInBytes - size);
- }
-
- // Set the type and the size
- slang::TaggedStructBase* dstBase = reinterpret_cast<slang::TaggedStructBase*>(dst);
- dstBase->structTag = structType->m_tag;
- dstBase->structSize = structType->m_sizeInBytes;
-}
-
-void* StructTagConverterBase::allocateAndCopy(const StructTagType* structType, const void* src)
-{
- uint8_t* dst = (uint8_t*)m_arena->allocate(structType->m_sizeInBytes);
- copy(structType, src, dst);
- return dst;
-}
-
-SlangResult StructTagConverterBase::convertCurrent(slang::StructTag tag, const void* in, void*& out)
-{
- auto base = reinterpret_cast<const slang::TaggedStructBase*>(in);
- auto inTag = base->structTag;
-
- // Currently we can only convert if same major type.
- // In future it might be possible to improve on this
- if (!StructTagUtil::areSameMajorType(inTag, tag))
- {
- return _diagnoseDifferentTypes(inTag, tag);
- }
-
- return convertCurrent(in, out);
-}
-
-SlangResult StructTagConverterBase::convertArrayField(const FieldType type, const void* in, Index count, void*& out)
-{
- if (count <= 0)
- {
- out = const_cast<void*>(in);
- return SLANG_OK;
- }
-
- SLANG_ASSERT(in);
- switch (type)
- {
- case FieldType::PtrTaggedStruct: return convertCurrentArray(in, count, out);
- case FieldType::PtrPtrTaggedStruct: return convertCurrentPtrArray((const void*const*)in, count, (void**&)out);
- default: break;
- }
- return SLANG_FAIL;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- CopyStructTagConverter
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-SlangResult CopyStructTagConverter::convertCurrentPtrArray(const void*const* in, Index count, void**& out)
-{
- if (count == 0)
- {
- out = nullptr;
- return SLANG_OK;
- }
- void** dst = (void**)m_arena->allocate(count * sizeof(void*));
- for (Index i = 0; i < count; ++i)
- {
- SLANG_RETURN_ON_FAIL(convertCurrent(in[i], dst[i]));
- }
- out = dst;
- return SLANG_OK;
-}
-
-SlangResult CopyStructTagConverter::convertCurrentArray(const void* in, Index count, void*& out)
-{
- if (count <= 0)
- {
- out = nullptr;
- return SLANG_OK;
- }
-
- if (count == 1)
- {
- return convertCurrent(in, out);
- }
-
- const slang::TaggedStructBase* arr = reinterpret_cast<const slang::TaggedStructBase*>(in);
-
- // We assume all have the same size/type
- auto tag = arr[0].structTag;
-
- auto structType = m_system->getType(tag);
-
- if (!structType)
- {
- return _diagnoseUnknownType(tag);
- }
- if (!canConvertToCurrent(tag, structType))
- {
- return _diagnoseCantConvert(tag, structType);
- }
-
- const size_t dstStride = structType->m_sizeInBytes;
- uint8_t*const dstStart = (uint8_t*)m_arena->allocate(dstStride * count);
- uint8_t* dst = dstStart;
-
- size_t srcStride = arr[0].structSize;
- const uint8_t* src = reinterpret_cast<const uint8_t*>(in);
-
- for (Index i = 0; i < count; ++i)
- {
- copy(structType, src, dst);
- SLANG_RETURN_ON_FAIL(convertCurrentContained(structType, dst));
-
- src += srcStride;
- dst += dstStride;
- }
-
- out = dstStart;
- return SLANG_OK;
-}
-
-SlangResult CopyStructTagConverter::convertCurrentContained(const StructTagType* structType, void* inout)
-{
- // Convert primary
- if (StructTagUtil::isPrimary(structType->m_tag))
- {
- // Copy extensions if needed
- slang::PrimaryTaggedStruct* primary = reinterpret_cast<slang::PrimaryTaggedStruct*>(inout);
- if (primary->extsCount > 0)
- {
- void** dstExts;
- SLANG_RETURN_ON_FAIL(convertCurrentPtrArray((const void*const*)primary->exts, primary->extsCount, dstExts));
- primary->exts = (const slang::StructTag**)dstExts;
- }
- }
-
- // It may have fields that need to be converted
- for (const auto& field : structType->m_fields)
- {
- const Index count = _getCount(field, inout);
- if (count)
- {
- void*& ptrRef = *(void**)(reinterpret_cast<uint8_t*>(inout) + field.m_offset);
- SLANG_RETURN_ON_FAIL(convertArrayField(field.m_type, ptrRef, count, ptrRef));
- }
- }
-
- return SLANG_OK;
-}
-
-SlangResult CopyStructTagConverter::convertCurrent(const void* in, void*& out)
-{
- auto tag = reinterpret_cast<const slang::TaggedStructBase*>(in)->structTag;
-
- auto structType = m_system->getType(tag);
- if (!structType)
- {
- return _diagnoseUnknownType(tag);
- }
- if (!canConvertToCurrent(tag, structType))
- {
- return _diagnoseCantConvert(tag, structType);
- }
-
- slang::TaggedStructBase* dst = (slang::TaggedStructBase*)allocateAndCopy(structType, in);
- SLANG_RETURN_ON_FAIL(convertCurrentContained(structType, dst));
- out = dst;
- return SLANG_OK;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- LazyStructTagConverter
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-SlangResult LazyStructTagConverter::convertCurrentPtrArray(const void*const* in, Index count, void**& out)
-{
- if (count == 0)
- {
- out = (void**)in;
- return SLANG_OK;
- }
-
- Index numConverted = 0;
- ScopeStack stackScope(this);
-
- for (Index i = 0; i < count; ++i)
- {
- const void* src = in[i];
- void* dst;
- SLANG_RETURN_ON_FAIL(convertCurrent(src, dst));
-
- // Make space if not set up
- numConverted += Index(dst != src);
- m_convertStack.add(dst);
- }
-
- // We need to make a copy of the exts
- if (numConverted)
- {
- SLANG_RETURN_ON_FAIL(_requireArena());
- out = (void**)m_arena->allocateAndCopyArray(m_convertStack.getBuffer() + stackScope.getStartIndex(), count);
- }
- else
- {
- out = (void**)in;
- }
-
- return SLANG_OK;
-}
-
-void LazyStructTagConverter::setContainedConverted(const StructTagType* structType, Index stackIndex, BitField fieldsSet, void* out)
-{
- if (fieldsSet == 0)
- {
- return;
- }
-
- if (StructTagUtil::isPrimary(structType->m_tag))
- {
- if (fieldsSet & 1)
- {
- // Copy extensions if needed
- slang::PrimaryTaggedStruct* primary = reinterpret_cast<slang::PrimaryTaggedStruct*>(out);
- primary->exts = (const slang::StructTag**)m_convertStack[stackIndex++];
- }
- fieldsSet >>= 1;
- }
-
- {
- for (const auto& field : structType->m_fields)
- {
- if (fieldsSet == 0)
- {
- return;
- }
-
- // If the field is set, copy
- if (fieldsSet & 1)
- {
- switch (field.m_type)
- {
- case FieldType::PtrTaggedStruct:
- case FieldType::PtrPtrTaggedStruct:
- {
- *(const void**)(reinterpret_cast<const uint8_t*>(out) + field.m_offset) = m_convertStack[stackIndex++];
- break;
- }
- default: break;
- }
- }
-
- // Remove the bit
- fieldsSet >>= 1;
- }
- }
-}
-
-
-SlangResult LazyStructTagConverter::maybeConvertCurrentContained(const StructTagType* structType, const void* in, BitField* outFieldsSet)
-{
- BitField fieldsSet = 0;
- BitField bit = 1;
-
- if (StructTagUtil::isPrimary(structType->m_tag))
- {
- // Copy extensions if needed
- const slang::PrimaryTaggedStruct* primary = reinterpret_cast<const slang::PrimaryTaggedStruct*>(in);
- if (primary->extsCount > 0)
- {
- auto srcExts = (const void*const*)primary->exts;
- void** dstExts;
- SLANG_RETURN_ON_FAIL(convertCurrentPtrArray(srcExts, primary->extsCount, dstExts));
-
- if (dstExts != srcExts)
- {
- m_convertStack.add(dstExts);
- fieldsSet |= bit;
- }
- }
-
- bit += bit;
- }
-
- // It may have fields that need to be converted
-
- {
- for (const auto& field : structType->m_fields)
- {
- const Index count = _getCount(field, in);
- if (count > 0)
- {
- void* dst = nullptr;
- const void* src = *(const void**)(reinterpret_cast<const uint8_t*>(in) + field.m_offset);
- SLANG_RETURN_ON_FAIL(convertArrayField(field.m_type, src, count, dst));
-
- if (dst != src)
- {
- // Set the and add to the stack
- m_convertStack.add(dst);
- fieldsSet |= bit;
- }
- }
-
- bit += bit;
- }
- }
-
- *outFieldsSet = fieldsSet;
- return SLANG_OK;
-}
-
-SlangResult LazyStructTagConverter::convertCurrentArray(const void* in, Index count, void*& out)
-{
- if (count == 0)
- {
- out = (void*)in;
- return SLANG_OK;
- }
-
- if (count == 1)
- {
- return convertCurrent(in, out);
- }
-
- const slang::TaggedStructBase* arr = reinterpret_cast<const slang::TaggedStructBase*>(in);
-
- // We assume all have the same size/type
- auto tag = arr[0].structTag;
-
- auto structType = m_system->getType(tag);
-
- if (!structType)
- {
- return _diagnoseUnknownType(tag);
- }
-
- if (StructTagUtil::areSameMajorType(tag, structType->m_tag) && structType->m_sizeInBytes == arr[0].structSize)
- {
- // Can just use what was passed in
- out = (void*)in;
- return SLANG_OK;
- }
-
- if (!canConvertToCurrent(tag, structType))
- {
- return _diagnoseCantConvert(tag, structType);
- }
-
- SLANG_RETURN_ON_FAIL(_requireArena());
-
- const size_t dstStride = structType->m_sizeInBytes;
- uint8_t*const dstStart = (uint8_t*)m_arena->allocate(dstStride * count);
- uint8_t* dst = dstStart;
-
- size_t srcStride = arr[0].structSize;
- const uint8_t* src = reinterpret_cast<const uint8_t*>(in);
-
- for (Index i = 0; i < count; ++i)
- {
- // Do the straight copy
- copy(structType, src, dst);
-
- // Work out what was converted
- ScopeStack scopeStack(this);
- BitField fieldsSet;
- SLANG_RETURN_ON_FAIL(maybeConvertCurrentContained(structType, in, &fieldsSet));
-
- // Copy anything converted
- setContainedConverted(structType, scopeStack, fieldsSet, dst);
-
- src += srcStride;
- dst += dstStride;
- }
-
- out = dstStart;
- return SLANG_OK;
-}
-
-SlangResult LazyStructTagConverter::convertCurrent(const void* in, void*& out)
-{
- auto base = reinterpret_cast<const slang::TaggedStructBase*>(in);
- auto tag = base->structTag;
-
- // If can't find the type it's incompatible
- auto structType = m_system->getType(tag);
- if (!structType)
- {
- return _diagnoseUnknownType(tag);
- }
-
- if (!canConvertToCurrent(tag, structType))
- {
- return _diagnoseCantConvert(tag, structType);
- }
-
- // Let's see if how everything contained converts
- ScopeStack stackScope(this);
- BitField fieldsSet;
- SLANG_RETURN_ON_FAIL(maybeConvertCurrentContained(structType, in, &fieldsSet));
-
- // If there were no fields set
- if (fieldsSet == 0)
- {
- // And it's the same major type, and is at least as big a the current struct
- // We can just use as is
- if (StructTagUtil::areSameMajorType(tag, structType->m_tag) && base->structSize >= structType->m_sizeInBytes)
- {
- out = (void*)in;
- return SLANG_OK;
- }
- }
-
- // Okay we will need to allocate and copy
- void* dst = allocateAndCopy(structType, in);
-
- // Copy anything converted
- setContainedConverted(structType, stackScope, fieldsSet, dst);
-
- out = dst;
- return SLANG_OK;
-}
-
-} // namespace Slang
diff --git a/source/compiler-core/slang-struct-tag-converter.h b/source/compiler-core/slang-struct-tag-converter.h
deleted file mode 100644
index 5f0ec7087..000000000
--- a/source/compiler-core/slang-struct-tag-converter.h
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef SLANG_COMPILER_CORE_STRUCT_TAG_CONVERTER_H
-#define SLANG_COMPILER_CORE_STRUCT_TAG_CONVERTER_H
-
-#include "slang-struct-tag-system.h"
-#include "slang-diagnostic-sink.h"
-
-namespace Slang {
-
-class StructTagConverterBase
-{
-public:
- typedef StructTagConverterBase ThisType;
- typedef StructTagField Field;
- typedef Field::Type FieldType;
-
- virtual SlangResult convertCurrent(const void* in, void*& out) = 0;
- virtual SlangResult convertCurrentArray(const void* in, Index count, void*& out) = 0;
- virtual SlangResult convertCurrentPtrArray(const void*const* in, Index count, void**& out) = 0;
-
- SlangResult convertCurrent(slang::StructTag tag, const void* in, void*& out);
-
- /// Allocates of type and copies src to dst
- void* allocateAndCopy(const StructTagType* type, const void* src);
- /// Copy from src to dst, zero extending or shrinking however structType requires
- void copy(const StructTagType* structType, const void* src, void* dst);
-
- /// Returns true if it's possible to convert tag to current type
- bool canConvertToCurrent(slang::StructTag tag, StructTagType* type) const;
-
- template <typename T>
- const T* convertToCurrent(const void* in)
- {
- void* dst;
- return SLANG_SUCCEEDED(convertCurrent(T::kStructTag, in, dst)) ? (const T*)dst : nullptr;
- }
-
- template <typename T>
- SlangResult convertToCurrent(const void* in, const T** out)
- {
- void* dst;
- SLANG_RETURN_ON_FAIL(convertCurrent(T::kStructTag, in, dst));
- *out = (const T*)dst;
- return SLANG_OK;
- }
-
- /// Convert a single field which is an array type
- SlangResult convertArrayField(const FieldType type, const void* in, Index count, void*& out);
-
- /// Ctor. Arena and sink can be optionally set (pass nullptr if not wanted)
- StructTagConverterBase(StructTagSystem* system, MemoryArena* arena, DiagnosticSink* sink) :
- m_system(system),
- m_arena(arena),
- m_sink(sink)
- {
- }
-
-protected:
- StructTagConverterBase(const ThisType& rhs) = delete;
- void operator=(const ThisType& rhs) = delete;
-
- SlangResult _requireArena();
- SlangResult _diagnoseCantConvert(slang::StructTag tag, StructTagType* type);
- SlangResult _diagnoseUnknownType(slang::StructTag tag);
- SlangResult _diagnoseDifferentTypes(slang::StructTag tagA, slang::StructTag tagB);
-
- StructTagSystem* m_system;
- DiagnosticSink* m_sink;
- MemoryArena* m_arena;
-};
-
-class CopyStructTagConverter : public StructTagConverterBase
-{
-public:
- typedef StructTagConverterBase Super;
-
- // StructTagConverterBase
- virtual SlangResult convertCurrent(const void* in, void*& out) SLANG_OVERRIDE;
- virtual SlangResult convertCurrentArray(const void* in, Index count, void*& out) SLANG_OVERRIDE;
- virtual SlangResult convertCurrentPtrArray(const void*const* in, Index count, void**& out) SLANG_OVERRIDE;
-
- /// Convert the items contained in inout
- SlangResult convertCurrentContained(const StructTagType* structType, void* inout);
-
- CopyStructTagConverter(StructTagSystem* system, MemoryArena* arena, DiagnosticSink* sink) :
- Super(system, arena, sink)
- {
- // If we are going to copy -> we have to have an arena
- SLANG_ASSERT(arena);
- }
-};
-
-class LazyStructTagConverter : public StructTagConverterBase
-{
-public:
- typedef StructTagConverterBase Super;
-
- typedef uint32_t BitField;
-
- struct ScopeStack
- {
- ScopeStack(LazyStructTagConverter* converter):
- m_stack(converter->m_convertStack),
- m_startIndex(converter->m_convertStack.getCount())
- {
- }
- ~ScopeStack()
- {
- m_stack.setCount(m_startIndex);
- }
-
- Index getStartIndex() const { return m_startIndex; }
- operator Index() const { return m_startIndex; }
-
- protected:
- List<void*>& m_stack;
- Index m_startIndex;
- };
-
- // StructTagConverterBase
- virtual SlangResult convertCurrent(const void* in, void*& out) SLANG_OVERRIDE;
- virtual SlangResult convertCurrentArray(const void* in, Index count, void*& out) SLANG_OVERRIDE;
- virtual SlangResult convertCurrentPtrArray(const void*const* in, Index count, void**& out) SLANG_OVERRIDE;
-
- /// Convert all the referenced items starting at in.
- /// Items that are converted are stored on the m_convertStack.
- /// The BitField records a bit for every 'field' (where exts is the 0 field) where there is something converted.
- /// If the BitField has no bits set -> then nothing was converted and can be used as is.
- /// To write the converted data, use setContainedConverted.
- ///
- /// NOTE! This method adds items to the end of the m_convertStack, it is the responsibility of the caller to clean up
- /// This can be made simpler by just using ScopeStack.
- SlangResult maybeConvertCurrentContained(const StructTagType* structType, const void* in, BitField* outFieldsSet);
-
- /// For every fieldSet bit set, copys over the data held in the m_convertStack (indexed from stackStartIndex).
- void setContainedConverted(const StructTagType* structType, Index stackIndex, BitField fieldsSet, void* dst);
-
- /// Ctor. The sink and arena are optional. If the arena isn't set then it is not possible to copy convert anything
- /// and so if a copy convert is required, it will fail.
- /// The sink is optional - if it's set failures will occur silently.
- LazyStructTagConverter(StructTagSystem* system, MemoryArena* arena, DiagnosticSink* sink):
- Super(system, arena, sink)
- {
- }
-
-protected:
-
- /// Used to hold pointers to things that have been converted.
- List<void*> m_convertStack;
-};
-
-} // namespace Slang
-
-#endif // SLANG_COMPILER_CORE_STRUCT_TAG_CONVERTER_H
diff --git a/source/compiler-core/slang-struct-tag-system.cpp b/source/compiler-core/slang-struct-tag-system.cpp
deleted file mode 100644
index 405d17360..000000000
--- a/source/compiler-core/slang-struct-tag-system.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include "slang-struct-tag-system.h"
-
-
-namespace Slang {
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructTagCategoryInfo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-StructTagCategoryInfo::~StructTagCategoryInfo()
-{
- for (auto type : m_types)
- {
- if (type)
- {
- type->~StructTagType();
- }
- }
-
-}
-
-void StructTagCategoryInfo::addType(StructTagType* type)
-{
- auto typeIndex = StructTagUtil::getTypeIndex(type->m_tag);
-
- if (typeIndex >= m_types.getCount())
- {
- Index prevCount = m_types.getCount();
- m_types.setCount(typeIndex + 1);
- // Zero it
- ::memset(m_types.getBuffer() + prevCount, 0, sizeof(StructTagType*) * (m_types.getCount() - prevCount));
- }
-
- SLANG_ASSERT(m_types[typeIndex] == nullptr);
- m_types[typeIndex] = type;
-}
-
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StructTagSystem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-StructTagSystem::~StructTagSystem()
-{
- for (auto category : m_categories)
- {
- if (category)
- {
- category->~StructTagCategoryInfo();
- }
- }
-}
-
-StructTagCategoryInfo* StructTagSystem::getCategoryInfo(slang::StructTagCategory category)
-{
- const Index index = Index(category);
- return (index < m_categories.getCount()) ? m_categories[index] : nullptr;
-}
-
-StructTagCategoryInfo* StructTagSystem::addCategoryInfo(slang::StructTagCategory category, const String& name)
-{
- StructTagCategoryInfo* categoryInfo = new (m_arena.allocateAligned(sizeof(StructTagCategoryInfo), SLANG_ALIGN_OF(StructTagCategoryInfo))) StructTagCategoryInfo(category, name);
-
- const Index index = Index(category);
-
- if (index >= m_categories.getCount())
- {
- m_categories.setCount(index + 1);
- }
- m_categories[index] = categoryInfo;
- return categoryInfo;
-}
-
-StructTagType* StructTagSystem::addType(slang::StructTag tag, const String& name, size_t sizeInBytes)
-{
- auto category = StructTagUtil::getCategory(tag);
- auto categoryInfo = getCategoryInfo(category);
-
- auto structType = new (m_arena.allocate<StructTagType>()) StructTagType(tag, name, sizeInBytes);
- categoryInfo->addType(structType);
-
- return structType;
-}
-
-StructTagType* StructTagSystem::getType(slang::StructTag tag)
-{
- const auto category = StructTagUtil::getCategory(tag);
- auto categoryInfo = getCategoryInfo(category);
- if (categoryInfo)
- {
- auto typeIndex = StructTagUtil::getTypeIndex(tag);
- return categoryInfo->getType(typeIndex);
- }
-
- return nullptr;
-}
-
-void StructTagSystem::appendName(slang::StructTag tag, StringBuilder& out)
-{
- auto info = StructTagUtil::getTypeInfo(tag);
-
- auto categoryInfo = getCategoryInfo(info.category);
- if (categoryInfo)
- {
- out << categoryInfo->m_name;
- }
- else
- {
- out << Index(info.category);
- }
-
- out << "::";
-
- auto type = categoryInfo->getType(info.typeIndex);
-
- if (type)
- {
- out << type->m_name;
- }
- else
- {
- out << "~" << Index(info.typeIndex) << "~";
- }
-
- out << "_";
- out << Index(info.majorVersion);
- out << ".";
- out << Index(info.minorVersion);
-}
-
-} // namespace Slang
diff --git a/source/compiler-core/slang-struct-tag-system.h b/source/compiler-core/slang-struct-tag-system.h
deleted file mode 100644
index 20581cec7..000000000
--- a/source/compiler-core/slang-struct-tag-system.h
+++ /dev/null
@@ -1,259 +0,0 @@
-#ifndef SLANG_COMPILER_CORE_STRUCT_TAG_SYSTEM_H
-#define SLANG_COMPILER_CORE_STRUCT_TAG_SYSTEM_H
-
-#include "../../slang.h"
-
-#include "../../slang-com-helper.h"
-#include "../../slang-com-ptr.h"
-
-#include "../core/slang-smart-pointer.h"
-
-#include "../core/slang-dictionary.h"
-#include "../core/slang-semantic-version.h"
-#include "../core/slang-memory-arena.h"
-
-namespace Slang {
-
-struct StructTagUtil
-{
- struct TypeInfo
- {
- slang::StructTagKind kind; ///< The kind
- slang::StructTagCategory category; ///< The category
- uint8_t typeIndex; ///< Type index for the category type
- uint8_t majorVersion; ///< The major semantic version
- uint8_t minorVersion; ///< The minor semantic version
- };
-
- /// True if it's a primary struct
- static bool isPrimary(slang::StructTag tag) { return (slang::StructTagInt(tag) & slang::kStructTagPrimaryMask) != 0; }
- /// True if it's an extension
- static bool isExtension(slang::StructTag tag) { return !isPrimary(tag); }
-
- inline static TypeInfo getTypeInfo(slang::StructTag tag);
-
- /// Get the category and type from the value
- static slang::StructTagInt getCategoryTypeIndex(slang::StructTag tag) { return (slang::StructTagInt(tag) & slang::kStructTagCategoryTypeIndexMask) >> slang::kStructTagCategoryTypeIndexShift; }
-
- /// Get the type index
- static Index getTypeIndex(slang::StructTag tag) { return Index((slang::StructTagInt(tag) & slang::kStructTagTypeIndexMask) >> slang::kStructTagTypeIndexShift); }
-
- /// Get the category
- static slang::StructTagCategory getCategory(slang::StructTag tag) { return slang::StructTagCategory((slang::StructTagInt(tag) & slang::kStructTagCategoryMask) >> slang::kStructTagCategoryShift); }
-
- /// They are the same type and have same major version
- static bool areSameMajorType(slang::StructTag a, slang::StructTag b)
- {
- const auto typeMask = slang::StructTagInt(slang::kStructTagCategoryTypeMajorMask);
- return ((slang::StructTagInt(a) ^ slang::StructTagInt(b)) & typeMask) == 0;
- }
-
- /// This will *only* determine if *just* this type is compatible for read and not if it contains other types (say in the form of extensions)
- static bool isReadCompatible(slang::StructTag inTag, slang::StructTag inCurrentTag)
- {
- // Uniquely identifies the 'type'.
- const auto typeMask = slang::StructTagInt(slang::kStructTagCategoryTypeMajorMask);
- const auto minorMask = slang::StructTagInt(slang::kStructTagMinorMask);
-
- const auto tag = slang::StructTagInt(inTag);
- const auto currentTag = slang::StructTagInt(inCurrentTag);
-
- // If they are the same type, and the input types minor is greater than equal to current minor we can accept for read (singly)
- return ((tag ^ currentTag) & typeMask) == 0 && (tag & minorMask) >= (currentTag & minorMask);
- }
-};
-
-/* static */ inline StructTagUtil::TypeInfo StructTagUtil::getTypeInfo(slang::StructTag tag)
-{
- const auto intTag = slang::StructTagInt(tag);
-
- TypeInfo info;
- info.kind = (intTag & slang::kStructTagPrimaryMask) ? slang::StructTagKind::Primary : slang::StructTagKind::Extension;
- info.category = getCategory(tag);
- info.typeIndex = uint8_t(getTypeIndex(tag));
- info.majorVersion = uint8_t((intTag & slang::kStructTagMajorMask) >> slang::kStructTagMajorShift);
- info.minorVersion = uint8_t((intTag & slang::kStructTagMinorMask) >> slang::kStructTagMinorShift);
- return info;
-}
-
-/// We can have a 'field' that is made up of 2 elements, so we have two entries.
-/// If m_countType is Unknown, then the entry can be ignored
-struct StructTagField
-{
- enum class Type : uint8_t
- {
- Unknown,
- TaggedStruct,
- PtrTaggedStruct,
- PtrPtrTaggedStruct,
- I32,
- I64,
- };
-
- SLANG_FORCE_INLINE static bool isInRange(Type type, Type start, Type end) { return Index(type) >= Index(start) && Index(type) <= Index(end); }
-
- /// True if it's an integral
- static bool isIntegral(Type type) { return isInRange(type, Type::I32, Type::I64); }
- /// True if it's a pointer or pointer to a pointer
- static bool isPtrLike(Type type) { return isInRange(type, Type::PtrTaggedStruct, Type::PtrPtrTaggedStruct); }
-
- Type m_type;
- Type m_countType;
- uint16_t m_offset;
- uint16_t m_countOffset;
-};
-
-struct StructTagType
-{
-public:
- typedef StructTagField Field;
-
- StructTagType(slang::StructTag tag, const String& name, size_t sizeInBytes):
- m_tag(tag),
- m_name(name),
- m_sizeInBytes(slang::StructSize(sizeInBytes))
- {
- }
-
- slang::StructTag m_tag; ///< The type/current version
- String m_name; ///< The name of the type
- slang::StructSize m_sizeInBytes; ///< The size of this version in bytes
-
- List<Field> m_fields; ///< Fields that need to be followed
-};
-
-namespace StructTagTypeTraits
-{
- typedef StructTagField Field;
- typedef Field::Type Type;
-
- // Helper that works out what a pointer to the inner type is.
- SLANG_FORCE_INLINE Type getPtrType(Type innerType)
- {
- switch (innerType)
- {
- case Type::TaggedStruct: return Type::PtrTaggedStruct;
- case Type::PtrTaggedStruct: return Type::PtrPtrTaggedStruct;
- default: return Type::Unknown;
- }
- }
-
- template <typename T, typename F>
- SLANG_FORCE_INLINE uint16_t getOffset(T* obj, const F* f)
- {
- return uint16_t((const char*)f - (const char*)obj);
- }
-
- // Use `substitution failure is not an error` (SFINAE) to detect tagged struct types
- template <typename T>
- struct IsTaggedStruct
- {
- typedef int32_t True;
- typedef int8_t False;
-
- template <typename C>
- static True check(typename C::Tag*);
- template <typename>
- static False check(...);
-
- // Is != 0 if it is a TaggedStruct type
- enum { kValue = int(sizeof(check<T>(nullptr)) == sizeof(True)) };
- };
-
- template <typename T>
- struct Impl { static Type getType() { return IsTaggedStruct<T>::kValue ? Type::TaggedStruct : Type::Unknown; } };
-
- // Doesn't currently handle fixed arrays, but could be added quite easily, with say a byte for the fixed size.
-
- // Integer types
- // We won't bother with sign for now
- template <> struct Impl<uint64_t> { static Type getType() { return Type::I64; } };
- template <> struct Impl<int64_t> { static Type getType() { return Type::I64; } };
- template <> struct Impl<uint32_t> { static Type getType() { return Type::I32; } };
- template <> struct Impl<int32_t> { static Type getType() { return Type::I32; } };
-
- // StructTag is used to indicate it can be any 'tagged struct type'
- template <> struct Impl<slang::StructTag> { static Type getType() { return Type::TaggedStruct; } };
-
- // Pointer
- template <typename T> struct Impl<T*> { static Type getType() { return getPtrType(Impl<T>::getType()); } };
-
- /// f1 should hold the count
- template <typename T, typename F0, typename F1>
- Field getFieldWithCount(const T* obj, const F0* ptr, const F1* count)
- {
- Field field;
- field.m_type = Impl<F0>::getType();
- field.m_countType = Impl<F1>::getType();
- field.m_offset = getOffset(obj, ptr);
- field.m_countOffset = getOffset(obj, count);
-
- SLANG_ASSERT(StructTagField::isPtrLike(field.m_type));
- SLANG_ASSERT(StructTagField::isIntegral(field.m_countType));
-
- return field;
- }
-}
-
-class StructTagCategoryInfo
-{
-public:
-
- /// Add a type. Will replace a type if there is already one setup for the m_Type
- void addType(StructTagType* type);
-
- /// Get a type
- StructTagType* getType(Index typeIndex) const { return typeIndex < m_types.getCount() ? m_types[typeIndex] : nullptr; }
-
- StructTagCategoryInfo(slang::StructTagCategory category, const String& name) :
- m_category(category),
- m_name(name)
- {
- }
- ~StructTagCategoryInfo();
-
- slang::StructTagCategory m_category; ///< The category type
- String m_name; ///< The name
-
- // All the types in this category
- List<StructTagType*> m_types;
-};
-
-/* Holds the information about TaggedStruct types. Use the StructTagConverter to actually convert to conforming
-types. */
-class StructTagSystem : public RefObject
-{
-public:
-
- /// Add a category
- StructTagCategoryInfo* addCategoryInfo(slang::StructTagCategory category, const String& name);
- StructTagCategoryInfo* getCategoryInfo(slang::StructTagCategory category);
-
- /// Get struct type
- StructTagType* getType(slang::StructTag tag);
-
- /// Add the struct type
- StructTagType* addType(slang::StructTag tag, const String& name, size_t sizeInBytes);
-
- void appendName(slang::StructTag tag, StringBuilder& out);
- String getName(slang::StructTag tag) { StringBuilder buf; appendName(tag, buf); return buf.ProduceString(); }
-
- StructTagSystem():
- m_arena(1024)
- {
- }
-
- ~StructTagSystem();
-
-protected:
-
- /// Arena stores all of the types
- MemoryArena m_arena;
-
- /// All of the categories
- List<StructTagCategoryInfo*> m_categories;
-};
-
-} // namespace Slang
-
-#endif // SLANG_COMPILER_CORE_STRUCT_TAG_SYSTEM_H
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index e6684108b..a933716a8 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -11,8 +11,6 @@
#include "../compiler-core/slang-include-system.h"
#include "../compiler-core/slang-command-line-args.h"
-#include "../compiler-core/slang-struct-tag-system.h"
-
#include "../core/slang-std-writers.h"
#include "../../slang-com-ptr.h"
@@ -2320,9 +2318,6 @@ namespace Slang
/// Get the built in linkage -> handy to get the stdlibs from
Linkage* getBuiltinLinkage() const { return m_builtinLinkage; }
- /// Get the Abi system used for managing binary compatibility of interface types (outside of COM mechanisms)
- StructTagSystem* getStructTagSystem() const { return m_structTagSystem; }
-
void init();
void addBuiltinSource(
@@ -2348,8 +2343,6 @@ namespace Slang
/// Linkage used for all built-in (stdlib) code.
RefPtr<Linkage> m_builtinLinkage;
- RefPtr<StructTagSystem> m_structTagSystem;
-
String m_downstreamCompilerPaths[int(PassThroughMode::CountOf)]; ///< Paths for each pass through
String m_languagePreludes[int(SourceLanguage::CountOf)]; ///< Prelude for each source language
PassThroughMode m_defaultDownstreamCompilers[int(SourceLanguage::CountOf)];
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 8d82ca1b7..acc4b6f77 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -23,7 +23,6 @@
#include "../core/slang-writer.h"
#include "../compiler-core/slang-source-loc.h"
-#include "../compiler-core/slang-struct-tag-converter.h"
#include "slang-ast-dump.h"
@@ -115,31 +114,6 @@ const char* getBuildTagString()
return SLANG_TAG_VERSION;
}
-static RefPtr<StructTagSystem> _createStructTagSystem()
-{
- RefPtr<StructTagSystem> system = new StructTagSystem;
-
- {
-#define SLANG_STRUCT_TAG_ADD_CATEGORY(x) system->addCategoryInfo(slang::StructTagCategory::x, #x);
- SLANG_STRUCT_TAG_CATEGORIES(SLANG_STRUCT_TAG_ADD_CATEGORY)
- }
-
- {
-#define SLANG_STRUCT_TAG_ADD_TYPE(X) system->addType(slang::X::kStructTag, "slang::" #X, sizeof(slang::X));
-SLANG_TAGGED_STRUCTS(SLANG_STRUCT_TAG_ADD_TYPE)
-
- // Add field that references more tagged structs
- {
- slang::SessionDesc desc;
- auto field = StructTagTypeTraits::getFieldWithCount(&desc, &desc.targets, &desc.targetCount);
-
- auto type = system->getType(slang::SessionDesc::kStructTag);
- type->m_fields.add(field);
- }
- }
-
- return system;
-}
void Session::init()
{
@@ -158,8 +132,6 @@ void Session::init()
m_sharedASTBuilder = new SharedASTBuilder;
m_sharedASTBuilder->init(this);
- m_structTagSystem = _createStructTagSystem();
-
// Use to create a ASTBuilder
RefPtr<ASTBuilder> builtinAstBuilder(new ASTBuilder(m_sharedASTBuilder, "m_builtInLinkage::m_astBuilder"));
@@ -467,45 +439,42 @@ ISlangUnknown* Session::getInterface(const Guid& guid)
}
SLANG_NO_THROW SlangResult SLANG_MCALL Session::createSession(
- slang::SessionDesc const& inDesc,
+ slang::SessionDesc const& desc,
slang::ISession** outSession)
{
- MemoryArena arena(1024);
-
- LazyStructTagConverter converter(getStructTagSystem(), &arena, nullptr);
-
- const slang::SessionDesc* desc = nullptr;
- SLANG_RETURN_ON_FAIL(converter.convertToCurrent(&inDesc, &desc));
-
RefPtr<ASTBuilder> astBuilder(new ASTBuilder(m_sharedASTBuilder, "Session::astBuilder"));
RefPtr<Linkage> linkage = new Linkage(this, astBuilder, getBuiltinLinkage());
+ Int targetCount = desc.targetCount;
+ const uint8_t* targetDescPtr = reinterpret_cast<const uint8_t*>(desc.targets);
+ for (Int ii = 0; ii < targetCount; ++ii)
{
- const Index targetCount = Index(desc->targetCount);
- for(Index ii = 0; ii < targetCount; ++ii)
- {
- const auto& targetDesc = desc->targets[ii];
- linkage->addTarget(targetDesc);
- }
+ slang::TargetDesc targetDesc;
+ // Copy the size field first.
+ memcpy(&targetDesc.structureSize, targetDescPtr, sizeof(size_t));
+ // Copy the entire desc structure.
+ memcpy(&targetDesc, targetDescPtr, targetDesc.structureSize);
+ linkage->addTarget(targetDesc);
+ targetDescPtr += targetDesc.structureSize;
}
- if(desc->flags & slang::kSessionFlag_FalcorCustomSharedKeywordSemantics)
+ if(desc.flags & slang::kSessionFlag_FalcorCustomSharedKeywordSemantics)
{
linkage->m_useFalcorCustomSharedKeywordSemantics = true;
}
- linkage->setMatrixLayoutMode(desc->defaultMatrixLayoutMode);
+ linkage->setMatrixLayoutMode(desc.defaultMatrixLayoutMode);
- Int searchPathCount = desc->searchPathCount;
+ Int searchPathCount = desc.searchPathCount;
for(Int ii = 0; ii < searchPathCount; ++ii)
{
- linkage->addSearchPath(desc->searchPaths[ii]);
+ linkage->addSearchPath(desc.searchPaths[ii]);
}
- Int macroCount = desc->preprocessorMacroCount;
+ Int macroCount = desc.preprocessorMacroCount;
for(Int ii = 0; ii < macroCount; ++ii)
{
- auto& macro = desc->preprocessorMacros[ii];
+ auto& macro = desc.preprocessorMacros[ii];
linkage->addPreprocessorDefine(macro.name, macro.value);
}
diff --git a/tools/slang-test/unit-test-struct-tag.cpp b/tools/slang-test/unit-test-struct-tag.cpp
deleted file mode 100644
index cc22d9b1d..000000000
--- a/tools/slang-test/unit-test-struct-tag.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-// unit-test-struct-tag.cpp
-
-#include "../../source/core/slang-memory-arena.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "test-context.h"
-
-#include "../../source/core/slang-random-generator.h"
-#include "../../source/core/slang-list.h"
-
-#include "../../source/compiler-core/slang-struct-tag-system.h"
-#include "../../source/compiler-core/slang-struct-tag-converter.h"
-
-using namespace Slang;
-
-namespace { // anonymous
-
-#define TAGGED_STRUCTS(x) \
- x(A) \
- x(B) \
- x(ExtensionA) \
- x(Desc)
-
-enum class TaggedStruct
-{
- TAGGED_STRUCTS(SLANG_STRUCT_TAG_ENUM)
-};
-
-#define PRIMARY_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_PRIMARY_TAGGED_STRUCT_IMPL(TYPE_NAME##MAJOR##_##MINOR, slang::StructTagCategory::Core, TaggedStruct::TYPE_NAME, MAJOR, MINOR)
-#define EXTENSION_TAGGED_STRUCT(TYPE_NAME, MAJOR, MINOR) SLANG_EXTENSION_TAGGED_STRUCT_IMPL(TYPE_NAME##MAJOR##_##MINOR, slang::StructTagCategory::Core, TaggedStruct::TYPE_NAME, MAJOR, MINOR)
-
-struct A0_0
-{
- PRIMARY_TAGGED_STRUCT(A, 0, 0)
-
- int a = 10;
-};
-
-struct A0_1
-{
- PRIMARY_TAGGED_STRUCT(A, 0, 1)
-
- int a = 10;
- int b = 20;
-};
-
-struct B0_0
-{
- PRIMARY_TAGGED_STRUCT(B, 0, 0)
-
- float v = -1.0f;
-};
-
-struct B0_1
-{
- PRIMARY_TAGGED_STRUCT(B, 0, 1)
-
- float v = -1.0f;
- float u = 20.0f;
-};
-
-struct A1_0
-{
- PRIMARY_TAGGED_STRUCT(A, 1, 0)
-};
-
-
-struct ExtensionA0_0
-{
- EXTENSION_TAGGED_STRUCT(ExtensionA, 0, 0)
-
- int b = 20;
-};
-
-// I guess a Desc could be implemented as 'Primary' or 'Extension' with what we have, but probably makes more sense
-// for 'Desc' like things to be primary
-
-struct Desc0_0
-{
- EXTENSION_TAGGED_STRUCT(Desc, 0, 0)
- int a = 1;
-};
-
-struct Desc0_1
-{
- EXTENSION_TAGGED_STRUCT(Desc, 0, 1)
- int a = 1;
- int b = 2;
-};
-
-
-struct A0_2
-{
- PRIMARY_TAGGED_STRUCT(A, 0, 2)
-
- int a = 10;
- int b = 20;
-
- Desc0_0* descs = nullptr;
- Index descsCount = 0;
-};
-
-} // anonymous
-
-static RefPtr<StructTagSystem> _createSystem()
-{
- RefPtr<StructTagSystem> system = new StructTagSystem;
-
- {
-#define SLANG_STRUCT_TAG_ADD_CATEGORY(x) system->addCategoryInfo(slang::StructTagCategory::x, #x);
- SLANG_STRUCT_TAG_CATEGORIES(SLANG_STRUCT_TAG_ADD_CATEGORY)
- }
-
- return system;
-}
-
-static void structTagUnitTest()
-{
- SourceManager sourceManager;
- sourceManager.initialize(nullptr, nullptr);
-
- DiagnosticSink sink;
- sink.init(&sourceManager, nullptr);
-
- {
- StructTagUtil::TypeInfo info = StructTagUtil::getTypeInfo(A0_1::kStructTag);
-
- SLANG_CHECK(info.kind == slang::StructTagKind::Primary);
- SLANG_CHECK(info.category == slang::StructTagCategory::Core);
- SLANG_CHECK(info.majorVersion == 0);
- SLANG_CHECK(info.minorVersion == 1);
- }
-
- {
- StructTagUtil::TypeInfo info = StructTagUtil::getTypeInfo(ExtensionA0_0::kStructTag);
-
- SLANG_CHECK(info.kind == slang::StructTagKind::Extension);
- SLANG_CHECK(info.category == slang::StructTagCategory::Core);
- SLANG_CHECK(info.majorVersion == 0);
- SLANG_CHECK(info.minorVersion == 0);
- }
-
- {
- // Set up the system with the versions
- auto system = _createSystem();
-
- system->addType(B0_1::kStructTag, "B", sizeof(B0_1));
- system->addType(A0_1::kStructTag, "A", sizeof(A0_1));
- system->addType(ExtensionA0_0::kStructTag, "ExtensionA", sizeof(ExtensionA0_0));
-
- {
- //The null operation means we are converting everything that is current (as defined by the system)
-
- A0_1 a;
- ExtensionA0_0 extA;
- const slang::StructTag* exts[] = { &extA.structTag };
- a.exts = exts;
- a.extsCount = SLANG_COUNT_OF(exts);
-
-
- LazyStructTagConverter converter(system, nullptr, nullptr);
-
- auto dstA = converter.convertToCurrent<A0_1>(&a);
-
- // We shouldn't have to convert anything, so we should be done
- SLANG_CHECK(dstA == &a);
- }
-
- {
- A0_0 a;
- ExtensionA0_0 extA;
- const slang::StructTag* exts[] = { &extA.structTag };
- a.exts = exts;
- a.extsCount = SLANG_COUNT_OF(exts);
-
-
- // Actually do a conversion from past
- MemoryArena arena(1024);
- LazyStructTagConverter converter(system, &arena, nullptr);
-
- auto dstA = converter.convertToCurrent<A0_1>(&a);
-
- SLANG_CHECK(dstA != nullptr);
- SLANG_CHECK(dstA->a == 10 && dstA->b == 0);
-
- SLANG_CHECK(dstA->extsCount == 1);
- SLANG_CHECK(((ExtensionA0_0*)dstA->exts[0])->b == 20);
- }
- }
-
- // Let's try going from the future backwards
- {
- // Set up the system with the versions
- auto system = _createSystem();
-
- system->addType(B0_1::kStructTag, "B", sizeof(B0_1));
- system->addType(A0_2::kStructTag, "A", sizeof(A0_2));
- system->addType(ExtensionA0_0::kStructTag, "ExtensionA", sizeof(ExtensionA0_0));
- system->addType(Desc0_0::kStructTag, "Desc", sizeof(Desc0_0));
-
- // Add the fields
- {
- auto type = system->getType(A0_2::kStructTag);
- A0_2 a;
- auto field = StructTagTypeTraits::getFieldWithCount(&a, &a.descs, &a.descsCount);
- type->m_fields.add(field);
- }
-
- //
-
- A0_2 a;
- Desc0_1 descs[2];
- descs[0].a = 27;
- descs[1].a = -1;
-
- a.descs = (Desc0_0*)descs;
- a.descsCount = SLANG_COUNT_OF(descs);
-
- // Actually do a conversion from future
- MemoryArena arena(1024);
- LazyStructTagConverter converter(system, &arena, nullptr);
-
- auto dstA = converter.convertToCurrent<A0_2>(&a);
-
- SLANG_CHECK(dstA->descsCount == a.descsCount);
-
- SLANG_CHECK(dstA->descs[0].a == 27 && dstA->descs[1].a == -1);
- }
-
- // Lets try some invalid conversions
-
- {
- // Set up the system with the versions
- auto system = _createSystem();
-
- system->addType(B0_1::kStructTag, "B", sizeof(B0_1));
- system->addType(A0_2::kStructTag, "A", sizeof(A0_2));
- system->addType(ExtensionA0_0::kStructTag, "ExtensionA", sizeof(ExtensionA0_0));
- system->addType(Desc0_0::kStructTag, "Desc", sizeof(Desc0_0));
-
- A1_0 a;
-
- MemoryArena arena(1024);
- LazyStructTagConverter converter(system, &arena, &sink);
-
- void* dst;
- SLANG_CHECK(SLANG_FAILED(converter.convertCurrent(&a, dst)));
-
- }
-
-}
-
-SLANG_UNIT_TEST("StructTag", structTagUnitTest);