summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-01-29 23:11:06 -0800
committerGitHub <noreply@github.com>2025-01-29 23:11:06 -0800
commit2ae194d51e15c064c3d905e628f7335de7504e32 (patch)
tree6ff8df77913152537d7564499b383c719af732c3
parentcbcb97a64c0b7b908fc7be565b0d6141d2f1a1f7 (diff)
Fix ConstantIntVal::toText when the val is a enum. (#6224)
* Fix ConstantIntVal::toText when the val is a enum. * Fix comment.
-rw-r--r--source/slang/slang-ast-decl.h2
-rw-r--r--source/slang/slang-ast-val.cpp24
-rw-r--r--source/slang/slang-check-decl.cpp5
-rw-r--r--tests/language-server/typename-enum-intval.slang24
4 files changed, 52 insertions, 3 deletions
diff --git a/source/slang/slang-ast-decl.h b/source/slang/slang-ast-decl.h
index 81e7337c7..7feb70e6a 100644
--- a/source/slang/slang-ast-decl.h
+++ b/source/slang/slang-ast-decl.h
@@ -210,6 +210,8 @@ class EnumCaseDecl : public Decl
// Tag value
Expr* tagExpr = nullptr;
+
+ IntVal* tagVal = nullptr;
};
// A member of InterfaceDecl representing the abstract ThisType.
diff --git a/source/slang/slang-ast-val.cpp b/source/slang/slang-ast-val.cpp
index 98135ef16..9bcfd21bc 100644
--- a/source/slang/slang-ast-val.cpp
+++ b/source/slang/slang-ast-val.cpp
@@ -149,6 +149,30 @@ void Val::_toTextOverride(StringBuilder& out)
void ConstantIntVal::_toTextOverride(StringBuilder& out)
{
+ if (auto enumTypeDecl = isDeclRefTypeOf<EnumDecl>(getType()))
+ {
+ // If this is an enum type, then we want to print the name of the
+ // corresponding enum case, instead of the raw integer value, if possible.
+ //
+ // We will look up the enum case that corresponds to the value, and
+ // print its name if we can find one.
+ //
+ for (auto enumCase : enumTypeDecl.getDecl()->getMembersOfType<EnumCaseDecl>())
+ {
+ if (auto constVal = as<ConstantIntVal>(enumCase->tagVal))
+ {
+ if (constVal->getValue() == getValue())
+ {
+ out << DeclRef(enumCase);
+ return;
+ }
+ }
+ }
+
+ // Fallback to explicit cast to the enum type.
+ out << getType() << "(" << getValue() << ")";
+ return;
+ }
out << getValue();
}
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index d12374d52..7d083e53b 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -7967,9 +7967,8 @@ void SemanticsDeclBodyVisitor::visitEnumCaseDecl(EnumCaseDecl* decl)
initExpr = coerce(CoercionSite::General, tagType, initExpr);
// We want to enforce that this is an integer constant
- // expression, but we don't actually care to retain
- // the value.
- CheckIntegerConstantExpression(
+ // expression.
+ decl->tagVal = CheckIntegerConstantExpression(
initExpr,
IntegerConstantExpressionCoercionType::AnyInteger,
nullptr,
diff --git a/tests/language-server/typename-enum-intval.slang b/tests/language-server/typename-enum-intval.slang
new file mode 100644
index 000000000..9eca71ae2
--- /dev/null
+++ b/tests/language-server/typename-enum-intval.slang
@@ -0,0 +1,24 @@
+//TEST:LANG_SERVER(filecheck=CHECK):
+
+namespace ns {
+enum Test : uint32_t
+{
+ A = 1,
+ B = 2,
+}
+
+struct Foo<let T : Test>
+{
+}
+}
+
+void f()
+{
+//HOVER:18,25
+ ns.Foo<ns.Test.A> first;
+//HOVER:20,27
+ ns.Foo<ns.Test(3)> second;
+}
+
+// CHECK: ns.Foo<ns.Test.A>
+// CHECK: ns.Foo<ns.Test(3)> \ No newline at end of file