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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to