Skip to content

Commit 3d24c77

Browse files
authored
[clang][DebugInfo] Emit DW_AT_object_pointer on function definitions with explicit this (#122897)
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 Fixing this will help LLDB in identifying static vs. non-static member functions (see #120856). 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. Partially fixes #120974
1 parent 93fd72c commit 3d24c77

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4829,6 +4829,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
48294829
if (IPD->getParameterKind() == ImplicitParamKind::CXXThis ||
48304830
IPD->getParameterKind() == ImplicitParamKind::ObjCSelf)
48314831
Flags |= llvm::DINode::FlagObjectPointer;
4832+
} else if (const auto *PVD = dyn_cast<ParmVarDecl>(VD)) {
4833+
if (PVD->isExplicitObjectParameter())
4834+
Flags |= llvm::DINode::FlagObjectPointer;
48324835
}
48334836

48344837
// Note: Older versions of clang used to emit byval references with an extra
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -x c++ -std=c++23 -debug-info-kind=limited -emit-llvm < %s | FileCheck %s
2+
3+
// CHECK: !DISubprogram(name: "bar",
4+
// CHECK-SAME: flags: DIFlagPrototyped
5+
// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
6+
// CHECK-SAME: flags: DIFlagArtificial | DIFlagObjectPointer
7+
//
8+
// // FIXME: DIFlagObjectPointer not attached to the explicit object
9+
// // argument in the subprogram declaration.
10+
// CHECK: !DISubprogram(name: "explicit_this",
11+
// flags: DIFlagPrototyped
12+
// CHECK-NOT: DIFlagObjectPointer
13+
// CHECK-NOT: DIFlagArtificial
14+
//
15+
// CHECK: !DILocalVariable(name: "this", arg: 1
16+
// CHECK-SAME: flags: DIFlagArtificial | DIFlagObjectPointer
17+
//
18+
// CHECK-NOT: DIFlagArtificial
19+
// CHECK: !DILocalVariable(arg: 1, {{.*}}, flags: DIFlagObjectPointer)
20+
21+
struct Foo {
22+
void bar() {}
23+
void explicit_this(this Foo &&) {}
24+
};
25+
26+
void f() {
27+
Foo{}.bar();
28+
Foo{}.explicit_this();
29+
}

0 commit comments

Comments
 (0)