[clang] [llvm] [clang] Add support for emitting DW_AT_defaulted (PR #213188)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 30 18:17:19 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Alex Langford (bulbazord)
<details>
<summary>Changes</summary>
A C++ special member function maybe declared default which causes the
compiler to generate a definition for it. DWARFv5 introduced a new
attribute to mark these methods as defaulted.
The attribute has 3 values: DW_DEFAULTED_no, DW_DEFAULTED_in_class, and
DW_DEFAULTED_out_of_class. When processing a method function's
declaration, it is trivial to detect when it is defaulted in-class and
possible to detect the "no" case if the declaration is also a
definition. However, we cannot differentiate between "no" and
"out-of-class" until we process the member function's definition. That
means the Declaration's DISubprogram OR the Definition's
DISubprogram will have this knowledge.
---
Patch is 62.97 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/213188.diff
9 Files Affected:
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+27)
- (modified) clang/test/DebugInfo/CXX/all-calls-described.cpp (+1-1)
- (added) clang/test/DebugInfo/CXX/defaulted.cpp (+118)
- (modified) llvm/include/llvm/IR/DebugInfoFlags.def (+4-3)
- (modified) llvm/include/llvm/IR/DebugInfoMetadata.h (+9-4)
- (modified) llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp (+33)
- (modified) llvm/lib/IR/DebugInfoMetadata.cpp (+4-2)
- (added) llvm/test/DebugInfo/X86/DW_AT_defaulted.ll (+730)
- (modified) llvm/unittests/IR/MetadataTest.cpp (+3-1)
``````````diff
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index f155761a1d998..bd874400d89cd 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2504,6 +2504,19 @@ llvm::DISubprogram *CGDebugInfo::CreateCXXMemberFunction(
if (Method->getCanonicalDecl()->isDeleted())
SPFlags |= llvm::DISubprogram::SPFlagDeleted;
+ const bool isExplicitlyDefaultable =
+ isa<CXXDestructorDecl>(Method) ||
+ (isa<CXXConstructorDecl>(Method) &&
+ cast<CXXConstructorDecl>(Method)->isDefaultConstructor()) ||
+ Method->isCopyOrMoveConstructorOrAssignment();
+ if (Method->isExplicitlyDefaulted())
+ SPFlags |= Method->isOutOfLine()
+ ? llvm::DISubprogram::SPFlagDefaultedOutOfClass
+ : llvm::DISubprogram::SPFlagDefaultedInClass;
+ else if (isExplicitlyDefaultable && !Method->isImplicit() &&
+ Method->isThisDeclarationADefinition())
+ SPFlags |= llvm::DISubprogram::SPFlagDefaultedNo;
+
if (Method->isNoReturn())
Flags |= llvm::DINode::FlagNoReturn;
@@ -5008,6 +5021,20 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
if (CGM.getCodeGenOpts().OptimizationLevel != 0)
SPFlags |= llvm::DISubprogram::SPFlagOptimized;
+ if (const auto *Method = dyn_cast_or_null<CXXMethodDecl>(D)) {
+ const bool isExplicitlyDefaultable =
+ isa<CXXDestructorDecl>(Method) ||
+ (isa<CXXConstructorDecl>(Method) &&
+ cast<CXXConstructorDecl>(Method)->isDefaultConstructor()) ||
+ Method->isCopyOrMoveConstructorOrAssignment();
+ if (Method->isExplicitlyDefaulted())
+ SPFlags |= Method->isOutOfLine()
+ ? llvm::DISubprogram::SPFlagDefaultedOutOfClass
+ : llvm::DISubprogram::SPFlagDefaultedInClass;
+ else if (isExplicitlyDefaultable && !Method->isImplicit())
+ SPFlags |= llvm::DISubprogram::SPFlagDefaultedNo;
+ }
+
llvm::DINode::DIFlags FlagsForDef = Flags | getCallSiteRelatedAttrs();
llvm::DISubprogram::DISPFlags SPFlagsForDef =
SPFlags | llvm::DISubprogram::SPFlagDefinition;
diff --git a/clang/test/DebugInfo/CXX/all-calls-described.cpp b/clang/test/DebugInfo/CXX/all-calls-described.cpp
index e64e07cdb7485..fe3220e2b186f 100644
--- a/clang/test/DebugInfo/CXX/all-calls-described.cpp
+++ b/clang/test/DebugInfo/CXX/all-calls-described.cpp
@@ -63,7 +63,7 @@
// HAS-ATTR-DAG: DISubprogram(name: "declaration1", {{.*}}, flags: DIFlagPrototyped
// HAS-ATTR-DAG: DISubprogram(name: "declaration2", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
-// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized)
+// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized | DISPFlagDefaultedNo)
// HAS-ATTR-DAG: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
// HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
// HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
diff --git a/clang/test/DebugInfo/CXX/defaulted.cpp b/clang/test/DebugInfo/CXX/defaulted.cpp
new file mode 100644
index 0000000000000..717d42a72bf86
--- /dev/null
+++ b/clang/test/DebugInfo/CXX/defaulted.cpp
@@ -0,0 +1,118 @@
+// Test for debug info for C++ defaulted member functions
+
+// Supported: -O0, standalone DI
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-linux-gnu %s -o - \
+// RUN: -O0 -disable-llvm-passes \
+// RUN: -debug-info-kind=standalone \
+// RUN: | FileCheck %s -check-prefix=ATTR
+
+// ATTR-DAG: DISubprogram(name: "DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "~DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN16DefaultedOutlineaSERKS_", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "DefaultedOutline", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN16DefaultedOutlineaSEOS_", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedOutOfClass
+
+// ATTR-DAG: DISubprogram(name: "DefaultedInline", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "~DefaultedInline", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "DefaultedInline", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN15DefaultedInlineaSERKS_", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "DefaultedInline", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN15DefaultedInlineaSEOS_", {{.*}} spFlags: DISPFlagDefaultedInClass
+
+// ATTR-DAG: DISubprogram(name: "DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "~DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN27DefaultedInlineWithTemplateILi6EEaSERKS0_", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN27DefaultedInlineWithTemplateILi6EEaSEOS0_", {{.*}} spFlags: DISPFlagDefaultedInClass
+
+// ATTR-DAG: DISubprogram(name: "DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "~DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN27DefaultedInlineWithTemplateILi7EEaSERKS0_", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "DefaultedInlineWithTemplate", {{.*}} spFlags: DISPFlagDefaultedInClass
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN27DefaultedInlineWithTemplateILi7EEaSEOS0_", {{.*}} spFlags: DISPFlagDefaultedInClass
+
+// ATTR-DAG: DISubprogram(name: "NeverDefaulted", {{.*}} spFlags: DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "~NeverDefaulted", {{.*}} spFlags: DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "NeverDefaulted", {{.*}} spFlags: DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN14NeverDefaultedaSERKS_", {{.*}} spFlags: DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "NeverDefaulted", {{.*}} spFlags: DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "operator=", linkageName: "_ZN14NeverDefaultedaSEOS_", {{.*}} spFlags: DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "NeverDefaulted", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "~NeverDefaulted", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "NeverDefaulted", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedNo
+// ATTR-DAG: DISubprogram(name: "~NeverDefaulted", {{.*}} spFlags: DISPFlagDefinition | DISPFlagDefaultedNo
+
+class DefaultedInline {
+public:
+ DefaultedInline() = default;
+ ~DefaultedInline() = default;
+
+ DefaultedInline(const DefaultedInline &) = default;
+ DefaultedInline &operator=(const DefaultedInline &) = default;
+
+ DefaultedInline(DefaultedInline &&) = default;
+ DefaultedInline &operator=(DefaultedInline &&) = default;
+};
+
+class DefaultedOutline {
+public:
+ DefaultedOutline();
+ ~DefaultedOutline();
+
+ DefaultedOutline(const DefaultedOutline &);
+ DefaultedOutline &operator=(const DefaultedOutline &);
+
+ DefaultedOutline(DefaultedOutline &&);
+ DefaultedOutline &operator=(DefaultedOutline &&);
+};
+
+DefaultedOutline::DefaultedOutline() = default;
+DefaultedOutline::~DefaultedOutline() = default;
+
+DefaultedOutline::DefaultedOutline(const DefaultedOutline &) = default;
+DefaultedOutline &
+DefaultedOutline::operator=(const DefaultedOutline &) = default;
+
+DefaultedOutline::DefaultedOutline(DefaultedOutline &&) = default;
+DefaultedOutline &DefaultedOutline::operator=(DefaultedOutline &&) = default;
+
+class NeverDefaulted {
+public:
+ NeverDefaulted() {}
+ ~NeverDefaulted() {}
+
+ NeverDefaulted(const NeverDefaulted &) {}
+ NeverDefaulted &operator=(const NeverDefaulted &) { return *this; }
+
+ NeverDefaulted(NeverDefaulted &&) {}
+ NeverDefaulted &operator=(NeverDefaulted &&) { return *this; }
+};
+
+template <int N> class DefaultedInlineWithTemplate {
+public:
+ char msg[N];
+
+ DefaultedInlineWithTemplate() = default;
+ ~DefaultedInlineWithTemplate() = default;
+
+ DefaultedInlineWithTemplate(const DefaultedInlineWithTemplate &) = default;
+ DefaultedInlineWithTemplate &operator=(const DefaultedInlineWithTemplate &) = default;
+
+ DefaultedInlineWithTemplate(DefaultedInlineWithTemplate &&) = default;
+ DefaultedInlineWithTemplate &operator=(DefaultedInlineWithTemplate &&) = default;
+};
+
+int main() {
+ DefaultedInline a;
+ DefaultedOutline b;
+ NeverDefaulted c;
+ DefaultedInlineWithTemplate<6> d;
+ DefaultedInlineWithTemplate<7> e;
+ return 0;
+}
diff --git a/llvm/include/llvm/IR/DebugInfoFlags.def b/llvm/include/llvm/IR/DebugInfoFlags.def
index 44946b1fb83b7..fcadb005e88bd 100644
--- a/llvm/include/llvm/IR/DebugInfoFlags.def
+++ b/llvm/include/llvm/IR/DebugInfoFlags.def
@@ -88,15 +88,16 @@ HANDLE_DISP_FLAG((1u << 5), Pure)
HANDLE_DISP_FLAG((1u << 6), Elemental)
HANDLE_DISP_FLAG((1u << 7), Recursive)
HANDLE_DISP_FLAG((1u << 8), MainSubprogram)
-// May also utilize this Flag in future, when adding support
-// for defaulted functions
HANDLE_DISP_FLAG((1u << 9), Deleted)
+HANDLE_DISP_FLAG((1u << 10), DefaultedNo)
HANDLE_DISP_FLAG((1u << 11), ObjCDirect)
+HANDLE_DISP_FLAG((1u << 12), DefaultedInClass)
+HANDLE_DISP_FLAG((1u << 13), DefaultedOutOfClass)
#ifdef DISP_FLAG_LARGEST_NEEDED
// Intended to be used with ADT/BitmaskEnum.h.
// NOTE: Always must be equal to largest flag, check this when adding new flags.
-HANDLE_DISP_FLAG((1 << 11), Largest)
+HANDLE_DISP_FLAG((1 << 13), Largest)
#undef DISP_FLAG_LARGEST_NEEDED
#endif
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 846342bee6071..6fbdbe65a34d8 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2303,6 +2303,9 @@ class DISubprogram : public DILocalScope {
#include "llvm/IR/DebugInfoFlags.def"
SPFlagNonvirtual = SPFlagZero,
SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
+ SPFlagDefaultedUnspecified = SPFlagZero,
+ SPFlagDefaulted =
+ SPFlagDefaultedNo | SPFlagDefaultedInClass | SPFlagDefaultedOutOfClass,
LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
};
@@ -2317,10 +2320,11 @@ class DISubprogram : public DILocalScope {
SmallVectorImpl<DISPFlags> &SplitFlags);
// Helper for converting old bitfields to new flags word.
- LLVM_ABI static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
- bool IsOptimized,
- unsigned Virtuality = SPFlagNonvirtual,
- bool IsMainSubprogram = false);
+ LLVM_ABI static DISPFlags
+ toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
+ unsigned Virtuality = SPFlagNonvirtual,
+ unsigned Defaulted = SPFlagDefaultedUnspecified,
+ bool IsMainSubprogram = false);
private:
DIFlags Flags;
@@ -2417,6 +2421,7 @@ class DISubprogram : public DILocalScope {
public:
unsigned getLine() const { return Line; }
unsigned getVirtuality() const { return getSPFlags() & SPFlagVirtuality; }
+ unsigned getDefaulted() const { return getSPFlags() & SPFlagDefaulted; }
unsigned getVirtualIndex() const { return VirtualIndex; }
int getThisAdjustment() const { return ThisAdjustment; }
unsigned getScopeLine() const { return ScopeLine; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 78c0769e49161..e7874bc22429f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1430,6 +1430,26 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
if (SP->getLine() != SPDecl->getLine())
addUInt(SPDie, dwarf::DW_AT_decl_line, std::nullopt, SP->getLine());
+
+ unsigned DefDefaulted = SP->getDefaulted();
+ if (DD->getDwarfVersion() >= 5 && DefDefaulted) {
+ unsigned DeclDefaulted = SPDecl->getDefaulted();
+ assert(DeclDefaulted ==
+ DISubprogram::DISPFlags::SPFlagDefaultedUnspecified ||
+ DeclDefaulted == DefDefaulted &&
+ "Declaration DISP and Definition DISP disagree on the "
+ "defaulted state of this subprogram!");
+ if (DefDefaulted & DISubprogram::DISPFlags::SPFlagDefaultedNo)
+ addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+ dwarf::DW_DEFAULTED_no);
+ else if (DefDefaulted & DISubprogram::DISPFlags::SPFlagDefaultedInClass)
+ addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+ dwarf::DW_DEFAULTED_in_class);
+ else if (DefDefaulted &
+ DISubprogram::DISPFlags::SPFlagDefaultedOutOfClass)
+ addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+ dwarf::DW_DEFAULTED_out_of_class);
+ }
}
}
@@ -1513,6 +1533,19 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
ContainingTypeMap.insert(std::make_pair(&SPDie, SP->getContainingType()));
}
+ unsigned Defaulted = SP->getDefaulted();
+ if (DD->getDwarfVersion() >= 5 && Defaulted) {
+ if (Defaulted & DISubprogram::DISPFlags::SPFlagDefaultedNo)
+ addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+ dwarf::DW_DEFAULTED_no);
+ else if (Defaulted & DISubprogram::DISPFlags::SPFlagDefaultedInClass)
+ addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+ dwarf::DW_DEFAULTED_in_class);
+ else if (Defaulted & DISubprogram::DISPFlags::SPFlagDefaultedOutOfClass)
+ addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+ dwarf::DW_DEFAULTED_out_of_class);
+ }
+
if (!SP->isDefinition()) {
addFlag(SPDie, dwarf::DW_AT_declaration);
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 88f7f2f6240e0..e780c511be341 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1314,14 +1314,15 @@ DISubprogram::DISubprogram(LLVMContext &C, StorageType Storage, unsigned Line,
}
DISubprogram::DISPFlags
DISubprogram::toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
- unsigned Virtuality, bool IsMainSubprogram) {
+ unsigned Virtuality, unsigned Defaulted,
+ bool IsMainSubprogram) {
// We're assuming virtuality is the low-order field.
static_assert(int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
int(SPFlagPureVirtual) ==
int(dwarf::DW_VIRTUALITY_pure_virtual),
"Virtuality constant mismatch");
return static_cast<DISPFlags>(
- (Virtuality & SPFlagVirtuality) |
+ (Virtuality & SPFlagVirtuality) | (Defaulted & SPFlagDefaulted) |
(IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
(IsDefinition ? SPFlagDefinition : SPFlagZero) |
(IsOptimized ? SPFlagOptimized : SPFlagZero) |
@@ -1378,6 +1379,7 @@ StringRef DISubprogram::getFlagString(DISPFlags Flag) {
switch (Flag) {
// Appease a warning.
case SPFlagVirtuality:
+ case SPFlagDefaulted:
return "";
#define HANDLE_DISP_FLAG(ID, NAME) \
case SPFlag##NAME: \
diff --git a/llvm/test/DebugInfo/X86/DW_AT_defaulted.ll b/llvm/test/DebugInfo/X86/DW_AT_defaulted.ll
new file mode 100644
index 0000000000000..a9829b42b8f23
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/DW_AT_defaulted.ll
@@ -0,0 +1,730 @@
+; RUN: llc < %s -filetype=obj -o %t
+; RUN: llvm-dwarfdump -v %t | FileCheck %s
+
+; C++ source to regenerate:
+; class DefaultedInline {
+; public:
+; DefaultedInline() = default;
+; ~DefaultedInline() = default;
+;
+; DefaultedInline(const DefaultedInline &) = default;
+; DefaultedInline &operator=(const DefaultedInline &) = default;
+;
+; DefaultedInline(DefaultedInline &&) = default;
+; DefaultedInline &operator=(DefaultedInline &&) = default;
+; };
+;
+; class DefaultedOutline {
+; public:
+; DefaultedOutline();
+; ~DefaultedOutline();
+;
+; DefaultedOutline(const DefaultedOutline &);
+; DefaultedOutline &operator=(const DefaultedOutline &);
+;
+; DefaultedOutline(DefaultedOutline &&);
+; DefaultedOutline &operator=(DefaultedOutline &&);
+; };
+;
+; DefaultedOutline::DefaultedOutline() = default;
+; DefaultedOutline::~DefaultedOutline() = default;
+;
+; DefaultedOutline::DefaultedOutline(const DefaultedOutline &) = default;
+; DefaultedOutline &
+; DefaultedOutline::operator=(const DefaultedOutline &) = default;
+;
+; DefaultedOutline::DefaultedOutline(DefaultedOutline &&) = default;
+; DefaultedOutline &DefaultedOutline::operator=(DefaultedOutline &&) = default;
+;
+; class NeverDefaulted {
+; public:
+; NeverDefaulted() {}
+; ~NeverDefaulted() {}
+;
+; NeverDefaulted(const NeverDefaulted &) {}
+; NeverDefaulted &operator=(const NeverDefaulted &) { return *this; }
+;
+; NeverDefaulted(NeverDefaulted &&) {}
+; NeverDefaulted &operator=(NeverDefaulted &&) { return *this; }
+; };
+;
+; template <int N> class DefaultedInlineWithTemplate {
+; public:
+; char m[N];
+;
+; DefaultedInlineWithTemplate() = default;
+; ~DefaultedInlineWithTemplate() = default;
+;
+; DefaultedInlineWithTemplate(const DefaultedInlineWithTemplate &) = default;
+; DefaultedInlineWithTemplate &
+; operator=(const DefaultedInlineWithTemplate &) = default;
+;
+; DefaultedInlineWithTemplate(DefaultedInlineWithTemplate &&) = default;
+; DefaultedInlineWithTemplate &
+; operator=(DefaultedInlineWithTemplate &&) = default;
+; };
+;
+; int main() {
+; DefaultedInline a;
+; DefaultedOutline b;
+; NeverDefaulted c;
+; DefaultedInlineWithTemplate<6> d;
+; DefaultedInlineWithTemplate<7> e;
+; return 0;
+; }
+; $ clang++ -O0 -g -gdwarf-5 debug-info-defaulted.cpp -S -emit-llvm
+
+; CHECK: .debug_abbrev contents:
+
+; CHECK: [11] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [13] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [14] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [15] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [17] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [20] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [21] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [22] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; CHECK: [23] DW_TAG_subprogram DW_CHILDREN_yes
+; CHECK: DW_AT_defaulted DW_FORM_data1
+
+; C...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/213188
More information about the llvm-commits
mailing list