[llvm] [llvm][DebugInfo][ObjC] Make sure we link backing ivars to their DW_TAG_APPLE_property (PR #165409)

Michael Buch via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 31 02:45:30 PDT 2025


https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/165409

>From a6f525fcc0a2ae45b2e449a1a75ce7849ffdba24 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 28 Oct 2025 16:31:55 +0000
Subject: [PATCH 1/5] [llvm][dwarfdump] Show name of referenced
 DW_TAG_APPLE_property

---
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp         |  28 ++++
 .../AArch64/DW_AT_APPLE_property.s            | 126 ++++++++++++++++++
 2 files changed, 154 insertions(+)
 create mode 100644 llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index db5cc37c93f90..94da588c439d4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -129,6 +129,25 @@ prettyLanguageVersionString(const DWARFAttribute &AttrValue,
       static_cast<SourceLanguageName>(*LName), *LVersion);
 }
 
+static llvm::Expected<llvm::StringRef>
+getApplePropertyName(const DWARFDie &PropDIE) {
+  if (!PropDIE)
+    return llvm::createStringError("invalid DIE");
+ 
+  if (PropDIE.getTag() != DW_TAG_APPLE_property)
+    return llvm::createStringError("referencing not a DW_TAG_APPLE_property");
+
+  auto PropNameForm = PropDIE.find(DW_AT_APPLE_property_name);
+  if (!PropNameForm)
+    return "";
+
+  auto NameOrErr = PropNameForm->getAsCString();
+  if (!NameOrErr)
+    return NameOrErr.takeError();
+
+  return *NameOrErr;
+}
+
 static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
                           const DWARFAttribute &AttrValue, unsigned Indent,
                           DIDumpOptions DumpOpts) {
@@ -233,6 +252,15 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
             Die.getAttributeValueAsReferencedDie(FormValue).getName(
                 DINameKind::LinkageName))
       OS << Space << "\"" << Name << '\"';
