SouraVX updated this revision to Diff 223954.
SouraVX added a comment.

Addressed comments, regarding flags.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68117/new/

https://reviews.llvm.org/D68117

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
  clang/test/CodeGenCXX/debug-info-defaulted-in-class.cpp
  clang/test/CodeGenCXX/debug-info-defaulted-out-of-class.cpp
  clang/test/CodeGenCXX/debug-info-deleted.cpp
  clang/test/CodeGenCXX/debug-info-not-defaulted.cpp
  llvm/include/llvm/BinaryFormat/Dwarf.h
  llvm/include/llvm/IR/DebugInfoFlags.def
  llvm/include/llvm/IR/DebugInfoMetadata.h
  llvm/lib/BinaryFormat/Dwarf.cpp
  llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
  llvm/lib/IR/DebugInfoMetadata.cpp

Index: llvm/lib/IR/DebugInfoMetadata.cpp
===================================================================
--- llvm/lib/IR/DebugInfoMetadata.cpp
+++ llvm/lib/IR/DebugInfoMetadata.cpp
@@ -600,6 +600,7 @@
   switch (Flag) {
   // Appease a warning.
   case SPFlagVirtuality:
+  case SPFlagDefaultedInOrOutOfClass:
     return "";
 #define HANDLE_DISP_FLAG(ID, NAME)                                             \
   case SPFlag##NAME:                                                           \
Index: llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1296,6 +1296,19 @@
     addFlag(SPDie, dwarf::DW_AT_elemental);
   if (SP->isRecursive())
     addFlag(SPDie, dwarf::DW_AT_recursive);
+  if (DD->getDwarfVersion() >= 5) {
+    if (SP->isDefaultedInClass())
+      addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+              dwarf::DW_DEFAULTED_in_class);
+    else if (SP->isDefaultedOutOfClass())
+      addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+              dwarf::DW_DEFAULTED_out_of_class);
+    else if (SP->isNotDefaulted())
+      addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+              dwarf::DW_DEFAULTED_no);
+    if (SP->isDeleted())
+      addFlag(SPDie, dwarf::DW_AT_deleted);
+  }
 }
 
 void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,
Index: llvm/lib/BinaryFormat/Dwarf.cpp
===================================================================
--- llvm/lib/BinaryFormat/Dwarf.cpp
+++ llvm/lib/BinaryFormat/Dwarf.cpp
@@ -271,6 +271,19 @@
   return StringRef();
 }
 
+StringRef llvm::dwarf::DefaultedMemberString(unsigned DefaultedEncodings) {
+  switch (DefaultedEncodings) {
+  // Defaulted Member Encodings codes
+  case DW_DEFAULTED_no:
+    return "DW_DEFAULTED_no";
+  case DW_DEFAULTED_in_class:
+    return "DW_DEFAULTED_in_class";
+  case DW_DEFAULTED_out_of_class:
+    return "DW_DEFAULTED_out_of_class";
+  }
+  return StringRef();
+}
+
 StringRef llvm::dwarf::VisibilityString(unsigned Visibility) {
   switch (Visibility) {
   case DW_VIS_local:
@@ -612,6 +625,8 @@
     return ArrayOrderString(Val);
   case DW_AT_APPLE_runtime_class:
     return LanguageString(Val);
+  case DW_AT_defaulted:
+    return DefaultedMemberString(Val);
   }
 
   return StringRef();
Index: llvm/include/llvm/IR/DebugInfoMetadata.h
===================================================================
--- llvm/include/llvm/IR/DebugInfoMetadata.h
+++ llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -1610,7 +1610,10 @@
 #define DISP_FLAG_LARGEST_NEEDED
 #include "llvm/IR/DebugInfoFlags.def"
     SPFlagNonvirtual = SPFlagZero,
+    SPFlagNotDefaulted = SPFlagZero,
     SPFlagVirtuality = SPFlagVirtual | SPFlagPureVirtual,
+    SPFlagDefaultedInOrOutOfClass =
+        SPFlagDefaultedInClass | SPFlagDefaultedOutOfClass,
     LLVM_MARK_AS_BITMASK_ENUM(SPFlagLargest)
   };
 
@@ -1625,10 +1628,11 @@
                               SmallVectorImpl<DISPFlags> &SplitFlags);
 
   // Helper for converting old bitfields to new flags word.
