https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/192711
>From 276684445c77d61ba54962b0ece6bdd5b677f463 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike <[email protected]> Date: Thu, 13 Aug 2026 16:01:45 +0100 Subject: [PATCH] [lldb] Mark enum types as scalar in clang typesystem - #192711 This is to differentiate enums in other languages that has non scalar enums. C/C++ enums are backed by an integer type and are always scalars. However. in languages such as swift and rust, Enums can have associated values. such as ```swift enum Barcode { case upc(Int, Int, Int, Int) case qrCode(String) case Empty } ``` ```rust enum IpAddr { V4(String), V6(String), } ``` in lldb-dap we would like to support changing enum values. but lldb currently only support changing values is that has an valid encoding and is 16 bytes (mostly likely the size of a general register). In the case of enums with associated values. the user should be able to set scalar enums directly ```swift enum Color { case Red case Blue case Green } var m_color = Color.Red ``` we should be able to set m_color to 2. to get the color green. and we only want do that if it is safe to do so. i.e it is an enum and is_scalar (doesn't have associated values). This fails currently because, type system clang does not mark enums as scalars. --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 2 +- lldb/source/ValueObject/DILEval.cpp | 7 ++++--- lldb/source/ValueObject/ValueObject.cpp | 2 +- lldb/test/API/lang/c/enum_types/TestEnumTypes.py | 3 +++ lldb/unittests/Symbol/TestTypeSystemClang.cpp | 4 ++++ 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 51018c1922c4d..7fbcd75673659 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -3919,7 +3919,7 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type, ->getDefinitionOrSelf() ->getIntegerType() .getAsOpaquePtr()); - return eTypeIsEnumeration | eTypeHasValue; + return eTypeIsEnumeration | eTypeHasValue | eTypeIsScalar; case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp index 0ef4e244410a4..91aaaa1c39ab4 100644 --- a/lldb/source/ValueObject/DILEval.cpp +++ b/lldb/source/ValueObject/DILEval.cpp @@ -1573,9 +1573,7 @@ Interpreter::VerifyCastType(lldb::ValueObjectSP operand, CompilerType source_type, CompilerType target_type, int location) { - if (target_type.IsScalarType()) - return VerifyArithmeticCast(source_type, target_type, location); - + // Enumerations can also be a scalar value, try enum cast first. if (target_type.IsEnumerationType()) { // Cast to enum type. if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) { @@ -1590,6 +1588,9 @@ Interpreter::VerifyCastType(lldb::ValueObjectSP operand, return CastKind::eEnumeration; } + if (target_type.IsScalarType()) + return VerifyArithmeticCast(source_type, target_type, location); + if (target_type.IsPointerType()) { if (!source_type.IsInteger() && !source_type.IsEnumerationType() && !source_type.IsArrayType() && !source_type.IsPointerType() && diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index b36a020d262c4..ea187bdc02eec 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -3236,7 +3236,7 @@ lldb::ValueObjectSP ValueObject::CastToBasicType(CompilerType type) { } if (type.IsInteger()) { - if (!is_scalar || is_integer) { + if (is_integer || (is_enum && is_scalar) || !is_scalar) { auto int_value_or_err = GetValueAsAPSInt(); if (int_value_or_err) { // Get the value as APSInt and extend or truncate it to the requested diff --git a/lldb/test/API/lang/c/enum_types/TestEnumTypes.py b/lldb/test/API/lang/c/enum_types/TestEnumTypes.py index 225f3b876e3e5..543818bdfa23e 100644 --- a/lldb/test/API/lang/c/enum_types/TestEnumTypes.py +++ b/lldb/test/API/lang/c/enum_types/TestEnumTypes.py @@ -152,6 +152,9 @@ def check_enum_members(self, members): self.assertEqual( member.signed, value_matches[idx], "Value matches for %d" % (idx) ) + member_type_flags = member.GetType().GetTypeFlags() + is_scalar = (member_type_flags & lldb.eTypeIsScalar) == lldb.eTypeIsScalar + self.assertTrue(is_scalar, f"expects enum: {member.name} is a scalar value") def test_api(self): """Test that the SBTypeEnumMember API's work correctly for enum_test_days""" diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp index 314f8e2c97e19..f7f15eb00bcac 100644 --- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -470,6 +470,7 @@ TEST_F(TestTypeSystemClang, TestIsEnumerationType) { EXPECT_TRUE(enum_type.IsEnumerationType(is_signed)); EXPECT_TRUE(is_signed); EXPECT_FALSE(enum_type.IsIntegerType(is_signed)); + EXPECT_TRUE(enum_type.IsScalarType()); } // Scoped unsigned enum @@ -484,6 +485,7 @@ TEST_F(TestTypeSystemClang, TestIsEnumerationType) { EXPECT_TRUE(enum_type.IsEnumerationType(is_signed)); EXPECT_FALSE(is_signed); EXPECT_FALSE(enum_type.IsIntegerType(is_signed)); + EXPECT_TRUE(enum_type.IsScalarType()); } // Unscoped signed enum @@ -498,6 +500,7 @@ TEST_F(TestTypeSystemClang, TestIsEnumerationType) { EXPECT_TRUE(enum_type.IsEnumerationType(is_signed)); EXPECT_TRUE(is_signed); EXPECT_FALSE(enum_type.IsIntegerType(is_signed)); + EXPECT_TRUE(enum_type.IsScalarType()); } // Unscoped unsigned enum @@ -512,6 +515,7 @@ TEST_F(TestTypeSystemClang, TestIsEnumerationType) { EXPECT_TRUE(enum_type.IsEnumerationType(is_signed)); EXPECT_FALSE(is_signed); EXPECT_FALSE(enum_type.IsIntegerType(is_signed)); + EXPECT_TRUE(enum_type.IsScalarType()); } } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
