summaryrefslogtreecommitdiffstats
path: root/source
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 /source
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.
Diffstat (limited to 'source')
-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
7 files changed, 17 insertions, 1136 deletions
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);
}