-  static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition,
-                             bool IsOptimized,
-                             unsigned Virtuality = SPFlagNonvirtual,
-                             bool IsMainSubprogram = false) {
+  static DISPFlags
+  toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized,
+            unsigned Virtuality = SPFlagNonvirtual,
+            unsigned DefaultedInOrOutOfClass = SPFlagNotDefaulted,
+            bool IsMainSubprogram = false) {
     // We're assuming virtuality is the low-order field.
     static_assert(
         int(SPFlagVirtual) == int(dwarf::DW_VIRTUALITY_virtual) &&
@@ -1636,6 +1640,7 @@
         "Virtuality constant mismatch");
     return static_cast<DISPFlags>(
         (Virtuality & SPFlagVirtuality) |
+        (DefaultedInOrOutOfClass & SPFlagDefaultedInOrOutOfClass) |
         (IsLocalToUnit ? SPFlagLocalToUnit : SPFlagZero) |
         (IsDefinition ? SPFlagDefinition : SPFlagZero) |
         (IsOptimized ? SPFlagOptimized : SPFlagZero) |
@@ -1758,6 +1763,18 @@
   bool isPure() const { return getSPFlags() & SPFlagPure; }
   bool isElemental() const { return getSPFlags() & SPFlagElemental; }
   bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
+  bool isDefaultedInClass() const {
+    return (getSPFlags() & SPFlagDefaultedInOrOutOfClass) ==
+           SPFlagDefaultedInClass;
+  }
+  bool isDefaultedOutOfClass() const {
+    return (getSPFlags() & SPFlagDefaultedInOrOutOfClass) ==
+           SPFlagDefaultedOutOfClass;
+  }
+  bool isNotDefaulted() const {
+    return (getSPFlags() & SPFlagDefaultedInOrOutOfClass) == SPFlagNotDefaulted;
+  }
+  bool isDeleted() const { return getSPFlags() & SPFlagDeleted; }
 
   /// Check if this is reference-qualified.
   ///
Index: llvm/include/llvm/IR/DebugInfoFlags.def
===================================================================
--- llvm/include/llvm/IR/DebugInfoFlags.def
+++ llvm/include/llvm/IR/DebugInfoFlags.def
@@ -88,11 +88,14 @@
 HANDLE_DISP_FLAG((1u << 6), Elemental)
 HANDLE_DISP_FLAG((1u << 7), Recursive)
 HANDLE_DISP_FLAG((1u << 8), MainSubprogram)
+HANDLE_DISP_FLAG((1u << 9), Deleted)
+HANDLE_DISP_FLAG((1u << 10), DefaultedInClass)
+HANDLE_DISP_FLAG((1u << 11), 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 << 8), Largest)
+HANDLE_DISP_FLAG((1 << 11), Largest)
 #undef DISP_FLAG_LARGEST_NEEDED
 #endif
 
Index: llvm/include/llvm/BinaryFormat/Dwarf.h
===================================================================
--- llvm/include/llvm/BinaryFormat/Dwarf.h
+++ llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -457,6 +457,7 @@
 StringRef DecimalSignString(unsigned Sign);
 StringRef EndianityString(unsigned Endian);
 StringRef AccessibilityString(unsigned Access);
+StringRef DefaultedMemberString(unsigned DefaultedEncodings);
 StringRef VisibilityString(unsigned Visibility);
 StringRef VirtualityString(unsigned Virtuality);
 StringRef LanguageString(unsigned Language);
Index: clang/test/CodeGenCXX/debug-info-not-defaulted.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/debug-info-not-defaulted.cpp
@@ -0,0 +1,30 @@
+// Test for debug info for C++11 Not 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: DISubprogram(name: "not_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagNotDefaulted
+// ATTR: DISubprogram(name: "not_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagNotDefaulted
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN13not_defaultedaSERS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagNotDefaulted
+// ATTR: DISubprogram(name: "not_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagNotDefaulted
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN13not_defaultedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagNotDefaulted
+// ATTR: DISubprogram(name: "~not_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagNotDefaulted
+class not_defaulted {
+public:
+  not_defaulted() {}
+
+  not_defaulted(const not_defaulted &) {}
+  not_defaulted &operator=(not_defaulted &param) { return param; }
+
+  not_defaulted(not_defaulted &&param) {}
+  not_defaulted &operator=(not_defaulted &&param) { return param; }
+
+  ~not_defaulted() {}
+};
+
+void foo() {
+  not_defaulted obj1;
+}
Index: clang/test/CodeGenCXX/debug-info-deleted.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/debug-info-deleted.cpp
@@ -0,0 +1,30 @@
+// Test for debug info for C++11 deleted 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: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+// ATTR: DISubprogram(name: "deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDeleted
+// 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: "~deleted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+class deleted {
+public:
+  deleted() = default; // Defaulted on purpose, so as to facilitate object creation
+
+  deleted(const deleted &) = delete;
+  deleted &operator=(const deleted &) = delete;
+
+  deleted(deleted &&) = delete;
+  deleted &operator=(deleted &&) = delete;
+
+  ~deleted() = default;
+};
+
+void foo() {
+  deleted obj1;
+}
Index: clang/test/CodeGenCXX/debug-info-defaulted-out-of-class.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/debug-info-defaulted-out-of-class.cpp
@@ -0,0 +1,49 @@
+// Test for debug info for C++11 out of 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: DISubprogram(name: "out_of_class_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedOutOfClass
+// ATTR: DISubprogram(name: "out_of_class_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN22out_of_class_defaultedaSERKS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped
+// ATTR: DISubprogram(name: "out_of_class_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN22out_of_class_defaultedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped
+// ATTR: DISubprogram(name: "~out_of_class_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped
+class out_of_class_defaulted {
+public:
+  out_of_class_defaulted();
+
+  out_of_class_defaulted(const out_of_class_defaulted &);
+  out_of_class_defaulted &operator=(const out_of_class_defaulted &);
+
+  out_of_class_defaulted(out_of_class_defaulted &&);
+  out_of_class_defaulted &operator=(out_of_class_defaulted &&);
+
+  //FIXME -- clang will not mark above member funtions, excluding constructors
+  // as out of class. If we did not mark destructor or other member functions
+  // as virtual.
+  // clang checks in CGDebug.cpp
+  // if (Method->getCanonicalDecl()->isDefaulted())
+  //        SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
+  //     else if (const auto Def = Method->getDefinition()) {
+  //             if (Def->isDefaulted())
+  //               SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
+  virtual ~out_of_class_defaulted();
+};
+
+out_of_class_defaulted::out_of_class_defaulted() = default;
+
+out_of_class_defaulted::out_of_class_defaulted(const out_of_class_defaulted &) = default;
+out_of_class_defaulted &out_of_class_defaulted::operator=(const out_of_class_defaulted &) = default;
+
+out_of_class_defaulted::out_of_class_defaulted(out_of_class_defaulted &&) = default;
+out_of_class_defaulted &out_of_class_defaulted::operator=(out_of_class_defaulted &&) = default;
+
+out_of_class_defaulted::~out_of_class_defaulted() = default;
+
+void foo() {
+  out_of_class_defaulted obj1;
+}
Index: clang/test/CodeGenCXX/debug-info-defaulted-in-class.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/debug-info-defaulted-in-class.cpp
@@ -0,0 +1,30 @@
+// Test for debug info for C++11 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: DISubprogram(name: "inclass_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+// ATTR: DISubprogram(name: "inclass_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN17inclass_defaultedaSERKS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+// ATTR: DISubprogram(name: "inclass_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+// ATTR: DISubprogram(name: "operator=", linkageName: "_ZN17inclass_defaultedaSEOS_", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+// ATTR: DISubprogram(name: "~inclass_defaulted", {{.*}}, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagDefaultedInClass
+class inclass_defaulted {
+public:
+  inclass_defaulted() = default;
+
+  inclass_defaulted(const inclass_defaulted &) = default;
+  inclass_defaulted &operator=(const inclass_defaulted &) = default;
+
+  inclass_defaulted(inclass_defaulted &&) = default;
+  inclass_defaulted &operator=(inclass_defaulted &&) = default;
+
+  ~inclass_defaulted() = default;
+};
+
+void foo() {
+  inclass_defaulted obj1;
+}
Index: clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
===================================================================
--- clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
+++ clang/test/CodeGenCXX/dbg-info-all-calls-described.cpp
@@ -57,7 +57,7 @@
 // NO-ATTR-NOT: FlagAllCallsDescribed
 
 // 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 | DISPFlagNotDefaulted)
 // 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
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1605,6 +1605,31 @@
     ContainingType = RecordTy;
   }
 
+  // DWARF-5 support for, defaulted, deleted member functions
+  auto checkAttrDefaultedOrDeleted = [&SPFlags](const auto *Method) {
+    if (Method->getCanonicalDecl()->isDeleted())
+      SPFlags |= llvm::DISubprogram::SPFlagDeleted;
+
+    if (Method->getCanonicalDecl()->isDefaulted())
+      SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
+    else if (const auto Def = Method->getDefinition()) {
+      if (Def->isDefaulted())
+        SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
+      else {
+        SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;
+      }
+    }
+  };
+
+  if (const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method))
+    checkAttrDefaultedOrDeleted(CXXC);
+
+  if (const auto *DXXC = dyn_cast<CXXDestructorDecl>(Method))
+    checkAttrDefaultedOrDeleted(DXXC);
+
+  if (Method->isCopyAssignmentOperator() || Method->isMoveAssignmentOperator())
+    checkAttrDefaultedOrDeleted(Method);
+
   if (Method->isStatic())
     Flags |= llvm::DINode::FlagStaticMember;
   if (Method->isImplicit())
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to