[clang] [clang][DebugInfo] Emit DIProperty for synthesized Objective-C properties (PR #220362)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 1 13:49:28 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Piotr Jeremicz (piotrekjeremicz)
<details>
<summary>Changes</summary>
Follow-up to #<!-- -->215776, which added `DW_TAG_property` / `DIProperty` support to LLVM's DebugInfo. This patch teaches Clang's CodeGen to emit the new `DIProperty` node.
In addition to the legacy `DIObjCProperty` node, `CGDebugInfo` now also emits a `DIProperty` node whose `backing_storage` points at the ivar a synthesized property forwards to.
Covered in `clang/test/DebugInfo/ObjC/property-backing-storage.m`:
- `declaredBacking`: `@<!-- -->synthesize` binds to a custom ivar name that IS declared in the `@<!-- -->interface`.
- `undeclaredBacking`: `@<!-- -->synthesize` binds to a custom ivar name that is NOT declared; the compiler creates the ivar itself.
- `implicitBacking`: no `@<!-- -->synthesize` at all; the compiler auto-synthesizes both the accessors and a default-named ivar.
---
Full diff: https://github.com/llvm/llvm-project/pull/220362.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+15-5)
- (added) clang/test/DebugInfo/ObjC/property-backing-storage.m (+49)
``````````diff
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 2c7af395c4562..5e966e6facff3 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3733,13 +3733,17 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
Flags |= llvm::DINode::FlagBitField;
llvm::MDNode *PropertyNode = nullptr;
+ ObjCPropertyDecl *SynthesizedProperty = nullptr;
+ llvm::DIFile *PUnit = nullptr;
+ unsigned PLine = 0;
if (ObjCImplementationDecl *ImpD = ID->getImplementation()) {
if (ObjCPropertyImplDecl *PImpD =
ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
if (ObjCPropertyDecl *PD = PImpD->getPropertyDecl()) {
+ SynthesizedProperty = PD;
SourceLocation Loc = PD->getLocation();
- llvm::DIFile *PUnit = getOrCreateFile(Loc);
- unsigned PLine = getLineNumber(Loc);
+ PUnit = getOrCreateFile(Loc);
+ PLine = getLineNumber(Loc);
ObjCMethodDecl *Getter = PImpD->getGetterMethodDecl();
ObjCMethodDecl *Setter = PImpD->getSetterMethodDecl();
PropertyNode = DBuilder.createObjCProperty(
@@ -3755,10 +3759,16 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
}
}
}
- FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
- FieldSize, FieldAlign, FieldOffset, Flags,
- FieldTy, PropertyNode);
+ auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
+ FieldSize, FieldAlign, FieldOffset,
+ Flags, FieldTy, PropertyNode);
+ FieldTy = IvarTy;
EltTys.push_back(FieldTy);
+
+ if (SynthesizedProperty)
+ EltTys.push_back(DBuilder.createProperty(
+ SynthesizedProperty->getName(), PUnit, PLine,
+ getOrCreateType(SynthesizedProperty->getType(), PUnit), IvarTy));
}
llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
diff --git a/clang/test/DebugInfo/ObjC/property-backing-storage.m b/clang/test/DebugInfo/ObjC/property-backing-storage.m
new file mode 100644
index 0000000000000..22cd7aa9392ad
--- /dev/null
+++ b/clang/test/DebugInfo/ObjC/property-backing-storage.m
@@ -0,0 +1,49 @@
+// Verifies that, in addition to the legacy DIObjCProperty node, Clang also
+// emits a new DIProperty node whose backing_storage points at the ivar a
+// synthesized property forwards to. Covers the three ways a property can be
+// backed by an ivar:
+// 1. declaredBacking - @synthesize with a custom ivar name that IS
+// declared in the @interface.
+// 2. undeclaredBacking - @synthesize with a custom ivar name that is NOT
+// declared; the compiler creates the ivar itself.
+// 3. implicitBacking - no @synthesize at all; the compiler
+// auto-synthesizes both the accessors and a
+// default-named ivar (_implicitBacking).
+
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
+
+// CHECK-DAG: ![[DECLARED_PROP:[0-9]+]] = !DIObjCProperty(name: "declaredBacking"
+// CHECK-SAME: attributes: 2316
+// CHECK-SAME: type: ![[DECLARED_TY:[0-9]+]]
+// CHECK-DAG: ![[DECLARED_IVAR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "_customDeclaredIvar"
+// CHECK-SAME: extraData: ![[DECLARED_PROP]]
+// CHECK-DAG: !DIProperty(name: "declaredBacking", file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DECLARED_TY]], backing_storage: ![[DECLARED_IVAR]])
+//
+// CHECK-DAG: ![[UNDECLARED_PROP:[0-9]+]] = !DIObjCProperty(name: "undeclaredBacking"
+// CHECK-SAME: attributes: 2316
+// CHECK-SAME: type: ![[UNDECLARED_TY:[0-9]+]]
+// CHECK-DAG: ![[UNDECLARED_IVAR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "_customUndeclaredIvar"
+// CHECK-SAME: extraData: ![[UNDECLARED_PROP]]
+// CHECK-DAG: !DIProperty(name: "undeclaredBacking", file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[UNDECLARED_TY]], backing_storage: ![[UNDECLARED_IVAR]])
+//
+// CHECK-DAG: ![[IMPLICIT_PROP:[0-9]+]] = !DIObjCProperty(name: "implicitBacking"
+// CHECK-SAME: attributes: 2316
+// CHECK-SAME: type: ![[IMPLICIT_TY:[0-9]+]]
+// CHECK-DAG: ![[IMPLICIT_IVAR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "_implicitBacking"
+// CHECK-SAME: extraData: ![[IMPLICIT_PROP]]
+// CHECK-DAG: !DIProperty(name: "implicitBacking", file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[IMPLICIT_TY]], backing_storage: ![[IMPLICIT_IVAR]])
+
+ at interface C {
+ int _customDeclaredIvar;
+}
+ at property int declaredBacking;
+ at property int undeclaredBacking;
+ at property int implicitBacking;
+ at end
+
+ at implementation C
+ at synthesize declaredBacking = _customDeclaredIvar;
+ at synthesize undeclaredBacking = _customUndeclaredIvar;
+ at end
+
+void foo(C *cptr) {}
``````````
</details>
https://github.com/llvm/llvm-project/pull/220362
More information about the cfe-commits
mailing list