[Lldb-commits] [lldb] [lldb] Resolve ObjC property backing storage in dwim-print (PR #225204)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Sep 23 09:47:23 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Piotr Jeremicz (piotrekjeremicz)
<details>
<summary>Changes</summary>
Follow-up to #<!-- -->215776 (DWARF/LLVM IR representation) and #<!-- -->220362 (Clang emission) - this teaches LLDB to actually consume DW_TAG_property / DW_AT_property_forward.
A synthesized Objective-C property whose backing ivar has a different name than the property itself (e.g. `@<!-- -->synthesize declaredBacking = _customDeclaredIvar;`) can't be resolved by a plain `frame variable` lookup - the property name never names a real member, only the ivar does. `dwim-print` ("p") therefore always fell back to a full JIT-compiled `expression`, even though nothing about reading the property actually requires evaluation.
Assisted-by: Claude
---
Patch is 21.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/225204.diff
11 Files Affected:
- (modified) lldb/include/lldb/Symbol/CompilerType.h (+3)
- (modified) lldb/include/lldb/Symbol/TypeSystem.h (+6)
- (modified) lldb/source/Commands/CommandObjectDWIMPrint.cpp (+76-9)
- (modified) lldb/source/Commands/CommandObjectDWIMPrint.h (+6)
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+67-5)
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h (+9)
- (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp (+42-13)
- (modified) lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h (+4)
- (modified) lldb/source/Symbol/CompilerType.cpp (+10)
- (modified) lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py (+21)
- (modified) lldb/test/API/commands/dwim-print/objc/main.m (+19)
``````````diff
diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index 168946cf17475e..da22b35a619bf2 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -485,6 +485,9 @@ class CompilerType {
CompilerType GetDirectNestedTypeWithName(llvm::StringRef name) const;
+ llvm::StringRef
+ GetPropertyBackingStorageName(llvm::StringRef property_name) const;
+
/// Return the number of template arguments the type has.
/// If expand_pack is true, then variadic argument packs are automatically
/// expanded to their supplied arguments. If it is false an argument pack
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index 9ec0f13814975a..400bb0726a6274 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -403,6 +403,12 @@ class TypeSystem : public PluginInterface,
return CompilerType();
}
+ virtual llvm::StringRef
+ GetPropertyBackingStorageName(lldb::opaque_compiler_type_t type,
+ llvm::StringRef property_name) {
+ return llvm::StringRef();
+ }
+
virtual bool IsTemplateType(lldb::opaque_compiler_type_t type);
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
index 1b0b4c7881cfc1..7b4be1692ae27e 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.cpp
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.cpp
@@ -22,6 +22,7 @@
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <regex>
@@ -51,6 +52,52 @@ CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter)
Options *CommandObjectDWIMPrint::GetOptions() { return &m_option_group; }
+std::string CommandObjectDWIMPrint::RewritePathForBackingStorage(
+ llvm::StringRef expr, StackFrame &frame,
+ lldb::DynamicValueType use_dynamic) {
+ llvm::SmallVector<llvm::StringRef, 4> components;
+ expr.split(components, '.');
+ if (components.empty())
+ return {};
+
+ VariableSP var_sp;
+ Status status;
+ ValueObjectSP valobj_sp = frame.GetValueForVariableExpressionPath(
+ components[0], use_dynamic,
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
+ StackFrame::eExpressionPathOptionsDisallowGlobals,
+ var_sp, status, lldb::eDILModeSimple);
+ if (!valobj_sp || !status.Success() || valobj_sp->GetError().Fail())
+ return {};
+
+ std::string rewritten_path = components[0].str();
+ bool did_rewrite = false;
+
+ for (llvm::StringRef component : llvm::ArrayRef(components).drop_front()) {
+ ValueObjectSP child_sp = valobj_sp->GetChildMemberWithName(component);
+ llvm::StringRef name_used = component;
+ if (!child_sp) {
+ llvm::StringRef backing_name =
+ valobj_sp->GetCompilerType().GetPropertyBackingStorageName(component);
+ if (backing_name.empty())
+ return {};
+ child_sp = valobj_sp->GetChildMemberWithName(backing_name);
+ if (!child_sp)
+ return {};
+ name_used = backing_name;
+ did_rewrite = true;
+ }
+ rewritten_path += '.';
+ rewritten_path += name_used;
+ valobj_sp = child_sp;
+ }
+
+ if (!did_rewrite)
+ return {};
+
+ return rewritten_path;
+}
+
void CommandObjectDWIMPrint::DoExecute(StringRef command,
CommandReturnObject &result) {
m_option_group.NotifyOptionParsingStarting(&m_exe_ctx);
@@ -165,14 +212,34 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
const bool try_variable_path =
expr.find_first_of("*&->[]") == StringRef::npos;
if (frame && try_variable_path) {
- VariableSP var_sp;
- Status status;
- auto valobj_sp = frame->GetValueForVariableExpressionPath(
- expr, eval_options.GetUseDynamic(),
- StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
- StackFrame::eExpressionPathOptionsDisallowGlobals,
- var_sp, status, lldb::eDILModeSimple);
- if (valobj_sp && status.Success() && valobj_sp->GetError().Success()) {
+ auto try_variable_expr = [&](llvm::StringRef path) -> ValueObjectSP {
+ VariableSP var_sp;
+ Status status;
+ auto valobj_sp = frame->GetValueForVariableExpressionPath(
+ path, eval_options.GetUseDynamic(),
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
+ StackFrame::eExpressionPathOptionsDisallowGlobals,
+ var_sp, status, lldb::eDILModeSimple);
+ if (valobj_sp && status.Success() && valobj_sp->GetError().Success())
+ return valobj_sp;
+ return nullptr;
+ };
+
+ StringRef used_path = expr;
+ ValueObjectSP valobj_sp = try_variable_expr(expr);
+
+ std::string rewritten_path;
+ if (!valobj_sp) {
+ rewritten_path = RewritePathForBackingStorage(
+ expr, *frame, eval_options.GetUseDynamic());
+ if (!rewritten_path.empty()) {
+ valobj_sp = try_variable_expr(rewritten_path);
+ if (valobj_sp)
+ used_path = rewritten_path;
+ }
+ }
+
+ if (valobj_sp) {
if (!suppress_result) {
if (auto persisted_valobj = valobj_sp->Persist())
valobj_sp = persisted_valobj;
@@ -183,7 +250,7 @@ void CommandObjectDWIMPrint::DoExecute(StringRef command,
if (args.HasArgs())
flags = args.GetArgString();
result.AppendNoteWithFormatv("ran `frame variable {0}{1}`", flags,
- expr);
+ used_path);
}
dump_val_object(*valobj_sp);
diff --git a/lldb/source/Commands/CommandObjectDWIMPrint.h b/lldb/source/Commands/CommandObjectDWIMPrint.h
index 01ba9c225e3301..dd7b9ea7cb77a2 100644
--- a/lldb/source/Commands/CommandObjectDWIMPrint.h
+++ b/lldb/source/Commands/CommandObjectDWIMPrint.h
@@ -17,6 +17,8 @@
namespace lldb_private {
+class StackFrame;
+
/// Implements `dwim-print`, a printing command that chooses the most direct,
/// efficient, and resilient means of printing a given expression.
///
@@ -42,6 +44,10 @@ class CommandObjectDWIMPrint : public CommandObjectRaw {
private:
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
+ std::string RewritePathForBackingStorage(llvm::StringRef expr,
+ StackFrame &frame,
+ lldb::DynamicValueType use_dynamic);
+
OptionGroupOptions m_option_group;
OptionGroupFormat m_format_options = lldb::eFormatDefault;
OptionGroupValueObjectDisplay m_varobj_options;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index b60f1d9e41958a..c039aa3234a07f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -48,6 +48,7 @@
#include "clang/AST/Type.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
#include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
#include "llvm/Demangle/Demangle.h"
@@ -1983,21 +1984,41 @@ class DWARFASTParserClang::DelayedAddObjCClassProperty {
// required if you don't have an
// ivar decl
const char *property_setter_name, const char *property_getter_name,
- uint32_t property_attributes, ClangASTMetadata metadata)
+ uint32_t property_attributes, ClangASTMetadata metadata,
+ llvm::StringRef property_ivar_name)
: m_class_opaque_type(class_opaque_type), m_property_name(property_name),
m_property_opaque_type(property_opaque_type),
m_property_setter_name(property_setter_name),
m_property_getter_name(property_getter_name),
- m_property_attributes(property_attributes), m_metadata(metadata) {}
+ m_property_attributes(property_attributes), m_metadata(metadata),
+ m_property_ivar_name(property_ivar_name) {}
bool Finalize() {
return TypeSystemClang::AddObjCClassProperty(
m_class_opaque_type, m_property_name, m_property_opaque_type,
- /*ivar_decl=*/nullptr, m_property_setter_name, m_property_getter_name,
+ FindIvarDecl(), m_property_setter_name, m_property_getter_name,
m_property_attributes, m_metadata);
}
private:
+ clang::ObjCIvarDecl *FindIvarDecl() {
+ if (m_property_ivar_name.empty())
+ return nullptr;
+
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ TypeSystemClang::GetAsObjCInterfaceDecl(m_class_opaque_type);
+ if (!class_interface_decl)
+ return nullptr;
+
+ auto ast = m_class_opaque_type.GetTypeSystem<TypeSystemClang>();
+ if (!ast)
+ return nullptr;
+
+ clang::IdentifierInfo &ivar_ident =
+ ast->getASTContext().Idents.get(m_property_ivar_name);
+ return class_interface_decl->lookupInstanceVariable(&ivar_ident);
+ }
+
CompilerType m_class_opaque_type;
const char *m_property_name;
CompilerType m_property_opaque_type;
@@ -2005,6 +2026,7 @@ class DWARFASTParserClang::DelayedAddObjCClassProperty {
const char *m_property_getter_name;
uint32_t m_property_attributes;
ClangASTMetadata m_metadata;
+ llvm::StringRef m_property_ivar_name;
};
static std::optional<clang::APValue> MakeAPValue(const clang::ASTContext &ast,
@@ -2831,9 +2853,39 @@ PropertyAttributes::PropertyAttributes(const DWARFDIE &die) {
}
}
+DWARFASTParserClang::PropertyBackingStorageNames
+DWARFASTParserClang::ParsePropertyBackingStorageNames(
+ const DWARFDIE &parent_die) {
+ PropertyBackingStorageNames property_backing_names;
+
+ for (DWARFDIE die : parent_die.children()) {
+ if (die.Tag() != DW_TAG_property)
+ continue;
+
+ const char *prop_name = die.GetName();
+ if (!prop_name)
+ continue;
+
+ for (DWARFDIE child_die : die.children()) {
+ if (child_die.Tag() != DW_TAG_property_getter)
+ continue;
+
+ if (DWARFDIE backing_die = child_die.GetAttributeValueAsReferenceDIE(
+ DW_AT_property_forward)) {
+ if (const char *backing_name = backing_die.GetName())
+ property_backing_names[prop_name] = backing_name;
+ }
+ break;
+ }
+ }
+
+ return property_backing_names;
+}
+
void DWARFASTParserClang::ParseObjCProperty(
const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
+ const PropertyBackingStorageNames &property_backing_names,
DelayedPropertyList &delayed_properties) {
// This function can only parse DW_TAG_APPLE_property.
assert(die.Tag() == DW_TAG_APPLE_property);
@@ -2859,12 +2911,18 @@ void DWARFASTParserClang::ParseObjCProperty(
return;
}
+ llvm::StringRef property_ivar_name;
+ auto backing_name_it = property_backing_names.find(propAttrs.prop_name);
+ if (backing_name_it != property_backing_names.end())
+ property_ivar_name = backing_name_it->second;
+
ClangASTMetadata metadata;
metadata.SetUserID(die.GetID());
delayed_properties.emplace_back(
class_clang_type, propAttrs.prop_name,
member_type->GetLayoutCompilerType(), propAttrs.prop_setter_name,
- propAttrs.prop_getter_name, propAttrs.prop_attributes, metadata);
+ propAttrs.prop_getter_name, propAttrs.prop_attributes, metadata,
+ property_ivar_name);
}
llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue(
@@ -3140,12 +3198,16 @@ bool DWARFASTParserClang::ParseChildMembers(
if (ast == nullptr)
return false;
+ const PropertyBackingStorageNames property_backing_names =
+ ParsePropertyBackingStorageNames(parent_die);
+
for (DWARFDIE die : parent_die.children()) {
dw_tag_t tag = die.Tag();
switch (tag) {
case DW_TAG_APPLE_property:
- ParseObjCProperty(die, parent_die, class_clang_type, delayed_properties);
+ ParseObjCProperty(die, parent_die, class_clang_type,
+ property_backing_names, delayed_properties);
break;
case DW_TAG_variant_part:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 03c431c73fb6ff..1d4569a7588eca 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
#include "DWARFASTParser.h"
#include "DWARFDIE.h"
@@ -137,6 +138,8 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+ typedef llvm::StringMap<llvm::StringRef> PropertyBackingStorageNames;
+
typedef llvm::DenseMap<
const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
clang::DeclContext *>
@@ -204,6 +207,9 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
DelayedPropertyList &delayed_properties,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
+ PropertyBackingStorageNames ParsePropertyBackingStorageNames(
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die);
+
void ParseChildParameters(
clang::DeclContext *containing_decl_ctx,
const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
@@ -399,12 +405,15 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// \param parent_die The parent DIE.
/// \param class_clang_type The Objective-C class that will contain the
/// created property.
+ /// \param property_backing_names Map from property name to backing member
+ /// name, as produced by ParsePropertyBackingStorageNames.
/// \param delayed_properties The list of delayed properties that the result
/// will be appended to.
void
ParseObjCProperty(const lldb_private::plugin::dwarf::DWARFDIE &die,
const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
+ const PropertyBackingStorageNames &property_backing_names,
DelayedPropertyList &delayed_properties);
void
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 5255ec835c0a44..01ff6376b3d0a9 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -7090,6 +7090,40 @@ TypeSystemClang::GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
return CompilerType();
}
+llvm::StringRef TypeSystemClang::GetPropertyBackingStorageName(
+ lldb::opaque_compiler_type_t type, llvm::StringRef property_name) {
+ if (!type || property_name.empty())
+ return llvm::StringRef();
+
+ CompilerType compiler_type(weak_from_this(), type);
+
+ CompilerType class_type;
+ if (IsObjCObjectPointerType(compiler_type, &class_type))
+ compiler_type = class_type;
+
+ if (!GetCompleteType(compiler_type.GetOpaqueQualType()))
+ return llvm::StringRef();
+
+ clang::ObjCInterfaceDecl *class_interface_decl =
+ GetAsObjCInterfaceDecl(compiler_type);
+ if (!class_interface_decl)
+ return llvm::StringRef();
+
+ clang::IdentifierInfo &property_ident =
+ getASTContext().Idents.get(property_name);
+ clang::ObjCPropertyDecl *property_decl =
+ class_interface_decl->FindPropertyDeclaration(
+ &property_ident,
+ clang::ObjCPropertyQueryKind::OBJC_PR_query_instance);
+ if (!property_decl)
+ return llvm::StringRef();
+
+ if (clang::ObjCIvarDecl *ivar_decl = property_decl->getPropertyIvarDecl())
+ return ivar_decl->getName();
+
+ return llvm::StringRef();
+}
+
bool TypeSystemClang::IsTemplateType(lldb::opaque_compiler_type_t type) {
if (!type)
return false;
@@ -7931,29 +7965,24 @@ bool TypeSystemClang::AddObjCClassProperty(
CompilerType property_clang_type_to_access;
- if (property_clang_type.IsValid())
- property_clang_type_to_access = property_clang_type;
- else if (ivar_decl)
+ if (ivar_decl)
property_clang_type_to_access = ast->GetType(ivar_decl->getType());
+ else if (property_clang_type.IsValid())
+ property_clang_type_to_access = property_clang_type;
if (!class_interface_decl || !property_clang_type_to_access.IsValid())
return false;
- clang::TypeSourceInfo *prop_type_source;
- if (ivar_decl)
- prop_type_source = clang_ast.getTrivialTypeSourceInfo(ivar_decl->getType());
- else
- prop_type_source = clang_ast.getTrivialTypeSourceInfo(
- ClangUtil::GetQualType(property_clang_type));
+ clang::QualType property_qual_type =
+ ClangUtil::GetQualType(property_clang_type_to_access);
+ clang::TypeSourceInfo *prop_type_source =
+ clang_ast.getTrivialTypeSourceInfo(property_qual_type);
clang::ObjCPropertyDecl *property_decl =
clang::ObjCPropertyDecl::CreateDeserialized(clang_ast, GlobalDeclID());
property_decl->setDeclContext(class_interface_decl);
property_decl->setDeclName(&clang_ast.Idents.get(property_name));
- property_decl->setType(ivar_decl
- ? ivar_decl->getType()
- : ClangUtil::GetQualType(property_clang_type),
- prop_type_source);
+ property_decl->setType(property_qual_type, prop_type_source);
SetMemberOwningModule(property_decl, class_interface_decl);
if (!property_decl)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 28e79f2b0b11f8..cfeac83d3c8398 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -927,6 +927,10 @@ class TypeSystemClang : public TypeSystem {
CompilerType GetDirectNestedTypeWithName(lldb::opaque_compiler_type_t type,
llvm::StringRef name) override;
+ llvm::StringRef
+ GetPropertyBackingStorageName(lldb::opaque_compiler_type_t type,
+ llvm::StringRef property_name) override;
+
bool IsTemplateType(lldb::opaque_compiler_type_t type) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
diff --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 6f20bfa89ed38c..e1db240979ac76 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -970,6 +970,16 @@ CompilerType::GetDirectNestedTypeWithName(llvm::StringRef name) const {
return CompilerType();
}
+llvm::StringRef CompilerType::GetPropertyBackingStorageName(
+ llvm::StringRef property_name) const {
+ if (IsValid() && !property_name.empty()) {
+ if (auto type_system_sp = GetTypeSystem())
+ return type_system_sp->GetPropertyBackingStorageName(m_type,
+ property_name);
+ }
+ return llvm::StringRef();
+}
+
size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
if (IsValid()) {
if (auto type_system_sp = GetTypeSystem())
diff --git a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
index a25a1925272933..a852c93a366b34 100644
--- a/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
+++ b/lldb/test/API/commands/dwim-print/objc/TestDWIMPrintObjC.py
@@ -25,3 +25,24 @@ def test_with_summary(self):
self.runCmd("type summary add -s 'Parent of ${var._child._name}' 'Parent *'")
self.expect("dwim-print parent", matching=False, substrs=["_child = 0x"])
self.expect("dwim-print parent", substrs=['Parent of @"Seven"'])
+
+ @requireDarwin
+ def test_property_backing_storage(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "break here for backing storage", lldb.SBFileSpec("main....
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/225204
More information about the lldb-commits
mailing list