summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-14 14:45:57 -0700
committerGitHub <noreply@github.com>2024-03-14 14:45:57 -0700
commitf5f0740be8102b4d719575d97b00dbd21b54ffbe (patch)
tree3ca8da03f4ff12a11a42370d17bcd9593a103cfd
parent78d4df0644b20b8ba4eeff459c749c4e8d261345 (diff)
Support unscoped enums. (#3771)
-rw-r--r--docs/user-guide/02-conventional-features.md14
-rw-r--r--source/slang/core.meta.slang3
-rw-r--r--source/slang/slang-ast-modifier.h4
-rw-r--r--source/slang/slang-check-modifier.cpp10
-rw-r--r--source/slang/slang-lookup.cpp3
-rw-r--r--tests/language-feature/enums/unscoped-enum.slang17
6 files changed, 47 insertions, 4 deletions
diff --git a/docs/user-guide/02-conventional-features.md b/docs/user-guide/02-conventional-features.md
index 4faa6607b..8c45fec48 100644
--- a/docs/user-guide/02-conventional-features.md
+++ b/docs/user-guide/02-conventional-features.md
@@ -158,8 +158,18 @@ enum Channel
}
```
-> #### Note ####
-> Unlike C/C++, `enum` types in Slang are always scoped (like `enum class` in C++). You can write `enum class` in Slang if it makes you happy, but it isn't required.
+Unlike C/C++, `enum` types in Slang are always scoped by default (like `enum class` in C++). You can write `enum class` in Slang if it makes you happy, but it isn't required. If you want a `enum` type to be unscoped, you can use the `[UnscopedEnum]` attribute:
+```csharp
+[[UnscopedEnum]
+enum Channel
+{
+ Red, Green, Blue
+}
+void test(Channel c)
+{
+ if (c == Red) { /*...*/ }
+}
+```
### Opaque Types
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 54a82c4f0..237daac56 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -2345,6 +2345,9 @@ attribute_syntax [spv_target_env_1_3] : SPIRVTargetEnv13Attribute;
__attributeTarget(VarDeclBase)
attribute_syntax [disable_array_flattening] : DisableArrayFlatteningAttribute;
+__attributeTarget(EnumDecl)
+attribute_syntax [UnscopedEnum] : UnscopedEnumAttribute;
+
// Statement Attributes
__attributeTarget(LoopStmt)
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 49dc1b81f..32852496c 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -713,6 +713,10 @@ class CallAttribute : public Attribute
};
// `[call]`
+class UnscopedEnumAttribute : public Attribute
+{
+ SLANG_AST_CLASS(UnscopedEnumAttribute)
+};
// [[vk_push_constant]] [[push_constant]]
class PushConstantAttribute : public Attribute
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 6359096b9..eae993dc7 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -1173,7 +1173,15 @@ namespace Slang
// the right syntax class to instantiate.
//
- return checkAttribute(hlslUncheckedAttribute, syntaxNode);
+ auto checkedAttr = checkAttribute(hlslUncheckedAttribute, syntaxNode);
+
+ if (as<UnscopedEnumAttribute>(checkedAttr))
+ {
+ if (auto parentDecl = as<ContainerDecl>(getParentDecl(as<Decl>(syntaxNode))))
+ parentDecl->invalidateMemberDictionary();
+ return getASTBuilder()->create<TransparentModifier>();
+ }
+ return checkedAttr;
}
if (auto decl = as<Decl>(syntaxNode))
diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp
index 04a855c3c..301c86aa8 100644
--- a/source/slang/slang-lookup.cpp
+++ b/source/slang/slang-lookup.cpp
@@ -648,7 +648,8 @@ static void _lookUpMembersInValue(
// in the *type* of that value.
//
auto valueType = getTypeForDeclRef(astBuilder, valueDeclRef, SourceLoc());
-
+ if (auto typeType = as<TypeType>(valueType))
+ valueType = typeType->getType();
return _lookUpMembersInType(astBuilder, name, valueType, request, ioResult, breadcrumbs);
}
diff --git a/tests/language-feature/enums/unscoped-enum.slang b/tests/language-feature/enums/unscoped-enum.slang
new file mode 100644
index 000000000..6d6558268
--- /dev/null
+++ b/tests/language-feature/enums/unscoped-enum.slang
@@ -0,0 +1,17 @@
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=CHECK): -shaderobj
+
+[UnscopedEnum]
+enum class Fruit
+{
+ Orange, Apple
+}
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<uint> outputBuffer;
+
+[numthreads(1,1,1)]
+void computeMain()
+{
+ // CHECK: 1
+ outputBuffer[0] = (int)Apple;
+} \ No newline at end of file