Michael137 created this revision.
Michael137 added reviewers: aprantl, dblaikie.
Herald added a project: All.
Michael137 requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.
Currently we emit `DW_AT_deleted` for `deleted` special-member
functions (i.e., ctors/dtors). However, in C++ one can mark any
member function as deleted. This patch expands the set of member
functions for which we emit `DW_AT_deleted`.
The DWARFv5 spec section 5.7.8 says:
<non-normative>
In C++, a member function may be declared as deleted. This prevents the
compiler from
generating a default implementation of a special member function such as a
constructor
or destructor, and can affect overload resolution when used on other member
functions.
</non-normative>
If the member function entry has been declared as deleted, then that entry
has a
DW_AT_deleted attribute.
Thus this change is conforming.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D153282
Files:
clang/lib/CodeGen/CGDebugInfo.cpp
clang/test/CodeGenCXX/debug-info-deleted.cpp
llvm/test/DebugInfo/X86/DW_AT_deleted.ll
Index: llvm/test/DebugInfo/X86/DW_AT_deleted.ll
===================================================================
--- llvm/test/DebugInfo/X86/DW_AT_deleted.ll
+++ llvm/test/DebugInfo/X86/DW_AT_deleted.ll
@@ -12,6 +12,9 @@
;
; deleted(deleted &&) = delete;
; deleted &operator=(deleted &&) = delete;
+;
+; void func() && {}
+; static void bar() = delete;
;
; ~deleted() = default;
; };
@@ -48,6 +51,16 @@
; CHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (00000008) string = "operator=")
; CHECK: DW_AT_deleted [DW_FORM_flag_present] (true)
+; CHECK: DW_TAG_subprogram [10]
+; CHECK-NEXT: DW_AT_linkage_name [DW_FORM_strx1] (indexed (0000000b) string = "_ZNO7deleted4funcEv")
+; CHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (0000000c) string = "func")
+; CHECK: DW_AT_deleted [DW_FORM_flag_present] (true)
+
+; CHECK: DW_TAG_subprogram [11]
+; CHECK-NEXT: DW_AT_linkage_name [DW_FORM_strx1] (indexed (0000000d) string = "_ZN7deleted3barEv")
+; CHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (0000000e) string = "bar")
+; CHECK: DW_AT_deleted [DW_FORM_flag_present] (true)
+
; ModuleID = 'debug-info-deleted.cpp'
source_filename = "debug-info-deleted.cpp"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
@@ -58,8 +71,8 @@
; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @_Z3foov() #0 !dbg !7 {
%1 = alloca %class.deleted, align 1
- call void @llvm.dbg.declare(metadata ptr %1, metadata !10, metadata !DIExpression()), !dbg !34
- ret void, !dbg !35
+ call void @llvm.dbg.declare(metadata ptr %1, metadata !10, metadata !DIExpression()), !dbg !39
+ ret void, !dbg !40
}
; Function Attrs: nounwind readnone speculatable willreturn
@@ -84,7 +97,7 @@
!9 = !{null}
!10 = !DILocalVariable(name: "obj1", scope: !7, file: !1, line: 15, type: !11)
!11 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "deleted", file: !1, line: 1, size: 8, flags: DIFlagTypePassByReference, elements: !12, identifier: "_ZTS7deleted")
-!12 = !{!13, !17, !22, !26, !30, !33}
+!12 = !{!13, !17, !22, !26, !30, !33, !34, !36}
!13 = !DISubprogram(name: "deleted", scope: !11, file: !1, line: 3, type: !14, scopeLine: 3, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
!14 = !DISubroutineType(types: !15)
!15 = !{null, !16}
@@ -106,5 +119,10 @@
!31 = !DISubroutineType(types: !32)
!32 = !{!25, !16, !29}
!33 = !DISubprogram(name: "~deleted", scope: !11, file: !1, line: 11, type: !14, scopeLine: 11, flags: DIFlagPublic | DIFlagPrototyped, spFlags: 0)
-!34 = !DILocation(line: 15, column: 13, scope: !7)
-!35 = !DILocation(line: 16, column: 3, scope: !7)
+!34 = !DISubprogram(name: "func", linkageName: "_ZNO7deleted4funcEv", scope: !11, file: !1, line: 13, type: !35, scopeLine: 13, flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference, spFlags: DISPFlagDeleted)
+!35 = !DISubroutineType(flags: DIFlagRValueReference, types: !15)
+!36 = !DISubprogram(name: "bar", linkageName: "_ZN7deleted3barEv", scope: !11, file: !1, line: 15, type: !37, scopeLine: 15, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagDeleted)
+!37 = !DISubroutineType(types: !38)
+!38 = !{null}
+!39 = !DILocation(line: 15, column: 13, scope: !7)
+!40 = !DILocation(line: 16, column: 3, scope: !7)
Index: clang/test/CodeGenCXX/debug-info-deleted.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-deleted.cpp
+++ clang/test/CodeGenCXX/debug-info-deleted.cpp
@@ -11,6 +11,8 @@
// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSERKS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN7deletedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
+// ATTR: DISubprogram(name: "func", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference, spFlags: DISPFlagDeleted
+// ATTR: DISubprogram(name: "bar", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagDeleted
// ATTR: DISubprogram(name: "~deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped,
class deleted {
public:
@@ -23,6 +25,9 @@
deleted(deleted &&) = delete;
deleted &operator=(deleted &&) = delete;
+ void func() && = delete;
+ static int bar() = delete;
+
~deleted() = default;
};
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1945,27 +1945,8 @@
ContainingType = RecordTy;
}
- // We're checking for deleted C++ special member functions
- // [Ctors,Dtors, Copy/Move]
- auto checkAttrDeleted = [&](const auto *Method) {
- if (Method->getCanonicalDecl()->isDeleted())
- SPFlags |= llvm::DISubprogram::SPFlagDeleted;
- };
-
- switch (Method->getKind()) {
-
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- checkAttrDeleted(Method);
- break;
- case Decl::CXXMethod:
- if (Method->isCopyAssignmentOperator() ||
- Method->isMoveAssignmentOperator())
- checkAttrDeleted(Method);
- break;
- default:
- break;
- }
+ if (Method->getCanonicalDecl()->isDeleted())
+ SPFlags |= llvm::DISubprogram::SPFlagDeleted;
if (Method->isNoReturn())
Flags |= llvm::DINode::FlagNoReturn;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits