diff options
| author | Yong He <yonghe@outlook.com> | 2025-01-29 23:11:06 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-29 23:11:06 -0800 |
| commit | 2ae194d51e15c064c3d905e628f7335de7504e32 (patch) | |
| tree | 6ff8df77913152537d7564499b383c719af732c3 | |
| parent | cbcb97a64c0b7b908fc7be565b0d6141d2f1a1f7 (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.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ast-val.cpp | 24 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 5 | ||||
| -rw-r--r-- | tests/language-server/typename-enum-intval.slang | 24 |
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 |
