llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Michael Buch (Michael137)

<details>
<summary>Changes</summary>

We currently don't emit `DW_AT_object_pointer` on function declarations or 
definitions. GCC suffers from the same issue: https://godbolt.org/z/h4jeT54G5

If I interpreted the DWARFv5 spec correctly, it doesn't mandate this attribute 
be present *only* for implicit object parameters:
```
If the member function entry describes a non-static member function,
then that entry has a DW_AT_object_pointer attribute whose value is a reference 
to
the formal parameter entry that corresponds to the object for which the
function is called.

That parameter also has a DW_AT_artificial attribute whose value is true.
```

This patch attaches the `DW_AT_object_pointer` for function *defintions*. The 
declarations will be handled in a separate patch.

The part about `DW_AT_artificial` seems overly restrictive, and not true for 
explicit object parameters. We probably should relax this part of the DWARF 
spec.

This will help LLDB identify static vs. non-static member functions (see 
https://github.com/llvm/llvm-project/issues/120856).

Partially fixes https://github.com/llvm/llvm-project/issues/120974

---
Full diff: https://github.com/llvm/llvm-project/pull/122897.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+3) 
- (added) clang/test/CodeGenCXX/debug-info-object-pointer.cpp (+29) 


``````````diff
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index d7e5e95b7873a0..f9cba414dcfe2c 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4829,6 +4829,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const 
VarDecl *VD,
     if (IPD->getParameterKind() == ImplicitParamKind::CXXThis ||
         IPD->getParameterKind() == ImplicitParamKind::ObjCSelf)
       Flags |= llvm::DINode::FlagObjectPointer;
+  } else if (const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
+    if (PVD->isExplicitObjectParameter())
+      Flags |= llvm::DINode::FlagObjectPointer;
   }
 
   // Note: Older versions of clang used to emit byval references with an extra
diff --git a/clang/test/CodeGenCXX/debug-info-object-pointer.cpp 
b/clang/test/CodeGenCXX/debug-info-object-pointer.cpp
new file mode 100644
index 00000000000000..594d4da791ee84
--- /dev/null
+++ b/clang/test/CodeGenCXX/debug-info-object-pointer.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -x c++ -std=c++23 -debug-info-kind=limited -emit-llvm < %s 
| FileCheck %s
+
+// CHECK: !DISubprogram(name: "bar",
+// CHECK-SAME:          flags: DIFlagPrototyped
+// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
+// CHECK-SAME:           flags: DIFlagArtificial | DIFlagObjectPointer
+//
+// // FIXME: DIFlagObjectPointer not attached to the explicit object
+// // argument in the subprogram declaration.
+// CHECK: !DISubprogram(name: "explicit_this",
+//                      flags: DIFlagPrototyped
+// CHECK-NOT: DIFlagObjectPointer
+// CHECK-NOT: DIFlagArtificial
+//
+// CHECK: !DILocalVariable(name: "this", arg: 1
+// CHECK-SAME:             flags: DIFlagArtificial | DIFlagObjectPointer
+//
+// CHECK-NOT: DIFlagArtificial
+// CHECK: !DILocalVariable(arg: 1, {{.*}}, flags: DIFlagObjectPointer)
+
+struct Foo {
+  void bar() {}
+  void explicit_this(this Foo &&) {}
+};
+
+void f() {
+  Foo{}.bar();
+  Foo{}.explicit_this();
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/122897
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to