[clang] 9741e25 - [clang][DebugInfo] Emit DIProperty for synthesized Objective-C properties (#220362)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 3 14:07:16 PDT 2026
Author: Piotr Jeremicz
Date: 2026-09-03T14:07:11-07:00
New Revision: 9741e25af3cecae45327c8adab6b7234f767df67
URL: https://github.com/llvm/llvm-project/commit/9741e25af3cecae45327c8adab6b7234f767df67
DIFF: https://github.com/llvm/llvm-project/commit/9741e25af3cecae45327c8adab6b7234f767df67.diff
LOG: [clang][DebugInfo] Emit DIProperty for synthesized Objective-C properties (#220362)
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.
Added:
clang/test/DebugInfo/ObjC/property-backing-storage.m
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index fdb5d869c441b..02864621d60a3 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3748,13 +3748,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(
@@ -3770,10 +3774,17 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty,
}
}
}
- FieldTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
- FieldSize, FieldAlign, FieldOffset, Flags,
- FieldTy, PropertyNode);
- EltTys.push_back(FieldTy);
+ auto *IvarTy = DBuilder.createObjCIVar(FieldName, FieldDefUnit, FieldLine,
+ FieldSize, FieldAlign, FieldOffset,
+ Flags, FieldTy, PropertyNode);
+ EltTys.push_back(IvarTy);
+
+ if (SynthesizedProperty) {
+ assert(PUnit && "SynthesizedProperty implies PUnit");
+ 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..456926e3a9dd4
--- /dev/null
+++ b/clang/test/DebugInfo/ObjC/property-backing-storage.m
@@ -0,0 +1,41 @@
+// 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", file: ![[FILE:[0-9]+]], line: {{[0-9]+}}, attributes: 2316, type: ![[INT_TY:[0-9]+]])
+// CHECK-DAG: ![[UNDECLARED_PROP:[0-9]+]] = !DIObjCProperty(name: "undeclaredBacking", file: ![[FILE]], line: {{[0-9]+}}, attributes: 2316, type: ![[INT_TY]])
+// CHECK-DAG: ![[IMPLICIT_PROP:[0-9]+]] = !DIObjCProperty(name: "implicitBacking", file: ![[FILE]], line: {{[0-9]+}}, attributes: 2316, type: ![[INT_TY]])
+//
+// CHECK-DAG: ![[DECLARED_IVAR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "_customDeclaredIvar", {{.*}}file: ![[FILE]], {{.*}}extraData: ![[DECLARED_PROP]])
+// CHECK-DAG: !DIProperty(name: "declaredBacking", file: ![[FILE]], line: {{[0-9]+}}, type: ![[INT_TY]], backing_storage: ![[DECLARED_IVAR]])
+//
+// CHECK-DAG: ![[UNDECLARED_IVAR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "_customUndeclaredIvar", {{.*}}file: ![[FILE]], {{.*}}extraData: ![[UNDECLARED_PROP]])
+// CHECK-DAG: !DIProperty(name: "undeclaredBacking", file: ![[FILE]], line: {{[0-9]+}}, type: ![[INT_TY]], backing_storage: ![[UNDECLARED_IVAR]])
+//
+// CHECK-DAG: ![[IMPLICIT_IVAR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "_implicitBacking", {{.*}}file: ![[FILE]], {{.*}}extraData: ![[IMPLICIT_PROP]])
+// CHECK-DAG: !DIProperty(name: "implicitBacking", file: ![[FILE]], line: {{[0-9]+}}, type: ![[INT_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) {}
More information about the cfe-commits
mailing list