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

>From 48540bd7c3951ff9d994ff9c120b82faf9f38ead Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Fri, 24 Oct 2025 09:02:12 +0100
Subject: [PATCH 1/2] [clang][DebugInfo] Don't mark parameters of synthesized
 ObjC property accessors artificial

---
 clang/lib/CodeGen/CGDebugInfo.cpp             | 34 +++++++++-
 .../ObjC/property-synthesized-accessors.m     | 63 +++++++++++++++++++
 2 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/DebugInfo/ObjC/property-synthesized-accessors.m

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 12e2813ef2ec7..6af806686a3b9 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -110,6 +110,33 @@ static bool IsArtificial(VarDecl const *VD) {
                               cast<Decl>(VD->getDeclContext())->isImplicit());
 }
 
+/// Returns \c true if the specified variable \c VD is an explicit parameter of
+/// a synthesized Objective-C property accessor. E.g., a synthesized property
+/// setter method will have a single explicit parameter which is the property 
to
+/// set.
+static bool IsObjCSynthesizedPropertyExplicitParameter(VarDecl const *VD) {
+  assert(VD);
+
+  if (!llvm::isa<ParmVarDecl>(VD))
+    return false;
+
+  // Not a property method.
+  const auto *Method =
+      llvm::dyn_cast_or_null<ObjCMethodDecl>(VD->getDeclContext());
+  if (!Method)
+    return false;
+
+  // Not a synthesized property accessor.
+  if (!Method->isImplicit() || !Method->isPropertyAccessor())
+    return false;
+
+  // Not an explicit parameter.
+  if (VD->isImplicit())
+    return false;
+
+  return true;
+}
+
 CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
     : CGM(CGM), DebugKind(CGM.getCodeGenOpts().getDebugInfo()),
       DebugTypeExtRefs(CGM.getCodeGenOpts().DebugTypeExtRefs),
@@ -5158,7 +5185,12 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const 
VarDecl *VD,
   }
   SmallVector<uint64_t, 13> Expr;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
