SouraVX created this revision.
SouraVX added reviewers: aprantl, dblaikie, probinson.
SouraVX added projects: LLVM, clang, debug-info.
Herald added a subscriber: hiraditya.

This patch provides DWARF5 support for C++11 defaulted, deleted member. 
Added support in clang C++ frontend, llvm, and llvm-dwarfdump.


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-decl-nested.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

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);
+    if (SP->isDefaultedOutOfClass())
+      addUInt(SPDie, dwarf::DW_AT_defaulted, dwarf::DW_FORM_data1,
+              dwarf::DW_DEFAULTED_out_of_class);
+    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:
@@ -601,6 +614,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
@@ -1758,6 +1758,14 @@
   bool isPure() const { return getSPFlags() & SPFlagPure; }
   bool isElemental() const { return getSPFlags() & SPFlagElemental; }
   bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
+  bool isDefaultedInClass() const {
+    return getSPFlags() & SPFlagDefaultedInClass;
+  }
+  bool isDefaultedOutOfClass() const {
+    return getSPFlags() & SPFlagDefaultedOutOfClass;
+  }
+  bool isNotDefaulted() const { return getSPFlags() & 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,15 @@
 HANDLE_DISP_FLAG((1u << 6), Elemental)
 HANDLE_DISP_FLAG((1u << 7), Recursive)
 HANDLE_DISP_FLAG((1u << 8), MainSubprogram)
+HANDLE_DISP_FLAG((1u << 9), NotDefaulted)
+HANDLE_DISP_FLAG((1u << 10), DefaultedInClass)
+HANDLE_DISP_FLAG((1u << 11), DefaultedOutOfClass)
+HANDLE_DISP_FLAG((1u << 12), Deleted)
 
 #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 << 12), 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
@@ -411,6 +411,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-decl-nested.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-decl-nested.cpp
+++ clang/test/CodeGenCXX/debug-info-decl-nested.cpp
@@ -17,9 +17,9 @@
   public:
     InnerClass(); // Here createContextChain() generates a limited type for OuterClass.
   } theInnerClass;
-// CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass"
-// CHECK0-SAME: line: [[@LINE+2]]
-// CHECK0-SAME: spFlags: 0
+  // CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass"
+  // CHECK0-SAME: line: [[@LINE+2]]
+  // CHECK0-SAME: spFlags: 0
   OuterClass(const Foo *); // line 10
 };
 OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated.
@@ -41,9 +41,9 @@
   public:
     InnerClass1();
   } theInnerClass1;
-// CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar"
-// CHECK1-SAME: line: [[@LINE+2]]
-// CHECK1-SAME: spFlags: 0
+  // CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar"
+  // CHECK1-SAME: line: [[@LINE+2]]
+  // CHECK1-SAME: spFlags: 0
   void Bar(const Foo1 *);
 };
 OuterClass1::InnerClass1 OuterClass1::theInnerClass1;
@@ -64,9 +64,9 @@
   public:
     InnerClass2();
   } theInnerClass2;
-// CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2"
-// CHECK2-SAME: line: [[@LINE+2]]
-// CHECK2-SAME: spFlags: 0
+  // CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2"
+  // CHECK2-SAME: line: [[@LINE+2]]
+  // CHECK2-SAME: spFlags: 0
   ~OuterClass2(); // line 10
 };
 OuterClass2::InnerClass2 OuterClass2::theInnerClass2;
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
@@ -4,8 +4,7 @@
 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
 // RUN:   -O1 -disable-llvm-passes \
 // RUN:   -debug-info-kind=standalone -dwarf-version=5 \
-// RUN: | FileCheck %s -check-prefix=HAS-ATTR \
-// RUN:     -implicit-check-not=DISubprogram -implicit-check-not=DIFlagAllCallsDescribed
+// RUN: | FileCheck %s -check-prefix=HAS-DWARF5
 
 // Supported: DWARF4 + LLDB tuning, -O1, limited DI
 // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - \
@@ -62,6 +61,8 @@
 // HAS-ATTR-DAG: DISubprogram(name: "method1", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
 // HAS-ATTR-DAG: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
 
+// HAS-DWARF5: DISubprogram(name: "struct1", {{.*}}, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized | DISPFlagNotDefaulted)
+
 // LINE-TABLES-ONLY: DISubprogram(name: "force_irgen", {{.*}}, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition
 
 void declaration1();
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1605,6 +1605,50 @@
     ContainingType = RecordTy;
   }
 
+  if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
+    // DWARF-5 support for, defaulted, deleted member functions
+    if (const auto *CXXC = dyn_cast<CXXConstructorDecl>(Method)) {
+      if (CXXC->getCanonicalDecl()->isDeleted())
+        SPFlags |= llvm::DISubprogram::SPFlagDeleted;
+
+      if (CXXC->getCanonicalDecl()->isDefaulted())
+        SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
+      else if (const auto Def = CXXC->getDefinition()) {
+        if (Def->isDefaulted())
+          SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
+        else
+          SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;
+      }
+    }
+    if (const auto *DXXC = dyn_cast<CXXDestructorDecl>(Method)) {
+      if (DXXC->getCanonicalDecl()->isDeleted())
+        SPFlags |= llvm::DISubprogram::SPFlagDeleted;
+
+      if (DXXC->getCanonicalDecl()->isDefaulted())
+        SPFlags |= llvm::DISubprogram::SPFlagDefaultedInClass;
+      else if (const auto Def = DXXC->getDefinition()) {
+        if (Def->isDefaulted()) {
+          SPFlags |= llvm::DISubprogram::SPFlagDefaultedOutOfClass;
+        } else {
+          SPFlags |= llvm::DISubprogram::SPFlagNotDefaulted;
+        }
+      }
+    }
+    if (Method->isCopyAssignmentOperator() ||
+        Method->isMoveAssignmentOperator()) {
+      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 (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