diff options
| author | Ronan <ro.cailleau@gmail.com> | 2025-09-17 14:46:27 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-17 12:46:27 +0000 |
| commit | b5078d12127f4ab348b8d6d4c4e8139ba7bfb47f (patch) | |
| tree | 01444cbb7cf9ab7b28b08b9b842fdcb3f9a72a84 | |
| parent | 64d23f2a56d9bd064557ae02a4f8a9d365cd9d60 (diff) | |
Added __magic_enum (#8436)
Fixes #8406 (and #8410).
`AddressSpace`, `MemoryScope` and `AccessQualifier` are no longer
`BaseType`.
I added a new `__magic_enum` (very similar to `__magic_type`) syntax to
be able to easily create values or these enums from the compiler. (I
don't know if it was the right way to do it, but it works and the
changes are small enough?).
I had a weird bug: `tests/language-feature/capability/address-of.slang`
was failing in `IRBuilder::_findOrEmitConstant(IRConstant& keyInst)`.
When needing a new `u64(0)`, it did not find it in the `ConstantMap`
first, but then failed to add it right after because it already existed
in the map! But this was triggered by `IRPtrType*
IRBuilder::getPtrType(IROp op, IRType* valueType, AccessQualifier
accessQualifier, AddressSpace addressSpace)`, which is a strange
coincidence... but I could not find the issue in what I did. I ended up
bumping unordered_dense, and it solved the issue (so there was a bug in
there).
| m--------- | external/unordered_dense | 0 | ||||
| -rw-r--r-- | source/slang/core.meta.slang | 15 | ||||
| -rw-r--r-- | source/slang/slang-ast-builder.cpp | 18 | ||||
| -rw-r--r-- | source/slang/slang-ast-builder.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ast-val.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-base-type-info.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-mangle.cpp | 9 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 32 | ||||
| -rw-r--r-- | source/slang/slang-type-system-shared.h | 3 |
9 files changed, 54 insertions, 36 deletions
diff --git a/external/unordered_dense b/external/unordered_dense -Subproject fd80dad6285286db5be6d2588cc7ddb624db7e5 +Subproject 73f3cbb237e84d483afafc743f1f14ec53e1231 diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 5d2a80c29..5c4a35be2 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -1278,18 +1278,16 @@ struct __none_t { }; -// @hidden: this type is a BaseType since we want it to work with -// `registerBuiltinDecl` -__builtin_type($((int)BaseType::AddressSpace)) +/// @category misc_types +__magic_enum(AddressSpace) enum AddressSpace : uint64_t { Device = $((uint64_t)AddressSpace::UserPointer), GroupShared = $((uint64_t)AddressSpace::GroupShared), }; -// @hidden: this type is a BaseType since we want it to work with -// `registerBuiltinDecl` -__builtin_type($((int)BaseType::MemoryScope)) +/// @category misc_types +__magic_enum(MemoryScope) enum MemoryScope : int32_t { CrossDevice = $((int32_t)MemoryScope::CrossDevice), @@ -1300,9 +1298,8 @@ enum MemoryScope : int32_t QueueFamily = $((int32_t)MemoryScope::QueueFamily), } -// @hidden: this type is a BaseType since we want it to work with -// `registerBuiltinDecl` -__builtin_type($((int)BaseType::AccessQualifier)) +/// @category misc_types +__magic_enum(AccessQualifier) enum Access : uint64_t { ReadWrite = $((uint64_t)AccessQualifier::ReadWrite), diff --git a/source/slang/slang-ast-builder.cpp b/source/slang/slang-ast-builder.cpp index 5da4e9521..a88db3155 100644 --- a/source/slang/slang-ast-builder.cpp +++ b/source/slang/slang-ast-builder.cpp @@ -461,6 +461,18 @@ Type* ASTBuilder::getSpecializedBuiltinType(ArrayView<Val*> genericArgs, const c return rsType; } +Type* ASTBuilder::getMagicEnumType(const char* magicEnumName) +{ + auto& cache = getSharedASTBuilder()->m_magicEnumTypes; + Type* res = nullptr; + if (!cache.tryGetValue(magicEnumName, res)) + { + res = getSpecializedBuiltinType({}, magicEnumName); + cache.add(magicEnumName, res); + } + return res; +} + PtrType* ASTBuilder::getPtrType(Type* valueType, Val* accessQualifier, Val* addrSpace) { return dynamicCast<PtrType>(getPtrType(valueType, accessQualifier, addrSpace, "PtrType")); @@ -545,10 +557,12 @@ PtrTypeBase* ASTBuilder::getPtrType( AddressSpace addrSpace, char const* ptrTypeName) { + Type* typeOfAccessQualifier = getMagicEnumType("AccessQualifier"); + Type* typeOfAddressSpace = getMagicEnumType("AddressSpace"); return as<PtrTypeBase>(getPtrType( valueType, - getIntVal(getBuiltinType(BaseType::AccessQualifier), (IntegerLiteralValue)accessQualifier), - getIntVal(getBuiltinType(BaseType::AddressSpace), (IntegerLiteralValue)addrSpace), + getIntVal(typeOfAccessQualifier, (IntegerLiteralValue)accessQualifier), + getIntVal(typeOfAddressSpace, (IntegerLiteralValue)addrSpace), ptrTypeName)); } diff --git a/source/slang/slang-ast-builder.h b/source/slang/slang-ast-builder.h index e71e2665f..72a3db4ab 100644 --- a/source/slang/slang-ast-builder.h +++ b/source/slang/slang-ast-builder.h @@ -109,6 +109,7 @@ protected: Type* m_noneType = nullptr; Type* m_diffInterfaceType = nullptr; Type* m_builtinTypes[Index(BaseType::CountOf)]; + Dictionary<String, Type*> m_magicEnumTypes; Dictionary<String, Decl*> m_magicDecls; Dictionary<BuiltinRequirementKind, Decl*> m_builtinRequirementDecls; @@ -512,6 +513,8 @@ public: Type* getSpecializedBuiltinType(Type* typeParam, const char* magicTypeName); Type* getSpecializedBuiltinType(ArrayView<Val*> genericArgs, const char* magicTypeName); + Type* getMagicEnumType(const char* magicEnumName); + Type* getDefaultLayoutType(); Type* getDefaultPushConstantLayoutType(); Type* getStd140LayoutType(); diff --git a/source/slang/slang-ast-val.cpp b/source/slang/slang-ast-val.cpp index 96f0a1682..43bd99f19 100644 --- a/source/slang/slang-ast-val.cpp +++ b/source/slang/slang-ast-val.cpp @@ -1435,10 +1435,6 @@ Val* TypeCastIntVal::tryFoldImpl( case BaseType::UInt8: resultValue = (uint8_t)resultValue; return true; - case BaseType::AddressSpace: - case BaseType::AccessQualifier: - case BaseType::MemoryScope: - return true; default: return false; } diff --git a/source/slang/slang-base-type-info.cpp b/source/slang/slang-base-type-info.cpp index 984437ca8..e4006cc38 100644 --- a/source/slang/slang-base-type-info.cpp +++ b/source/slang/slang-base-type-info.cpp @@ -84,12 +84,6 @@ namespace Slang return UnownedStringSlice::fromLiteral("intptr_t"); case BaseType::UIntPtr: return UnownedStringSlice::fromLiteral("uintptr_t"); - case BaseType::AddressSpace: - return UnownedStringSlice::fromLiteral("AddressSpace"); - case BaseType::MemoryScope: - return UnownedStringSlice::fromLiteral("MemoryScope"); - case BaseType::AccessQualifier: - return UnownedStringSlice::fromLiteral("Access"); default: { SLANG_ASSERT(!"Unknown basic type"); diff --git a/source/slang/slang-mangle.cpp b/source/slang/slang-mangle.cpp index 7a5665905..311725e08 100644 --- a/source/slang/slang-mangle.cpp +++ b/source/slang/slang-mangle.cpp @@ -191,15 +191,6 @@ void emitBaseType(ManglingContext* context, BaseType baseType) case BaseType::IntPtr: emitRaw(context, "ip"); break; - case BaseType::AddressSpace: - emitRaw(context, "as"); - break; - case BaseType::AccessQualifier: - emitRaw(context, "aq"); - break; - case BaseType::MemoryScope: - emitRaw(context, "mem"); - break; default: SLANG_UNEXPECTED("unimplemented case in base type mangling"); diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 5b6f30477..196b2efa8 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -9388,7 +9388,16 @@ static NodeBase* parseBuiltinRequirementModifier(Parser* parser, void* /*userDat return modifier; } -static NodeBase* parseMagicTypeModifier(Parser* parser, void* /*userData*/) +enum class MagicTypeModifierKind +{ + Type, + Enum, +}; + +static NodeBase* parseMagicTypeModifierImpl( + Parser* parser, + void* /*userData*/, + MagicTypeModifierKind kind) { MagicTypeModifier* modifier = parser->astBuilder->create<MagicTypeModifier>(); parser->ReadToken(TokenType::LParent); @@ -9398,8 +9407,14 @@ static NodeBase* parseMagicTypeModifier(Parser* parser, void* /*userData*/) modifier->tag = uint32_t(stringToInt(parser->ReadToken(TokenType::IntegerLiteral).getContent())); } - auto syntaxClass = parser->astBuilder->findSyntaxClass(getName(parser, modifier->magicName)); - if (syntaxClass) + + if (kind == MagicTypeModifierKind::Enum) + { + modifier->magicNodeType = getSyntaxClass<EnumTypeType>(); + } + else if ( + auto syntaxClass = + parser->astBuilder->findSyntaxClass(getName(parser, modifier->magicName))) { modifier->magicNodeType = syntaxClass; } @@ -9410,6 +9425,16 @@ static NodeBase* parseMagicTypeModifier(Parser* parser, void* /*userData*/) return modifier; } +static NodeBase* parseMagicTypeModifier(Parser* parser, void* userData) +{ + return parseMagicTypeModifierImpl(parser, userData, MagicTypeModifierKind::Type); +} + +static NodeBase* parseMagicEnumModifier(Parser* parser, void* userData) +{ + return parseMagicTypeModifierImpl(parser, userData, MagicTypeModifierKind::Enum); +} + static NodeBase* parseIntrinsicTypeModifier(Parser* parser, void* /*userData*/) { IntrinsicTypeModifier* modifier = parser->astBuilder->create<IntrinsicTypeModifier>(); @@ -9634,6 +9659,7 @@ static const SyntaxParseInfo g_parseSyntaxEntries[] = { _makeParseModifier("__builtin_requirement", parseBuiltinRequirementModifier), _makeParseModifier("__magic_type", parseMagicTypeModifier), + _makeParseModifier("__magic_enum", parseMagicEnumModifier), _makeParseModifier("__intrinsic_type", parseIntrinsicTypeModifier), _makeParseModifier("__implicit_conversion", parseImplicitConversionModifier), diff --git a/source/slang/slang-type-system-shared.h b/source/slang/slang-type-system-shared.h index 3390c3b80..aa9b07d89 100644 --- a/source/slang/slang-type-system-shared.h +++ b/source/slang/slang-type-system-shared.h @@ -23,9 +23,6 @@ namespace Slang X(IntPtr) \ X(UIntPtr) \ X(CountOfPrimitives) \ - X(AddressSpace) \ - X(MemoryScope) \ - X(AccessQualifier) \ /* end */ enum class BaseType |
