Skip to content

Commit d7cd208

Browse files
committed
[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
1 parent 579b8fc commit d7cd208

File tree

6 files changed

+89
-1
lines changed

6 files changed

+89
-1
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,14 @@ def NoDebug : InheritableAttr {
16731673
let Documentation = [NoDebugDocs];
16741674
}
16751675

1676+
def StandaloneDebug : InheritableAttr {
1677+
let Spellings = [Clang<"standalone_debug", /*allowInC =*/0>];
1678+
let Subjects = SubjectList<[CXXRecord]>;
1679+
let Documentation = [StandaloneDebugDocs];
1680+
let SimpleHandler = 1;
1681+
let LangOpts = [CPlusPlus];
1682+
}
1683+
16761684
def NoDuplicate : InheritableAttr {
16771685
let Spellings = [Clang<"noduplicate">];
16781686
let Subjects = SubjectList<[Function]>;

clang/include/clang/Basic/AttrDocs.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,16 @@ data member, or for a typedef or using declaration.
11021102
}];
11031103
}
11041104

1105+
def StandaloneDebugDocs : Documentation {
1106+
let Category = DocCatVariable;
1107+
let Content = [{
1108+
The ``standalone_debug`` attribute causes debug info to be emitted for a record
1109+
type regardless of the debug info optimizations that are enabled with
1110+
-fno-standalone-debug. This attribute only has an effect when debug info
1111+
optimizations are enabled (e.g. with -fno-standalone-debug), and is C++-only.
1112+
}];
1113+
}
1114+
11051115
def NoDuplicateDocs : Documentation {
11061116
let Category = DocCatFunction;
11071117
let Content = [{

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,7 +2385,8 @@ static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
23852385
if (DebugKind == codegenoptions::DebugLineTablesOnly)
23862386
return true;
23872387

2388-
if (DebugKind > codegenoptions::LimitedDebugInfo)
2388+
if (DebugKind > codegenoptions::LimitedDebugInfo ||
2389+
RD->hasAttr<StandaloneDebugAttr>())
23892390
return false;
23902391

23912392
if (!LangOpts.CPlusPlus)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// RUN: %clang_cc1 -DSETATTR=0 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s --check-prefix=DEBUG
2+
// RUN: %clang_cc1 -DSETATTR=1 -triple x86_64-unknown-linux-gnu -emit-llvm -debug-info-kind=constructor %s -o - | FileCheck %s --check-prefix=WITHATTR
3+
// Use -debug-info-kind=constructor because it includes all the optimizations.
4+
5+
#if SETATTR
6+
#define STANDALONEDEBUGATTR __attribute__((standalone_debug))
7+
#else
8+
#define STANDALONEDEBUGATTR
9+
#endif
10+
11+
struct STANDALONEDEBUGATTR StructWithConstructor {
12+
StructWithConstructor() {}
13+
};
14+
void f(StructWithConstructor s) {}
15+
// DEBUG: !DICompositeType({{.*}}name: "StructWithConstructor"
16+
// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl
17+
// WITHATTR: !DICompositeType({{.*}}name: "StructWithConstructor"
18+
// WITHATTR-NOT: DIFlagFwdDecl
19+
20+
union STANDALONEDEBUGATTR UnionWithConstructor {
21+
UnionWithConstructor() {}
22+
};
23+
void f(UnionWithConstructor u) {}
24+
// DEBUG: !DICompositeType({{.*}}name: "UnionWithConstructor"
25+
// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl
26+
// WITHATTR: !DICompositeType({{.*}}name: "UnionWithConstructor"
27+
// WITHATTR-NOT: DIFlagFwdDecl
28+
29+
template <typename T> struct ExternTemplate {
30+
ExternTemplate() {}
31+
T x;
32+
};
33+
extern template struct STANDALONEDEBUGATTR ExternTemplate<int>;
34+
void f(ExternTemplate<int> s) {}
35+
// DEBUG: !DICompositeType({{.*}}name: "ExternTemplate<int>"
36+
// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl
37+
// WITHATTR: !DICompositeType({{.*}}name: "ExternTemplate<int>"
38+
// WITHATTR-NOT: DIFlagFwdDecl
39+
40+
struct STANDALONEDEBUGATTR CompleteTypeRequired {};
41+
void f(CompleteTypeRequired &s) {}
42+
// DEBUG: !DICompositeType({{.*}}name: "CompleteTypeRequired"
43+
// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl
44+
// WITHATTR: !DICompositeType({{.*}}name: "CompleteTypeRequired"
45+
// WITHATTR-NOT: DIFlagFwdDecl
46+
47+
struct STANDALONEDEBUGATTR Redecl;
48+
struct Redecl {};
49+
void f(Redecl &s) {}
50+
// DEBUG: !DICompositeType({{.*}}name: "Redecl"
51+
// DEBUG-SAME: flags: {{.*}}DIFlagFwdDecl
52+
// WITHATTR: !DICompositeType({{.*}}name: "Redecl"
53+
// WITHATTR-NOT: DIFlagFwdDecl
54+

clang/test/Misc/pragma-attribute-supported-attributes-list.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
// CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
155155
// CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
156156
// CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)
157+
// CHECK-NEXT: StandaloneDebug (SubjectMatchRule_record)
157158
// CHECK-NEXT: SwiftAsync (SubjectMatchRule_function, SubjectMatchRule_objc_method)
158159
// CHECK-NEXT: SwiftAsyncError (SubjectMatchRule_function, SubjectMatchRule_objc_method)
159160
// CHECK-NEXT: SwiftAsyncName (SubjectMatchRule_objc_method, SubjectMatchRule_function)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 %s -verify -fsyntax-only
2+
// RUN: %clang_cc1 %s -verify -fsyntax-only -x c
3+
4+
#ifdef __cplusplus
5+
int a __attribute__((standalone_debug)); // expected-warning {{'standalone_debug' attribute only applies to classes}}
6+
7+
void __attribute__((standalone_debug)) b(); // expected-warning {{'standalone_debug' attribute only applies to classes}}
8+
9+
struct __attribute__((standalone_debug(1))) c {}; // expected-error {{'standalone_debug' attribute takes no arguments}}
10+
11+
#else
12+
// Check that attribute only works in C++.
13+
struct __attribute__((standalone_debug)) a {}; // expected-warning {{'standalone_debug' attribute ignored}}
14+
#endif

0 commit comments

Comments
 (0)