Skip to content

Commit 2db0c00

Browse files
authored
[clang][CGDebugInfo] Don't generate an implicit 'this' parameter if one was specified explicitly (llvm#100767)
Currently we would unconditionally add an implicit `this` parameter when creating an instance method type. However, when we have an explicit 'this', we shouldn't generate one. This patch only passes a valid `ThisPtr` type to `getOrCreateInstanceMethodType` if one wasn't explicitly specified. There's no way to get a pointer to a member function with an explicit `this` parameter (those are treated as regular function pointers instead). So there's no need to account for that case in `CGDebugInfo::CreateType`. Fixes llvm#99744
1 parent f6d1d6f commit 2db0c00

File tree

2 files changed

+47
-22
lines changed

2 files changed

+47
-22
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,7 +1942,12 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
19421942
if (Method->isStatic())
19431943
return cast_or_null<llvm::DISubroutineType>(
19441944
getOrCreateType(QualType(Func, 0), Unit));
1945-
return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit);
1945+
1946+
QualType ThisType;
1947+
if (!Method->hasCXXExplicitFunctionObjectParameter())
1948+
ThisType = Method->getThisType();
1949+
1950+
return getOrCreateInstanceMethodType(ThisType, Func, Unit);
19461951
}
19471952

19481953
llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
@@ -1974,27 +1979,31 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
19741979
Elts.push_back(Args[0]);
19751980

19761981
// "this" pointer is always first argument.
1977-
const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
1978-
if (isa<ClassTemplateSpecializationDecl>(RD)) {
1979-
// Create pointer type directly in this case.
1980-
const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1981-
uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
1982-
auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
1983-
llvm::DIType *PointeeType =
1984-
getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
1985-
llvm::DIType *ThisPtrType =
1986-
DBuilder.createPointerType(PointeeType, Size, Align);
1987-
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
1988-
// TODO: This and the artificial type below are misleading, the
1989-
// types aren't artificial the argument is, but the current
1990-
// metadata doesn't represent that.
1991-
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1992-
Elts.push_back(ThisPtrType);
1993-
} else {
1994-
llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
1995-
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
1996-
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
1997-
Elts.push_back(ThisPtrType);
1982+
// ThisPtr may be null if the member function has an explicit 'this'
1983+
// parameter.
1984+
if (!ThisPtr.isNull()) {
1985+
const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
1986+
if (isa<ClassTemplateSpecializationDecl>(RD)) {
1987+
// Create pointer type directly in this case.
1988+
const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
1989+
uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
1990+
auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
1991+
llvm::DIType *PointeeType =
1992+
getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
1993+
llvm::DIType *ThisPtrType =
1994+
DBuilder.createPointerType(PointeeType, Size, Align);
1995+
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
1996+
// TODO: This and the artificial type below are misleading, the
1997+
// types aren't artificial the argument is, but the current
1998+
// metadata doesn't represent that.
1999+
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
2000+
Elts.push_back(ThisPtrType);
2001+
} else {
2002+
llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
2003+
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
2004+
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
2005+
Elts.push_back(ThisPtrType);
2006+
}
19982007
}
19992008

20002009
// Copy rest of the arguments.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -std=c++2b %s -o - | FileCheck %s
2+
3+
struct Foo {
4+
void Bar(this Foo&& self) {}
5+
};
6+
7+
void fn() {
8+
Foo{}.Bar();
9+
}
10+
11+
// CHECK: distinct !DISubprogram(name: "Bar", {{.*}}, type: ![[BAR_TYPE:[0-9]+]], {{.*}}, declaration: ![[BAR_DECL:[0-9]+]], {{.*}}
12+
// CHECK: ![[FOO:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo"
13+
// CHECK: ![[BAR_DECL]] = !DISubprogram(name: "Bar", {{.*}}, type: ![[BAR_TYPE]], {{.*}},
14+
// CHECK: ![[BAR_TYPE]] = !DISubroutineType(types: ![[PARAMS:[0-9]+]])
15+
// CHECK: ![[PARAMS]] = !{null, ![[SELF:[0-9]+]]}
16+
// CHECK: ![[SELF]] = !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[FOO]]

0 commit comments

Comments
 (0)