Skip to content

Commit 27c1aa9

Browse files
authored
[Clang,debuginfo] added vtt parameter in destructor DISubroutineType (llvm#130674)
Fixes issue llvm#104765: When creating a virtual destructor with an artificial "vtt" argument, the type of "vtt" was previously missing in the `DISubroutineType` `types` array. This commit fixes this behavior and adds a regression test.
1 parent 38ca73d commit 27c1aa9

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -2018,8 +2018,17 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
20182018
return getOrCreateInstanceMethodType(ThisType, Func, Unit);
20192019
}
20202020

2021-
llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
2022-
QualType ThisPtr, const FunctionProtoType *Func, llvm::DIFile *Unit) {
2021+
llvm::DISubroutineType *CGDebugInfo::getOrCreateMethodTypeForDestructor(
2022+
const CXXMethodDecl *Method, llvm::DIFile *Unit, QualType FNType) {
2023+
const FunctionProtoType *Func = FNType->getAs<FunctionProtoType>();
2024+
// skip the first param since it is also this
2025+
return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit, true);
2026+
}
2027+
2028+
llvm::DISubroutineType *
2029+
CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
2030+
const FunctionProtoType *Func,
2031+
llvm::DIFile *Unit, bool SkipFirst) {
20232032
FunctionProtoType::ExtProtoInfo EPI = Func->getExtProtoInfo();
20242033
Qualifiers &Qc = EPI.TypeQuals;
20252034
Qc.removeConst();
@@ -2059,7 +2068,7 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
20592068
}
20602069

20612070
// Copy rest of the arguments.
2062-
for (unsigned i = 1, e = Args.size(); i != e; ++i)
2071+
for (unsigned i = (SkipFirst ? 2 : 1), e = Args.size(); i != e; ++i)
20632072
Elts.push_back(Args[i]);
20642073

20652074
// Attach FlagObjectPointer to the explicit "this" parameter.
@@ -4372,6 +4381,12 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D,
43724381
// subprogram DIE will miss DW_AT_decl_file and DW_AT_decl_line fields.
43734382
return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray({}));
43744383

4384+
if (const auto *Method = dyn_cast<CXXDestructorDecl>(D)) {
4385+
// Read method type from 'FnType' because 'D.getType()' does not cover
4386+
// implicit arguments for destructors.
4387+
return getOrCreateMethodTypeForDestructor(Method, F, FnType);
4388+
}
4389+
43754390
if (const auto *Method = dyn_cast<CXXMethodDecl>(D))
43764391
return getOrCreateMethodType(Method, F);
43774392

clang/lib/CodeGen/CGDebugInfo.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,14 @@ class CGDebugInfo {
249249
/// to get a method type which includes \c this pointer.
250250
llvm::DISubroutineType *getOrCreateMethodType(const CXXMethodDecl *Method,
251251
llvm::DIFile *F);
252+
253+
llvm::DISubroutineType *
254+
getOrCreateMethodTypeForDestructor(const CXXMethodDecl *Method,
255+
llvm::DIFile *F, QualType FNType);
256+
252257
llvm::DISubroutineType *
253258
getOrCreateInstanceMethodType(QualType ThisPtr, const FunctionProtoType *Func,
254-
llvm::DIFile *Unit);
259+
llvm::DIFile *Unit, bool SkipFirst = false);
255260
llvm::DISubroutineType *
256261
getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
257262
/// \return debug info descriptor for vtable.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm -debug-info-kind=limited %s -o - | FileCheck --check-prefix MSVC %s
3+
4+
struct B {
5+
virtual ~B() {}
6+
};
7+
8+
struct A : virtual B {
9+
};
10+
11+
A a;
12+
13+
14+
// CHECK-DAG: !{{[0-9]+}} = !DILocalVariable(name: "vtt", arg: 2, scope: ![[destructor:[0-9]+]], type: ![[vtttype:[0-9]+]], flags: DIFlagArtificial)
15+
// CHECK-DAG: ![[destructor]] = distinct !DISubprogram(name: "~A", {{.*}}, type: ![[subroutinetype:[0-9]+]]
16+
// CHECK-DAG: ![[subroutinetype]] = !DISubroutineType(types: ![[types:[0-9]+]])
17+
// CHECK-DAG: [[types]] = !{null, !{{[0-9]+}}, ![[vtttype]]}
18+
19+
// MSVC-DAG: ![[inttype:[0-9]+]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
20+
// MSVC-DAG: ![[voidpointertype:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
21+
// MSVC-DAG: ![[destructor:[0-9]+]] = distinct !DISubprogram(name: "~A", linkageName: "??_GA@@UEAAPEAXI@Z", {{.*}}, type: ![[subroutinetype:[0-9]+]]
22+
// MSVC-DAG: !{{[0-9]+}} = !DILocalVariable(name: "should_call_delete", arg: 2, scope: ![[destructor]], type: ![[inttype]], flags: DIFlagArtificial)
23+
// MSVC-DAG: ![[subroutinetype]] = !DISubroutineType(types: ![[types:[0-9]+]])
24+
// MSVC-DAG: [[types]] = !{![[voidpointertype]], !{{[0-9]+}}, ![[inttype]]}

0 commit comments

Comments
 (0)