[Lldb-commits] [lldb] [lldb-dap] Allow setting scoped enums values (PR #192028)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Apr 14 02:19:12 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Sergei Druzhkov (DrSergei)
<details>
<summary>Changes</summary>
After this patch, users can set the value of a scoped enum in the VS Code UI using the fully qualified name of the enumerator instead of using integer representation before.
---
Full diff: https://github.com/llvm/llvm-project/pull/192028.diff
4 Files Affected:
- (modified) lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py (+38-15)
- (modified) lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py (-1)
- (modified) lldb/test/API/tools/lldb-dap/variables/main.cpp (+8)
- (modified) lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp (+8-1)
``````````diff
diff --git a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
index 66c8d7f720aef..4a5c428d41792 100644
--- a/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
+++ b/lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
@@ -351,9 +351,9 @@ def do_test_scopes_variables_setVariable_evaluate(
verify_locals["argc"]["equals"]["value"] = "123"
verify_locals["pt"]["children"]["x"]["equals"]["value"] = "111"
- verify_locals["x @ main.cpp:27"] = {"equals": {"type": "int", "value": "89"}}
- verify_locals["x @ main.cpp:29"] = {"equals": {"type": "int", "value": "42"}}
- verify_locals["x @ main.cpp:31"] = {"equals": {"type": "int", "value": "72"}}
+ verify_locals["x @ main.cpp:28"] = {"equals": {"type": "int", "value": "89"}}
+ verify_locals["x @ main.cpp:30"] = {"equals": {"type": "int", "value": "42"}}
+ verify_locals["x @ main.cpp:32"] = {"equals": {"type": "int", "value": "72"}}
self.verify_variables(verify_locals, self.dap_server.get_local_variables())
@@ -361,22 +361,22 @@ def do_test_scopes_variables_setVariable_evaluate(
self.assertFalse(self.set_local("x2", 9)["success"])
self.assertFalse(self.set_local("x @ main.cpp:0", 9)["success"])
- self.assertTrue(self.set_local("x @ main.cpp:27", 19)["success"])
- self.assertTrue(self.set_local("x @ main.cpp:29", 21)["success"])
- self.assertTrue(self.set_local("x @ main.cpp:31", 23)["success"])
+ self.assertTrue(self.set_local("x @ main.cpp:28", 19)["success"])
+ self.assertTrue(self.set_local("x @ main.cpp:30", 21)["success"])
+ self.assertTrue(self.set_local("x @ main.cpp:32", 23)["success"])
# The following should have no effect
- self.assertFalse(self.set_local("x @ main.cpp:31", "invalid")["success"])
+ self.assertFalse(self.set_local("x @ main.cpp:32", "invalid")["success"])
- verify_locals["x @ main.cpp:27"]["equals"]["value"] = "19"
- verify_locals["x @ main.cpp:29"]["equals"]["value"] = "21"
- verify_locals["x @ main.cpp:31"]["equals"]["value"] = "23"
+ verify_locals["x @ main.cpp:28"]["equals"]["value"] = "19"
+ verify_locals["x @ main.cpp:30"]["equals"]["value"] = "21"
+ verify_locals["x @ main.cpp:32"]["equals"]["value"] = "23"
self.verify_variables(verify_locals, self.dap_server.get_local_variables())
# The plain x variable shold refer to the innermost x
self.assertTrue(self.set_local("x", 22)["success"])
- verify_locals["x @ main.cpp:31"]["equals"]["value"] = "22"
+ verify_locals["x @ main.cpp:32"]["equals"]["value"] = "22"
self.verify_variables(verify_locals, self.dap_server.get_local_variables())
@@ -393,9 +393,9 @@ def do_test_scopes_variables_setVariable_evaluate(
names = [var["name"] for var in locals]
# The first shadowed x shouldn't have a suffix anymore
verify_locals["x"] = {"equals": {"type": "int", "value": "19"}}
- self.assertNotIn("x @ main.cpp:27", names)
- self.assertNotIn("x @ main.cpp:29", names)
- self.assertNotIn("x @ main.cpp:31", names)
+ self.assertNotIn("x @ main.cpp:28", names)
+ self.assertNotIn("x @ main.cpp:30", names)
+ self.assertNotIn("x @ main.cpp:32", names)
self.verify_variables(verify_locals, locals)
@@ -428,12 +428,13 @@ def do_test_scopes_and_evaluate_expansion(self, enableAutoVariableSummaries: boo
line_number(source, "// breakpoint 6"),
line_number(source, "// breakpoint 7"),
line_number(source, "// breakpoint 8"),
+ line_number(source, "// breakpoint 9"),
]
breakpoint_ids = self.set_source_breakpoints(source, lines)
self.assertEqual(
len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
)
- [bp1, bp3, bp6, bp7, bp8] = breakpoint_ids
+ [bp1, bp3, bp6, bp7, bp8, bp9] = breakpoint_ids
self.continue_to_breakpoint(bp1)
# Verify locals
@@ -737,6 +738,28 @@ def do_test_scopes_and_evaluate_expansion(self, enableAutoVariableSummaries: boo
inner_bitfields_struct,
)
+ self.continue_to_breakpoint(bp9)
+
+ verify_locals = {
+ "t": {
+ "equals": {
+ "type": "Test",
+ "value": "FOO",
+ "evaluateName": "t",
+ },
+ },
+ }
+ self.verify_variables(
+ verify_locals,
+ self.dap_server.get_local_variables(),
+ )
+ self.assertTrue(self.set_local("t", "Test::BAR")["success"])
+ verify_locals["t"]["equals"]["value"] = "BAR"
+ self.verify_variables(
+ verify_locals,
+ self.dap_server.get_local_variables(),
+ )
+
# Continue to breakpoint 3, permanent variable should still exist
# after resume.
self.continue_to_breakpoint(bp3)
diff --git a/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py b/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py
index 4622523931804..5f9e2383917f0 100644
--- a/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py
+++ b/lldb/test/API/tools/lldb-dap/variables/children/TestDAP_variables_children.py
@@ -24,7 +24,6 @@ def test_get_num_children(self):
self.continue_to_breakpoints(breakpoint_ids)
local_vars = self.dap_server.get_local_variables()
- print(local_vars)
indexed = next(filter(lambda x: x["name"] == "indexed", local_vars))
not_indexed = next(filter(lambda x: x["name"] == "not_indexed", local_vars))
self.assertIn("indexedVariables", indexed)
diff --git a/lldb/test/API/tools/lldb-dap/variables/main.cpp b/lldb/test/API/tools/lldb-dap/variables/main.cpp
index 6e17ebadc246f..e1a7fb165fc40 100644
--- a/lldb/test/API/tools/lldb-dap/variables/main.cpp
+++ b/lldb/test/API/tools/lldb-dap/variables/main.cpp
@@ -15,6 +15,7 @@ int test_return_variable();
int test_anonymous_types();
int test_anonymous_fields();
void test_unnamed_bitfields();
+void test_scoped_enums();
int main(int argc, char const *argv[]) {
static float s_local = 2.25;
@@ -38,6 +39,7 @@ int main(int argc, char const *argv[]) {
test_anonymous_types();
test_anonymous_fields();
test_unnamed_bitfields();
+ test_scoped_enums();
return test_indexedVariables(); // breakpoint 3
}
@@ -88,3 +90,9 @@ void test_unnamed_bitfields() {
example e = {0xA, 0xB};
printf("lo: %u, hi: %u\n", e.lo, e.hi); // breakpoint 8
}
+
+void test_scoped_enums() {
+ enum class Test { FOO, BAR };
+ Test t = Test::FOO;
+ printf("enum: %i", static_cast<int>(t)); // breakpoint 9
+}
diff --git a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
index 47a45ab807854..e27de395404fa 100644
--- a/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp
@@ -64,7 +64,14 @@ SetVariableRequestHandler::Run(const SetVariableArguments &args) const {
lldb::SBFrame frame = variable.GetFrame();
std::string expression = llvm::StringRef(args.value).trim().str();
lldb::SBValue result = EvaluateExpression(dap.target, frame, expression);
- const char *value = result.IsValid() ? result.GetValue() : expression.c_str();
+ const char *value = [&]() {
+ if (!result.IsValid())
+ return expression.c_str();
+ lldb::SBType type = result.GetType();
+ if (type.IsScopedEnumerationType())
+ return result.Cast(type.GetEnumerationIntegerType()).GetValue();
+ return result.GetValue();
+ }();
lldb::SBError error;
const bool success = variable.SetValueFromCString(value, error);
``````````
</details>
https://github.com/llvm/llvm-project/pull/192028
More information about the lldb-commits
mailing list