+  } else if (Attr == DW_AT_APPLE_property) {
+    auto PropDIE = Die.getAttributeValueAsReferencedDie(FormValue);
+    if (auto PropNameOrErr = getApplePropertyName(PropDIE))
+      OS << Space << "\"" << *PropNameOrErr << '\"';
+    else
+      DumpOpts.RecoverableErrorHandler(createStringError(
+          errc::invalid_argument,
+          llvm::formatv("decoding DW_AT_APPLE_property_name: {}",
+                        toString(PropNameOrErr.takeError()))));
   } else if (Attr == DW_AT_type || Attr == DW_AT_containing_type) {
     DWARFDie D = resolveReferencedType(Die, FormValue);
     if (D && !D.isNULL()) {
diff --git a/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s b/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s
new file mode 100644
index 0000000000000..416ad352c2254
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s
@@ -0,0 +1,126 @@
+# Checks that we correctly display the DW_AT_APPLE_property_name of a
+# referenced DW_TAG_APPLE_property.
+#
+# RUN: llvm-mc -triple=aarch64--darwin -filetype=obj -o %t.o < %s
+# RUN: not llvm-dwarfdump %t.o 2> %t.errs.txt | FileCheck %s
+# RUN: FileCheck %s --check-prefix=ERRORS < %t.errs.txt 
+
+# CHECK: 0x[[PROP_REF:[0-9a-f]+]]: DW_TAG_APPLE_property
+# CHECK-NEXT: DW_AT_APPLE_property_name ("autoSynthProp")
+#
+# CHECK: 0x[[NO_NAME_PROP:[0-9a-f]+]]: DW_TAG_APPLE_property
+# CHECK-NOT: DW_AT_APPLE_property_name
+#
+# CHECK: 0x[[INVALID_STRP:[0-9a-f]+]]: DW_TAG_APPLE_property
+# CHECK-NEXT: DW_AT_APPLE_property_name
+#
+# CHECK: DW_TAG_member
+# CHECK:   DW_AT_APPLE_property  (0x[[PROP_REF]] "autoSynthProp")
+# CHECK:   DW_AT_APPLE_property  (0x[[NO_NAME_PROP]] "")
+# CHECK:   DW_AT_APPLE_property  (0x{{.*}})
+# CHECK:   DW_AT_APPLE_property  (0x{{.*}})
+# CHECK:   DW_AT_APPLE_property  (0x[[INVALID_STRP]])
+
+# ERRORS: error: decoding DW_AT_APPLE_property_name: referencing not a DW_TAG_APPLE_property
+# ERRORS: error: decoding DW_AT_APPLE_property_name: invalid DIE
+# ERRORS: error: decoding DW_AT_APPLE_property_name: DW_FORM_strp offset 102 is beyond .debug_str bounds
+
+	.section	__DWARF,__debug_abbrev,regular,debug
+Lsection_abbrev:
+	.byte	1                               ; Abbreviation Code
+	.byte	17                              ; DW_TAG_compile_unit
+	.byte	1                               ; DW_CHILDREN_yes
+	.byte	114                             ; DW_AT_str_offsets_base
+	.byte	23                              ; DW_FORM_sec_offset
+	.byte	0                               ; EOM(1)
+	.byte	0                               ; EOM(2)
+	.byte	2                               ; Abbreviation Code
+	.byte	19                              ; DW_TAG_structure_type
+	.byte	1                               ; DW_CHILDREN_yes
+	.byte	3                               ; DW_AT_name
+	.byte	37                              ; DW_FORM_strx1
+	.byte	0                               ; EOM(1)
+	.byte	0                               ; EOM(2)
+	.byte	3                               ; Abbreviation Code
+	.ascii	"\200\204\001"                  ; DW_TAG_APPLE_property
+	.byte	0                               ; DW_CHILDREN_no
+	.ascii	"\350\177"                      ; DW_AT_APPLE_property_name
+	.byte	37                              ; DW_FORM_strx1
+	.byte	0                               ; EOM(1)
+	.byte	0                               ; EOM(2)
+	.byte	4                               ; Abbreviation Code
+	.ascii	"\200\204\001"                  ; DW_TAG_APPLE_property
+	.byte	0                               ; DW_CHILDREN_no
+	.byte	0                               ; EOM(1)
+	.byte	0                               ; EOM(2)
+	.byte	5                               ; Abbreviation Code
+	.ascii	"\200\204\001"                  ; DW_TAG_APPLE_property
+	.byte	0                               ; DW_CHILDREN_no
+	.ascii	"\350\177"                      ; DW_AT_APPLE_property_name
+	.byte	14                              ; DW_FORM_strp
+	.byte	0                               ; EOM(1)
+	.byte	0                               ; EOM(2)
+	.byte	6                               ; Abbreviation Code
+	.byte	13                              ; DW_TAG_member
+	.byte	0                               ; DW_CHILDREN_no
+	.byte	3                               ; DW_AT_name
+	.byte	37                              ; DW_FORM_strx1
+	.ascii	"\355\177"                      ; DW_AT_APPLE_property
+	.byte	19                              ; DW_FORM_ref4
+	.ascii	"\355\177"                      ; DW_AT_APPLE_property
+	.byte	19                              ; DW_FORM_ref4
+	.ascii	"\355\177"                      ; DW_AT_APPLE_property
+	.byte	19                              ; DW_FORM_ref4
+	.ascii	"\355\177"                      ; DW_AT_APPLE_property
+	.byte	19                              ; DW_FORM_ref4
+	.ascii	"\355\177"                      ; DW_AT_APPLE_property
+	.byte	19                              ; DW_FORM_ref4
+	.byte	0                               ; EOM(1)
+	.byte	0                               ; EOM(2)
+	.byte	0                               ; EOM(3)
+	.section	__DWARF,__debug_info,regular,debug
+Lsection_info:
+Lcu_begin0:
+Lset0 = Ldebug_info_end0-Ldebug_info_start0 ; Length of Unit
+	.long	Lset0
+Ldebug_info_start0:
+	.short	5                               ; DWARF version number
+	.byte	1                               ; DWARF Unit Type
+	.byte	8                               ; Address Size (in bytes)
+Lset1 = Lsection_abbrev-Lsection_abbrev ; Offset Into Abbrev. Section
+	.long	Lset1
+	.byte	1                               ; Abbrev [1] DW_TAG_compile_unit
+Lset2 = Lstr_offsets_base0-Lsection_str_off ; DW_AT_str_offsets_base
+	.long	Lset2
+	.byte	2                               ; Abbrev [2] DW_TAG_structure_type
+	.byte	2                               ; DW_AT_name
+	.byte	3                               ; Abbrev [3] DW_TAG_APPLE_property
+	.byte	0                               ; DW_AT_APPLE_property_name
+	.byte	4                               ; Abbrev [4] DW_TAG_APPLE_property
+	.byte	5                               ; Abbrev [5] DW_TAG_APPLE_property
+	.long	102                             ; DW_AT_APPLE_property_name
+	.byte	6                               ; Abbrev [6] DW_TAG_member
+	.byte	1                               ; DW_AT_name
+	.long	19                              ; DW_AT_APPLE_property
+	.long	21                              ; DW_AT_APPLE_property
+	.long	17                              ; DW_AT_APPLE_property
+	.long	0                               ; DW_AT_APPLE_property
+	.long	22                              ; DW_AT_APPLE_property
+	.byte	0                               ; End Of Children Mark
+	.byte	0                               ; End Of Children Mark
+Ldebug_info_end0:
+	.section	__DWARF,__debug_str_offs,regular,debug
+Lsection_str_off:
+	.long	16                              ; Length of String Offsets Set
+	.short	5
+	.short	0
+Lstr_offsets_base0:
+	.section	__DWARF,__debug_str,regular,debug
+Linfo_string:
+	.asciz	"autoSynthProp"                 ; string offset=0
+	.asciz	"_var"                          ; string offset=14
+	.asciz	"Foo"                           ; string offset=19
+	.section	__DWARF,__debug_str_offs,regular,debug
+	.long	0
+	.long	14
+	.long	19

>From ee38d2dd3e8f8c978e20715d29eb17f6283dda33 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 29 Oct 2025 10:27:25 +0000
Subject: [PATCH 2/5] fixup! clang-format

---
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 94da588c439d4..ca96d4153741c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -133,7 +133,7 @@ static llvm::Expected<llvm::StringRef>
 getApplePropertyName(const DWARFDie &PropDIE) {
   if (!PropDIE)
     return llvm::createStringError("invalid DIE");
- 
+
   if (PropDIE.getTag() != DW_TAG_APPLE_property)
     return llvm::createStringError("referencing not a DW_TAG_APPLE_property");
 

>From 144f6ce7c827c1c31fd60a39727d62a0c85d553e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 31 Oct 2025 09:05:57 +0000
Subject: [PATCH 3/5] fixup! reword error

---
 llvm/lib/DebugInfo/DWARF/DWARFDie.cpp                         | 2 +-
 llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index ca96d4153741c..6c78ef05e1b61 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -135,7 +135,7 @@ getApplePropertyName(const DWARFDie &PropDIE) {
     return llvm::createStringError("invalid DIE");
 
   if (PropDIE.getTag() != DW_TAG_APPLE_property)
-    return llvm::createStringError("referencing not a DW_TAG_APPLE_property");
+    return llvm::createStringError("not referencing a DW_TAG_APPLE_property");
 
   auto PropNameForm = PropDIE.find(DW_AT_APPLE_property_name);
   if (!PropNameForm)
diff --git a/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s b/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s
index 416ad352c2254..6c38791b0a083 100644
--- a/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s
+++ b/llvm/test/tools/llvm-dwarfdump/AArch64/DW_AT_APPLE_property.s
@@ -21,7 +21,7 @@
 # CHECK:   DW_AT_APPLE_property  (0x{{.*}})
 # CHECK:   DW_AT_APPLE_property  (0x[[INVALID_STRP]])
 
-# ERRORS: error: decoding DW_AT_APPLE_property_name: referencing not a DW_TAG_APPLE_property
+# ERRORS: error: decoding DW_AT_APPLE_property_name: not referencing a DW_TAG_APPLE_property
 # ERRORS: error: decoding DW_AT_APPLE_property_name: invalid DIE
 # ERRORS: error: decoding DW_AT_APPLE_property_name: DW_FORM_strp offset 102 is beyond .debug_str bounds
 

>From b30580c557cfa143ae9169c68895c99289ac43f4 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 28 Oct 2025 14:27:46 +0000
Subject: [PATCH 4/5] [llvm][DebugInfo][ObjC] Make sure we link backing ivars
 to their DW_TAG_APPLE_property

Depends on:
* https://github.com/llvm/llvm-project/pull/165373

When an Objective-C property has a backing ivar, we would previously not add a `DW_AT_APPLE_property` to the ivar's `DW_TAG_member`. This is what was intended based on the [Objective-C DebugInfo docs](https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#proposal) but is not what LLVM currently generates.

LLDB currently doesn't ever try linking the `ObjCPropertyDecl`s to their `ObjCIvarDecl`s, but if we wanted to, this debug-info patch is a pre-requisite.
---
 llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp    |  2 +-
 llvm/test/DebugInfo/Generic/objc-property.ll | 26 ++++++++++++--------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 555c56fd322bb..b16e131529ac3 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1120,7 +1120,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
           constructMemberDIE(Buffer, DDTy);
         }
       } else if (auto *Property = dyn_cast<DIObjCProperty>(Element)) {
-        DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer);
+        DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer, Property);
         StringRef PropertyName = Property->getName();
         addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
         if (Property->getType())
diff --git a/llvm/test/DebugInfo/Generic/objc-property.ll b/llvm/test/DebugInfo/Generic/objc-property.ll
index 007d1fe698b30..68362fcb4bde4 100644
--- a/llvm/test/DebugInfo/Generic/objc-property.ll
+++ b/llvm/test/DebugInfo/Generic/objc-property.ll
@@ -5,33 +5,33 @@
 ; CHECK: DW_TAG_structure_type
 ; CHECK:   DW_AT_name ("Foo")
 ;
-; CHECK:   DW_TAG_APPLE_property
+; CHECK:   0x[[AUTO_SYNTH:[0-9a-f]+]]: DW_TAG_APPLE_property
 ; CHECK:     DW_AT_APPLE_property_name ("autoSynthProp")
 ; CHECK:     DW_AT_APPLE_property_attribute
 ; CHECK-SAME: DW_APPLE_PROPERTY_assign, DW_APPLE_PROPERTY_readwrite,
 ; CHECK-SAME: DW_APPLE_PROPERTY_atomic, DW_APPLE_PROPERTY_unsafe_unretained
 ;
-; CHECK:   DW_TAG_APPLE_property
+; CHECK:   0x[[SYNTH:[0-9a-f]+]]: DW_TAG_APPLE_property
 ; CHECK:     DW_AT_APPLE_property_name ("synthProp")
 ; CHECK:     DW_AT_APPLE_property_attribute
 ; CHECK-SAME: DW_APPLE_PROPERTY_assign, DW_APPLE_PROPERTY_readwrite,
 ; CHECK-SAME: DW_APPLE_PROPERTY_atomic, DW_APPLE_PROPERTY_unsafe_unretained
 ;
-; CHECK:   DW_TAG_APPLE_property
+; CHECK:   0x[[GET:[0-9a-f]+]]: DW_TAG_APPLE_property
 ; CHECK:     DW_AT_APPLE_property_name ("customGetterProp")
 ; CHECK:     DW_AT_APPLE_property_getter   ("customGetter")
 ; CHECK:     DW_AT_APPLE_property_attribute
 ; CHECK-SAME: DW_APPLE_PROPERTY_getter, DW_APPLE_PROPERTY_assign, DW_APPLE_PROPERTY_readwrite,
 ; CHECK-SAME: DW_APPLE_PROPERTY_atomic, DW_APPLE_PROPERTY_unsafe_unretained
 ;
-; CHECK:   DW_TAG_APPLE_property
+; CHECK:   0x[[SET:[0-9a-f]+]]: DW_TAG_APPLE_property
 ; CHECK:     DW_AT_APPLE_property_name ("customSetterProp")
 ; CHECK:     DW_AT_APPLE_property_setter   ("customSetter:")
 ; CHECK:     DW_AT_APPLE_property_attribute
 ; CHECK-SAME: DW_APPLE_PROPERTY_assign, DW_APPLE_PROPERTY_readwrite,
 ; CHECK-SAME: DW_APPLE_PROPERTY_setter, DW_APPLE_PROPERTY_atomic, DW_APPLE_PROPERTY_unsafe_unretained
 ;
-; CHECK:   DW_TAG_APPLE_property
+; CHECK:   0x[[ACCESSORS:[0-9a-f]+]]: DW_TAG_APPLE_property
 ; CHECK:     DW_AT_APPLE_property_name ("customAccessorsProp")
 ; CHECK:     DW_AT_APPLE_property_getter   ("customGetter")
 ; CHECK:     DW_AT_APPLE_property_setter   ("customSetter:")
@@ -39,15 +39,21 @@
 ; CHECK-SAME: DW_APPLE_PROPERTY_getter, DW_APPLE_PROPERTY_assign, DW_APPLE_PROPERTY_readwrite,
 ; CHECK-SAME: DW_APPLE_PROPERTY_setter, DW_APPLE_PROPERTY_atomic, DW_APPLE_PROPERTY_unsafe_unretained
 ;
-; FIXME: missing link between DW_TAG_member and the associated DW_TAG_APPLE_property
 ; CHECK:   DW_TAG_member
-; CHECK-NOT: DW_AT_APPLE_property
+; CHECK:     DW_AT_name ("someBackingIvar")
+; CHECK:     DW_AT_APPLE_property (0x[[SYNTH]])
+;
 ; CHECK:   DW_TAG_member
-; CHECK-NOT: DW_AT_APPLE_property
+; CHECK:     DW_AT_name ("_autoSynthProp")
+; CHECK:     DW_AT_APPLE_property (0x[[AUTO_SYNTH]])
+;
 ; CHECK:   DW_TAG_member
-; CHECK-NOT: DW_AT_APPLE_property
+; CHECK:     DW_AT_name ("_customGetterProp")
+; CHECK:     DW_AT_APPLE_property (0x[[GET]])
+;
 ; CHECK:   DW_TAG_member
-; CHECK-NOT: DW_AT_APPLE_property
+; CHECK:     DW_AT_name ("_customSetterProp")
+; CHECK:     DW_AT_APPLE_property (0x[[SET]])
 
 !llvm.module.flags = !{!0, !1}
 !llvm.dbg.cu = !{!2}

>From 8416728afcc409b25233deb88cf71f538280bb7d Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 31 Oct 2025 09:14:00 +0000
Subject: [PATCH 5/5] fixup! fix dwarfdump output in tests

---
 llvm/test/DebugInfo/Generic/objc-property.ll | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/test/DebugInfo/Generic/objc-property.ll b/llvm/test/DebugInfo/Generic/objc-property.ll
index 68362fcb4bde4..1ee792941bcbb 100644
--- a/llvm/test/DebugInfo/Generic/objc-property.ll
+++ b/llvm/test/DebugInfo/Generic/objc-property.ll
@@ -41,19 +41,19 @@
 ;
 ; CHECK:   DW_TAG_member
 ; CHECK:     DW_AT_name ("someBackingIvar")
-; CHECK:     DW_AT_APPLE_property (0x[[SYNTH]])
+; CHECK:     DW_AT_APPLE_property (0x[[SYNTH]] "synthProp")
 ;
 ; CHECK:   DW_TAG_member
 ; CHECK:     DW_AT_name ("_autoSynthProp")
-; CHECK:     DW_AT_APPLE_property (0x[[AUTO_SYNTH]])
+; CHECK:     DW_AT_APPLE_property (0x[[AUTO_SYNTH]] "autoSynthProp")
 ;
 ; CHECK:   DW_TAG_member
 ; CHECK:     DW_AT_name ("_customGetterProp")
-; CHECK:     DW_AT_APPLE_property (0x[[GET]])
+; CHECK:     DW_AT_APPLE_property (0x[[GET]] "customGetterProp")
 ;
 ; CHECK:   DW_TAG_member
 ; CHECK:     DW_AT_name ("_customSetterProp")
-; CHECK:     DW_AT_APPLE_property (0x[[SET]])
+; CHECK:     DW_AT_APPLE_property (0x[[SET]] "customSetterProp")
 
 !llvm.module.flags = !{!0, !1}
 !llvm.dbg.cu = !{!2}



More information about the llvm-commits mailing list