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

Reply via email to