[clang] 2db0c00 - [clang][CGDebugInfo] Don't generate an implicit 'this' parameter if one was specified explicitly (#100767)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 29 00:47:06 PDT 2024
Author: Michael Buch
Date: 2024-07-29T08:47:02+01:00
New Revision: 2db0c00e6092947fa07cc587c4a7537213bbc093
URL: https://github.com/llvm/llvm-project/commit/2db0c00e6092947fa07cc587c4a7537213bbc093
DIFF: https://github.com/llvm/llvm-project/commit/2db0c00e6092947fa07cc587c4a7537213bbc093.diff
LOG: [clang][CGDebugInfo] Don't generate an implicit 'this' parameter if one was specified explicitly (#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 https://github.com/llvm/llvm-project/issues/99744
Added:
clang/test/CodeGenCXX/debug-info-explicit-this.cpp
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3d8a715b692de..b49dee24c3c1a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1942,7 +1942,12 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
if (Method->isStatic())
return cast_or_null<llvm::DISubroutineType>(
getOrCreateType(QualType(Func, 0), Unit));
- return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit);
+
+ QualType ThisType;
+ if (!Method->hasCXXExplicitFunctionObjectParameter())
+ ThisType = Method->getThisType();
+
+ return getOrCreateInstanceMethodType(ThisType, Func, Unit);
}
llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
@@ -1974,27 +1979,31 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
Elts.push_back(Args[0]);
// "this" pointer is always first argument.
- const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
- if (isa<ClassTemplateSpecializationDecl>(RD)) {
- // Create pointer type directly in this case.
- const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
- uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
- auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
- llvm::DIType *PointeeType =
- getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
- llvm::DIType *ThisPtrType =
- DBuilder.createPointerType(PointeeType, Size, Align);
- TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
- // TODO: This and the artificial type below are misleading, the
- // types aren't artificial the argument is, but the current
- // metadata doesn't represent that.
- ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
- Elts.push_back(ThisPtrType);
- } else {
- llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
- TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
- ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
- Elts.push_back(ThisPtrType);
+ // ThisPtr may be null if the member function has an explicit 'this'
+ // parameter.
+ if (!ThisPtr.isNull()) {
+ const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
+ if (isa<ClassTemplateSpecializationDecl>(RD)) {
+ // Create pointer type directly in this case.
+ const PointerType *ThisPtrTy = cast<PointerType>(ThisPtr);
+ uint64_t Size = CGM.getContext().getTypeSize(ThisPtrTy);
+ auto Align = getTypeAlignIfRequired(ThisPtrTy, CGM.getContext());
+ llvm::DIType *PointeeType =
+ getOrCreateType(ThisPtrTy->getPointeeType(), Unit);
+ llvm::DIType *ThisPtrType =
+ DBuilder.createPointerType(PointeeType, Size, Align);
+ TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
+ // TODO: This and the artificial type below are misleading, the
+ // types aren't artificial the argument is, but the current
+ // metadata doesn't represent that.
+ ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
+ Elts.push_back(ThisPtrType);
+ } else {
+ llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
+ TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
+ ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
+ Elts.push_back(ThisPtrType);
+ }
}
// Copy rest of the arguments.
diff --git a/clang/test/CodeGenCXX/debug-info-explicit-this.cpp b/clang/test/CodeGenCXX/debug-info-explicit-this.cpp
new file mode 100644
index 0000000000000..45ab2a0216ca7
--- /dev/null
+++ b/clang/test/CodeGenCXX/debug-info-explicit-this.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -std=c++2b %s -o - | FileCheck %s
+
+struct Foo {
+ void Bar(this Foo&& self) {}
+};
+
+void fn() {
+ Foo{}.Bar();
+}
+
+// CHECK: distinct !DISubprogram(name: "Bar", {{.*}}, type: ![[BAR_TYPE:[0-9]+]], {{.*}}, declaration: ![[BAR_DECL:[0-9]+]], {{.*}}
+// CHECK: ![[FOO:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Foo"
+// CHECK: ![[BAR_DECL]] = !DISubprogram(name: "Bar", {{.*}}, type: ![[BAR_TYPE]], {{.*}},
+// CHECK: ![[BAR_TYPE]] = !DISubroutineType(types: ![[PARAMS:[0-9]+]])
+// CHECK: ![[PARAMS]] = !{null, ![[SELF:[0-9]+]]}
+// CHECK: ![[SELF]] = !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[FOO]]
More information about the cfe-commits
mailing list