[clang] d7cd208 - [DebugInfo] Add an attribute to force type info to be emitted for types that are required to be complete.

Amy Huang via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 12 12:30:20 PST 2021


Author: Amy Huang
Date: 2021-03-12T12:30:01-08:00
New Revision: d7cd208f08afca450484be97604a55704a628e88

URL: https://github.com/llvm/llvm-project/commit/d7cd208f08afca450484be97604a55704a628e88
DIFF: https://github.com/llvm/llvm-project/commit/d7cd208f08afca450484be97604a55704a628e88.diff

LOG: [DebugInfo] Add an attribute to force type info to be emitted for types that are required to be complete.

This was motivated by the fact that constructor type homing (debug info
optimization that we want to turn on by default) drops some libc++ types,
so an attribute would allow us to override constructor homing and emit
them anyway. I'm currently looking into the particular libc++ issue, but
even if we do fix that, this issue might come up elsewhere and it might be
nice to have this.

As I've implemented it now, the attribute isn't specific to the
constructor homing optimization and overrides all of the debug info
optimizations.

Open to discussion about naming, specifics on what the attribute should do, etc.

Differential Revision: https://reviews.llvm.org/D97411

Added: 
    clang/test/CodeGenCXX/standalone-debug-attribute.cpp
    clang/test/Sema/attr-standalonedebug.cpp

Modified: 
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/AttrDocs.td
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/test/Misc/pragma-attribute-supported-attributes-list.test

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 9625e7f8f3221..664eb566a7032 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1673,6 +1673,14 @@ def NoDebug : InheritableAttr {
   let Documentation = [NoDebugDocs];
 }
 
+def StandaloneDebug : InheritableAttr {
+  let Spellings = [Clang<"standalone_debug", /*allowInC =*/0>];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let Documentation = [StandaloneDebugDocs];
+  let SimpleHandler = 1;
+  let LangOpts = [CPlusPlus];
+}
+
 def NoDuplicate : InheritableAttr {
   let Spellings = [Clang<"noduplicate">];
   let Subjects = SubjectList<[Function]>;

diff  --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index deda68b64f909..77d3bd1fdcd6e 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1102,6 +1102,16 @@ data member, or for a typedef or using declaration.
   }];
 }
 
+def StandaloneDebugDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``standalone_debug`` attribute causes debug info to be emitted for a record
+type regardless of the debug info optimizations that are enabled with
+-fno-standalone-debug. This attribute only has an effect when debug info
+optimizations are enabled (e.g. with -fno-standalone-debug), and is C++-only.
+  }];
+}
+
 def NoDuplicateDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{

diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 0aa8737b9f07d..468c2b78b488d 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2385,7 +2385,8 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
   if (DebugKind == codegenoptions::DebugLineTablesOnly)
     return true;
 
-  if (DebugKind > codegenoptions::LimitedDebugInfo)
+  if (DebugKind > codegenoptions::LimitedDebugInfo ||
+      RD->hasAttr<StandaloneDebugAttr>())
     return false;
 
   if (!LangOpts.CPlusPlus)

diff  --git a/clang/test/CodeGenCXX/standalone-debug-attribute.cpp b/clang/test/CodeGenCXX/standalone-debug-attribute.cpp
new file mode 100644
index 0000000000000..a814e6f425ed6
--- /dev/null
+++ b/clang/test/CodeGenCXX/standalone-debug-attribute.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -DSETATTR=0 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s --check-prefix=DEBUG
+// RUN: %clang_cc1 -DSETATTR=1 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s --check-prefix=WITHATTR
+// Use -debug-info-kind=constructor because it includes all the optimizations.
+
+#if SETATTR
+#define STANDALONEDEBUGATTR __attribute__((standalone_debug))
+#else
+#define STANDALONEDEBUGATTR
+#endif
+
+struct STANDALONEDEBUGATTR StructWithConstructor {
+  StructWithConstructor() {}
+};
+void f(StructWithConstructor s) {}
+// DEBUG:  !DICompositeType({{.*}}name: "StructWithConstructor"
+// DEBUG-SAME:              flags: {{.*}}DIFlagFwdDecl
+// WITHATTR: !DICompositeType({{.*}}name: "StructWithConstructor"
+// WITHATTR-NOT: DIFlagFwdDecl
+
+union STANDALONEDEBUGATTR UnionWithConstructor {
+  UnionWithConstructor() {}
+};
+void f(UnionWithConstructor u) {}
+// DEBUG:  !DICompositeType({{.*}}name: "UnionWithConstructor"
+// DEBUG-SAME:              flags: {{.*}}DIFlagFwdDecl
+// WITHATTR: !DICompositeType({{.*}}name: "UnionWithConstructor"
+// WITHATTR-NOT: DIFlagFwdDecl
+
+template <typename T> struct ExternTemplate {
+  ExternTemplate() {}
+  T x;
+};
+extern template struct STANDALONEDEBUGATTR ExternTemplate<int>;
+void f(ExternTemplate<int> s) {}
+// DEBUG: !DICompositeType({{.*}}name: "ExternTemplate<int>"
+// DEBUG-SAME:             flags: {{.*}}DIFlagFwdDecl
+// WITHATTR: !DICompositeType({{.*}}name: "ExternTemplate<int>"
+// WITHATTR-NOT: DIFlagFwdDecl
+
+struct STANDALONEDEBUGATTR CompleteTypeRequired {};
+void f(CompleteTypeRequired &s) {}
+// DEBUG: !DICompositeType({{.*}}name: "CompleteTypeRequired"
+// DEBUG-SAME:             flags: {{.*}}DIFlagFwdDecl
+// WITHATTR: !DICompositeType({{.*}}name: "CompleteTypeRequired"
+// WITHATTR-NOT: DIFlagFwdDecl
+
+struct STANDALONEDEBUGATTR Redecl;
+struct Redecl {};
+void f(Redecl &s) {}
+// DEBUG: !DICompositeType({{.*}}name: "Redecl"
+// DEBUG-SAME:             flags: {{.*}}DIFlagFwdDecl
+// WITHATTR: !DICompositeType({{.*}}name: "Redecl"
+// WITHATTR-NOT: DIFlagFwdDecl
+

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index dd9cd79e69dc5..fd56bd197586e 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -154,6 +154,7 @@
 // CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
 // CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
+// CHECK-NEXT: StandaloneDebug (SubjectMatchRule_record)
 // CHECK-NEXT: SwiftAsync (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: SwiftAsyncError (SubjectMatchRule_function, SubjectMatchRule_objc_method)
 // CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function)

diff  --git a/clang/test/Sema/attr-standalonedebug.cpp b/clang/test/Sema/attr-standalonedebug.cpp
new file mode 100644
index 0000000000000..540dd5f79af5b
--- /dev/null
+++ b/clang/test/Sema/attr-standalonedebug.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -x c
+
+#ifdef __cplusplus
+int a __attribute__((standalone_debug)); // expected-warning {{'standalone_debug' attribute only applies to classes}}
+
+void __attribute__((standalone_debug)) b(); // expected-warning {{'standalone_debug' attribute only applies to classes}}
+
+struct __attribute__((standalone_debug(1))) c {}; // expected-error {{'standalone_debug' attribute takes no arguments}}
+
+#else
+// Check that attribute only works in C++.
+struct __attribute__((standalone_debug)) a {}; // expected-warning {{'standalone_debug' attribute ignored}}
+#endif


        


More information about the cfe-commits mailing list