Skip to content

Commit 6d6a459

Browse files
Awanish PandeySouraVX
authored andcommitted
[DWARF5][clang]: Added support for DebugInfo generation for auto return type for C++ member functions.
Summary: This patch will provide support for auto return type for the C++ member functions. This patch includes clang side implementation of this feature. Patch by: Awanish Pandey <[email protected]> Reviewers: dblaikie, aprantl, shafik, alok, SouraVX, jini.susan.george Reviewed by: dblaikie Differential Revision: https://reviews.llvm.org/D70524
1 parent c958639 commit 6d6a459

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,10 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
810810
return DBuilder.createBasicType(BTName, Size, Encoding);
811811
}
812812

813+
llvm::DIType *CGDebugInfo::CreateType(const AutoType *Ty) {
814+
return DBuilder.createUnspecifiedType("auto");
815+
}
816+
813817
llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) {
814818
// Bit size and offset of the type.
815819
llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;
@@ -1457,26 +1461,31 @@ void CGDebugInfo::CollectRecordFields(
14571461

14581462
llvm::DISubroutineType *
14591463
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
1460-
llvm::DIFile *Unit) {
1464+
llvm::DIFile *Unit, bool decl) {
14611465
const FunctionProtoType *Func = Method->getType()->getAs<FunctionProtoType>();
14621466
if (Method->isStatic())
14631467
return cast_or_null<llvm::DISubroutineType>(
14641468
getOrCreateType(QualType(Func, 0), Unit));
1465-
return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit);
1469+
return getOrCreateInstanceMethodType(Method->getThisType(), Func, Unit, decl);
14661470
}
14671471

1468-
llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
1469-
QualType ThisPtr, const FunctionProtoType *Func, llvm::DIFile *Unit) {
1472+
llvm::DISubroutineType *
1473+
CGDebugInfo::getOrCreateInstanceMethodType(QualType ThisPtr,
1474+
const FunctionProtoType *Func,
1475+
llvm::DIFile *Unit, bool decl) {
14701476
// Add "this" pointer.
14711477
llvm::DITypeRefArray Args(
14721478
cast<llvm::DISubroutineType>(getOrCreateType(QualType(Func, 0), Unit))
14731479
->getTypeArray());
14741480
assert(Args.size() && "Invalid number of arguments!");
14751481

14761482
SmallVector<llvm::Metadata *, 16> Elts;
1477-
14781483
// First element is always return type. For 'void' functions it is NULL.
1479-
Elts.push_back(Args[0]);
1484+
QualType temp = Func->getReturnType();
1485+
if (temp->getTypeClass() == Type::Auto && decl)
1486+
Elts.push_back(CreateType(cast<AutoType>(temp)));
1487+
else
1488+
Elts.push_back(Args[0]);
14801489

14811490
// "this" pointer is always first argument.
14821491
const CXXRecordDecl *RD = ThisPtr->getPointeeCXXRecordDecl();
@@ -1535,7 +1544,7 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
15351544
isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
15361545

15371546
StringRef MethodName = getFunctionName(Method);
1538-
llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit);
1547+
llvm::DISubroutineType *MethodTy = getOrCreateMethodType(Method, Unit, true);
15391548

15401549
// Since a single ctor/dtor corresponds to multiple functions, it doesn't
15411550
// make sense to give a single ctor/dtor a linkage name.
@@ -2754,7 +2763,7 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
27542763
return DBuilder.createMemberPointerType(
27552764
getOrCreateInstanceMethodType(
27562765
CXXMethodDecl::getThisType(FPT, Ty->getMostRecentCXXRecordDecl()),
2757-
FPT, U),
2766+
FPT, U, false),
27582767
ClassType, Size, /*Align=*/0, Flags);
27592768
}
27602769

@@ -3529,7 +3538,7 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateFunctionType(const Decl *D,
35293538
return DBuilder.createSubroutineType(DBuilder.getOrCreateTypeArray(None));
35303539

35313540
if (const auto *Method = dyn_cast<CXXMethodDecl>(D))
3532-
return getOrCreateMethodType(Method, F);
3541+
return getOrCreateMethodType(Method, F, false);
35333542

35343543
const auto *FTy = FnType->getAs<FunctionType>();
35353544
CallingConv CC = FTy ? FTy->getCallConv() : CallingConv::CC_C;

clang/lib/CodeGen/CGDebugInfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class CGDebugInfo {
165165
/// ivars and property accessors.
166166
llvm::DIType *CreateType(const BuiltinType *Ty);
167167
llvm::DIType *CreateType(const ComplexType *Ty);
168+
llvm::DIType *CreateType(const AutoType *Ty);
168169
llvm::DIType *CreateQualifiedType(QualType Ty, llvm::DIFile *Fg);
169170
llvm::DIType *CreateType(const TypedefType *Ty, llvm::DIFile *Fg);
170171
llvm::DIType *CreateType(const TemplateSpecializationType *Ty,
@@ -214,10 +215,10 @@ class CGDebugInfo {
214215
/// not updated to include implicit \c this pointer. Use this routine
215216
/// to get a method type which includes \c this pointer.
216217
llvm::DISubroutineType *getOrCreateMethodType(const CXXMethodDecl *Method,
217-
llvm::DIFile *F);
218+
llvm::DIFile *F, bool decl);
218219
llvm::DISubroutineType *
219220
getOrCreateInstanceMethodType(QualType ThisPtr, const FunctionProtoType *Func,
220-
llvm::DIFile *Unit);
221+
llvm::DIFile *Unit, bool decl);
221222
llvm::DISubroutineType *
222223
getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
223224
/// \return debug info descriptor for vtable.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Test for debug info for C++11 auto return member functions
2+
// RUN: %clang_cc1 -dwarf-version=5 -emit-llvm -triple x86_64-linux-gnu %s -o - \
3+
// RUN: -O0 -disable-llvm-passes \
4+
// RUN: -debug-info-kind=standalone \
5+
// RUN: | FileCheck %s
6+
7+
// CHECK: !DISubprogram(name: "findMax",{{.*}}, type: ![[FUN_TYPE:[0-9]+]],{{.*}}
8+
9+
// CHECK: ![[FUN_TYPE]] = !DISubroutineType(types: ![[TYPE_NODE:[0-9]+]])
10+
// CHECK-NEXT: ![[TYPE_NODE]] = !{![[DOUBLE_TYPE:[0-9]+]], {{.*}}
11+
// CHECK-NEXT: ![[DOUBLE_TYPE]] = !DIBasicType(name: "double", {{.*}})
12+
13+
// CHECK: !DISubroutineType(types: ![[TYPE_DECL_NODE:[0-9]+]])
14+
// CHECK-NEXT: ![[TYPE_DECL_NODE]] = !{![[AUTO_TYPE:[0-9]+]], {{.*}}
15+
// CHECK-NEXT: ![[AUTO_TYPE]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "auto")
16+
struct myClass {
17+
auto findMax();
18+
};
19+
20+
auto myClass::findMax() {
21+
return 0.0;
22+
}

0 commit comments

Comments
 (0)