https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/100767
>From 427fe3468534d31778ae361cc057dad817ecffea Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Fri, 26 Jul 2024 16:40:04 +0100 Subject: [PATCH 1/2] [clang][CGDebugInfo] Don't generate an implicit 'this' parameter if one was specified explicitly 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 --- clang/lib/CodeGen/CGDebugInfo.cpp | 52 +++++++++++-------- .../CodeGenCXX/debug-info-explicit-this.cpp | 16 ++++++ 2 files changed, 46 insertions(+), 22 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-explicit-this.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 3d8a715b692de..ac31f5ce8a801 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,30 @@ 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]] >From 2475c151596ffcdd91f049d3f976808dc7c6ce1d Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Fri, 26 Jul 2024 16:48:45 +0100 Subject: [PATCH 2/2] fixup! clang-format --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index ac31f5ce8a801..b49dee24c3c1a 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1979,7 +1979,8 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType( Elts.push_back(Args[0]); // "this" pointer is always first argument. - // ThisPtr may be null if the member function has an explicit 'this' parameter. + // 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)) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits