llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: John Harrison (ashgti)

<details>
<summary>Changes</summary>

This corrects a mistake I made when I previously tried to add support for 
obj-c/swift variables in lldb-dap. This should call into `GetObjectDescription` 
if there is no summary of the type available and the description is not empty.

I also added a unit test to verify this.

---
Full diff: https://github.com/llvm/llvm-project/pull/146754.diff


5 Files Affected:

- (added) lldb/test/API/tools/lldb-dap/variables/objc/Makefile (+9) 
- (added) lldb/test/API/tools/lldb-dap/variables/objc/TestDAP_variables_objc.py 
(+31) 
- (added) lldb/test/API/tools/lldb-dap/variables/objc/main.m (+45) 
- (modified) lldb/tools/lldb-dap/JSONUtils.cpp (+12-8) 
- (modified) lldb/tools/lldb-dap/JSONUtils.h (+3) 


``````````diff
diff --git a/lldb/test/API/tools/lldb-dap/variables/objc/Makefile 
b/lldb/test/API/tools/lldb-dap/variables/objc/Makefile
new file mode 100644
index 0000000000000..71d7ec417633f
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/variables/objc/Makefile
@@ -0,0 +1,9 @@
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS := -w -fobjc-arc
+
+USE_SYSTEM_STDLIB := 1
+
+LD_EXTRAS := -framework Foundation
+
+include Makefile.rules
diff --git 
a/lldb/test/API/tools/lldb-dap/variables/objc/TestDAP_variables_objc.py 
b/lldb/test/API/tools/lldb-dap/variables/objc/TestDAP_variables_objc.py
new file mode 100644
index 0000000000000..9dcbed50987b9
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/variables/objc/TestDAP_variables_objc.py
@@ -0,0 +1,31 @@
+"""
+Test 'variables' requests for obj-c types.
+"""
+
+import lldbdap_testcase
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+class TestDAP_variables_objc(lldbdap_testcase.DAPTestCaseBase):
+    @skipUnlessDarwin
+    def test_objc_description(self):
+        """Test that we can get the description of an Objective-C object."""
+        program = self.getBuildArtifact("a.out")
+        self.build_and_launch(
+            program,
+        )
+        source = "main.m"
+        breakpoint_ids = self.set_source_breakpoints(
+            source, [line_number(source, "// breakpoint")]
+        )
+        self.continue_to_breakpoints(breakpoint_ids)
+
+        greeter_var = self.dap_server.get_local_variable(name="greeter")
+        self.assertIsNotNone(greeter_var, "greeter variable should not be 
None")
+        self.assertEqual(greeter_var["type"], "Greeter *")
+        self.assertEqual(greeter_var["evaluateName"], "greeter")
+        self.assertRegexpMatches(
+            greeter_var["value"], r"<Greeter 0x[0-9A-Fa-f]+ name=Bob 
debugDescription>"
+        )
+        self.continue_to_exit()
diff --git a/lldb/test/API/tools/lldb-dap/variables/objc/main.m 
b/lldb/test/API/tools/lldb-dap/variables/objc/main.m
new file mode 100644
index 0000000000000..aeafa0019af8c
--- /dev/null
+++ b/lldb/test/API/tools/lldb-dap/variables/objc/main.m
@@ -0,0 +1,45 @@
+#import <Foundation/Foundation.h>
+
+@interface Greeter : NSObject
+
+@property(nonatomic, strong) NSString *name;
+
+- (void)greet:(NSString *)other;
+
+@end
+
+@implementation Greeter
+
+- (instancetype)initWithName:(NSString *)name {
+  if ((self = [super init])) {
+    _name = [name copy];
+  }
+  return self;
+}
+
+- (void)greet:(NSString *)other {
+  NSLog(@"Hello %@, from %@", other, _name);
+}
+
+- (NSString *)description {
+  return
+      [NSString stringWithFormat:@"<Greeter %p name=%@>", (void *)self, _name];
+}
+
+- (NSString *)debugDescription {
+  return [NSString stringWithFormat:@"<Greeter %p name=%@ debugDescription>",
+                                    (void *)self, _name];
+}
+
+@end
+
+int main(int argc, char *argv[]) {
+  Greeter *greeter = [[Greeter alloc] initWithName:@"Bob"];
+  if (argc > 1) {
+    [greeter greet:@(argv[1])];
+  } else {
+    [greeter greet:@"World"];
+  }
+
+  return 0; // breakpoint
+}
diff --git a/lldb/tools/lldb-dap/JSONUtils.cpp 
b/lldb/tools/lldb-dap/JSONUtils.cpp
index 08e65ab835a57..a42b4af05d782 100644
--- a/lldb/tools/lldb-dap/JSONUtils.cpp
+++ b/lldb/tools/lldb-dap/JSONUtils.cpp
@@ -836,6 +836,7 @@ VariableDescription::VariableDescription(lldb::SBValue v,
     os_display_value << "<error: " << error << ">";
   } else {
     value = llvm::StringRef(v.GetValue()).str();
+    object_description = llvm::StringRef(v.GetObjectDescription()).str();
     summary = llvm::StringRef(v.GetSummary()).str();
     if (summary.empty() && auto_variable_summaries)
       auto_summary = TryCreateAutoSummary(v);
@@ -843,7 +844,10 @@ VariableDescription::VariableDescription(lldb::SBValue v,
     std::optional<std::string> effective_summary =
         !summary.empty() ? summary : auto_summary;
 
-    if (!value.empty()) {
+    if (!object_description.empty() &&
+        (!effective_summary || effective_summary->empty())) {
+      os_display_value << object_description;
+    } else if (!value.empty()) {
       os_display_value << value;
       if (effective_summary)
         os_display_value << " " << *effective_summary;
@@ -901,18 +905,18 @@ llvm::json::Object 
VariableDescription::GetVariableExtensionsJSON() {
 std::string VariableDescription::GetResult(llvm::StringRef context) {
   // In repl context, the results can be displayed as multiple lines so more
   // detailed descriptions can be returned.
-  if (context != "repl")
+  if (context != "repl" || !v.IsValid())
     return display_value;
 
-  if (!v.IsValid())
-    return display_value;
+  // First, try the SBValue::GetObjectDescription(), which may call into
+  // language runtime specific formatters (see ValueObjectPrinter).
+  if (!object_description.empty())
+    return object_description;
 
-  // Try the SBValue::GetDescription(), which may call into language runtime
-  // specific formatters (see ValueObjectPrinter).
+  // Fallback to the default description for the value.
   lldb::SBStream stream;
   v.GetDescription(stream);
-  llvm::StringRef description = stream.GetData();
-  return description.trim().str();
+  return llvm::StringRef(stream.GetData()).trim().str();
 }
 
 bool ValuePointsToCode(lldb::SBValue v) {
diff --git a/lldb/tools/lldb-dap/JSONUtils.h b/lldb/tools/lldb-dap/JSONUtils.h
index fd9a06931ebff..0a660d04d02d8 100644
--- a/lldb/tools/lldb-dap/JSONUtils.h
+++ b/lldb/tools/lldb-dap/JSONUtils.h
@@ -329,6 +329,9 @@ struct VariableDescription {
   std::string evaluate_name;
   // The output of SBValue.GetValue() if it doesn't fail. It might be empty.
   std::string value;
+  // The output of SBValue.GetObjectDescription() if it doesn't fail. It might
+  // be empty.
+  std::string object_description;
   // The summary string of this variable. It might be empty.
   std::string summary;
   // The auto summary if using `enableAutoVariableSummaries`.

``````````

</details>


https://github.com/llvm/llvm-project/pull/146754
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to