-  if (VarIsArtificial)
+
+  // While synthesized Objective-C property setters are "artificial" (i.e., 
they
+  // are not spelled out in source), we want to pretend they are just like a
+  // regular non-compiler generated method. Hence, don't mark explicitly passed
+  // parameters of such methods as artificial.
+  if (VarIsArtificial && !IsObjCSynthesizedPropertyExplicitParameter(VD))
     Flags |= llvm::DINode::FlagArtificial;
 
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
diff --git a/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m 
b/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m
new file mode 100644
index 0000000000000..6ed2885024c48
--- /dev/null
+++ b/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m
@@ -0,0 +1,63 @@
+// Test that synthesized accessors get treated like regular method 
declarations/defeinitions.
+// I.e.:
+// 1. explicitly passed parameter are not marked artificial.
+// 2. Each property accessor has a method declaration and definition.
+
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -dwarf-version=5 
-debug-info-kind=limited %s -o - | FileCheck %s --implicit-check-not 
"DIFlagArtificial"
+
+@interface Foo
+@property int p1;
+@end
+
+@implementation Foo
+@end
+
+int main(void) {
+  Foo *f;
+  f.p1 = 2;
+  return f.p1;
+}
+
+// CHECK: ![[P1_TYPE:[0-9]+]] = !DIBasicType(name: "int"
+// CHECK: ![[GETTER_DECL:[0-9]+]] = !DISubprogram(name: "-[Foo p1]"
+// CHECK-SAME:                                    type: ![[GETTER_TYPE:[0-9]+]]
+// CHECK-SAME:                                    flags: DIFlagArtificial | 
DIFlagPrototyped
+// CHECK-SAME:                                    spFlags: DISPFlagLocalToUnit)
+
+// CHECK: ![[GETTER_TYPE]] = !DISubroutineType(types: 
![[GETTER_PARAMS:[0-9]+]])
+// CHECK: ![[GETTER_PARAMS]] = !{![[P1_TYPE]], ![[ID_TYPE:[0-9]+]], 
![[SEL_TYPE:[0-9]+]]}
+// CHECK: ![[ID_TYPE]] = !DIDerivedType(tag: DW_TAG_pointer_type
+// CHECK-SAME:                          flags: DIFlagArtificial | 
DIFlagObjectPointer)
+// CHECK: ![[SEL_TYPE]] = !DIDerivedType(tag: DW_TAG_typedef, name: "SEL"
+// CHECK-SAME:                           flags: DIFlagArtificial)
+
+// CHECK: ![[SETTER_DECL:[0-9]+]] = !DISubprogram(name: "-[Foo setP1:]"
+// CHECK-SAME:                                    type: ![[SETTER_TYPE:[0-9]+]]
+// CHECK-SAME:                                    flags: DIFlagArtificial | 
DIFlagPrototyped
+// CHECK-SAME:                                    spFlags: DISPFlagLocalToUnit)
+// CHECK: ![[SETTER_TYPE]] = !DISubroutineType(types: 
![[SETTER_PARAMS:[0-9]+]])
+// CHECK: ![[SETTER_PARAMS]] = !{null, ![[ID_TYPE]], ![[SEL_TYPE]], 
![[P1_TYPE]]}
+
+// CHECK: ![[GETTER_DEF:[0-9]+]] = distinct !DISubprogram(name: "-[Foo p1]"
+// CHECK-SAME:                                            type: 
![[GETTER_TYPE]]
+// CHECK-SAME:                                            flags: 
DIFlagArtificial | DIFlagPrototyped
+// CHECK-SAME:                                            spFlags: 
DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-SAME:                                            declaration: 
![[GETTER_DECL]]
+
+// CHECK: !DILocalVariable(name: "self", arg: 1, scope: ![[GETTER_DEF]]
+// CHECK-SAME:             flags: DIFlagArtificial | DIFlagObjectPointer)
+//
+// CHECK: !DILocalVariable(name: "_cmd", arg: 2, scope: ![[GETTER_DEF]],
+// CHECK-SAME:             flags: DIFlagArtificial)
+
+// CHECK: ![[SETTER_DEF:[0-9]+]] = distinct !DISubprogram(name: "-[Foo 
setP1:]",
+// CHECK-SAME:                                            type: 
![[SETTER_TYPE]]
+// CHECK-SAME:                                            flags: 
DIFlagArtificial | DIFlagPrototyped
+// CHECK-SAME:                                            spFlags: 
DISPFlagLocalToUnit | DISPFlagDefinition
+// CHECK-SAME:                                            declaration: 
![[SETTER_DECL]]
+
+// CHECK: !DILocalVariable(name: "self", arg: 1, scope: ![[SETTER_DEF]]
+// CHECK-SAME:             flags: DIFlagArtificial | DIFlagObjectPointer
+// CHECK: !DILocalVariable(name: "_cmd", arg: 2, scope: ![[SETTER_DEF]]
+// CHECK-SAME:             flags: DIFlagArtificial
+// CHECK: !DILocalVariable(name: "p1", arg: 3, scope: ![[SETTER_DEF]]

>From 4a4f29bc272e68fa6017cd8977eb2c27b3c0fcb8 Mon Sep 17 00:00:00 2001
From: Michael Buch <[email protected]>
Date: Fri, 24 Oct 2025 17:55:53 +0100
Subject: [PATCH 2/2] fixup! fix typo

---
 clang/test/DebugInfo/ObjC/property-synthesized-accessors.m | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m 
b/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m
index 6ed2885024c48..d2e2dba9c5463 100644
--- a/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m
+++ b/clang/test/DebugInfo/ObjC/property-synthesized-accessors.m
@@ -1,4 +1,4 @@
-// Test that synthesized accessors get treated like regular method 
declarations/defeinitions.
+// Test that synthesized accessors get treated like regular method 
declarations/definitions.
 // I.e.:
 // 1. explicitly passed parameter are not marked artificial.
 // 2. Each property accessor has a method declaration and definition.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to