From 0c5885d927031f5b8f1b650badb237154d3cb878 Mon Sep 17 00:00:00 2001 From: "Khatavkar, Yashasvi" Date: Tue, 29 Apr 2025 07:19:31 -0700 Subject: [PATCH 1/5] fix emiision of nested unused enum types with -fno-eliminate-unused-debug-types --- clang/lib/CodeGen/CGDebugInfo.cpp | 10 +++++++++ clang/lib/CodeGen/CGDebugInfo.h | 2 ++ clang/test/CodeGen/unused_nested_enump.cpp | 26 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 clang/test/CodeGen/unused_nested_enump.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index f3ec498d4064b..7840b09776be4 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1901,6 +1901,14 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, return GV; } +void CGDebugInfo::CollectRecordEnumType( + const EnumDecl *ED, SmallVectorImpl &elements) { + QualType Ty = CGM.getContext().getTypeDeclType(ED); + SourceLocation Loc = ED->getLocation(); + if (llvm::DIType *enumType = getOrCreateType(Ty, getOrCreateFile(Loc))) + elements.push_back(enumType); +} + void CGDebugInfo::CollectRecordNormalField( const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit, SmallVectorImpl &elements, llvm::DIType *RecordTy, @@ -1987,6 +1995,8 @@ void CGDebugInfo::CollectRecordFields( // Bump field number for next field. ++fieldNo; + } else if (const auto *enumType = dyn_cast(I)) { + CollectRecordEnumType(enumType, elements); } else if (CGM.getCodeGenOpts().EmitCodeView) { // Debug info for nested types is included in the member list only for // CodeView. diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index b287ce7b92eee..baf2069745535 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -370,6 +370,8 @@ class CGDebugInfo { llvm::DIDerivedType *CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, const RecordDecl *RD); + void CollectRecordEnumType(const EnumDecl *ED, + SmallVectorImpl &elements); void CollectRecordNormalField(const FieldDecl *Field, uint64_t OffsetInBits, llvm::DIFile *F, SmallVectorImpl &E, diff --git a/clang/test/CodeGen/unused_nested_enump.cpp b/clang/test/CodeGen/unused_nested_enump.cpp new file mode 100644 index 0000000000000..1e7b39dbb7b1c --- /dev/null +++ b/clang/test/CodeGen/unused_nested_enump.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -debug-info-kind=unused-types -emit-llvm -o - %s | FileCheck %s + +struct Type { + enum { Unused }; + int value = 0; +}; +int main() { + Type t; + return t.value; +} + +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type +// CHECK-SAME: scope: ![[STRUCT:[0-9]+]] +// CHECK-SAME: elements: ![[ELEMENTS:[0-9]+]] + +// CHECK: ![[STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type +// CHECK-SAME: elements: ![[STRUCT_ELEMENTS:[0-9]+]] + +// CHECK: ![[STRUCT_ELEMENTS]] = !{![[ENUM_MEMBER:[0-9]+]], ![[VALUE_MEMBER:[0-9]+]]} + +// CHECK: ![[VALUE_MEMBER]] = !DIDerivedType(tag: DW_TAG_member +// CHECK-SAME: name: "value" +// CHECK-SAME: scope: ![[STRUCT]] + +// CHECK: ![[ELEMENTS]] = !{![[ENUMERATOR:[0-9]+]]} +// CHECK: ![[ENUMERATOR]] = !DIEnumerator(name: "Unused", value: 0 From e01ac2035177cab509d9c82bb72b4b4b56a1bf65 Mon Sep 17 00:00:00 2001 From: "Khatavkar, Yashasvi" Date: Fri, 2 May 2025 08:02:16 -0700 Subject: [PATCH 2/5] reuse CollectRecordNestedType() --- clang/lib/CodeGen/CGDebugInfo.cpp | 12 +----------- clang/lib/CodeGen/CGDebugInfo.h | 2 -- clang/test/CodeGen/unused_nested_enump.cpp | 6 +++++- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 7840b09776be4..e7b5383dc688e 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1901,14 +1901,6 @@ CGDebugInfo::CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, return GV; } -void CGDebugInfo::CollectRecordEnumType( - const EnumDecl *ED, SmallVectorImpl &elements) { - QualType Ty = CGM.getContext().getTypeDeclType(ED); - SourceLocation Loc = ED->getLocation(); - if (llvm::DIType *enumType = getOrCreateType(Ty, getOrCreateFile(Loc))) - elements.push_back(enumType); -} - void CGDebugInfo::CollectRecordNormalField( const FieldDecl *field, uint64_t OffsetInBits, llvm::DIFile *tunit, SmallVectorImpl &elements, llvm::DIType *RecordTy, @@ -1995,9 +1987,7 @@ void CGDebugInfo::CollectRecordFields( // Bump field number for next field. ++fieldNo; - } else if (const auto *enumType = dyn_cast(I)) { - CollectRecordEnumType(enumType, elements); - } else if (CGM.getCodeGenOpts().EmitCodeView) { + } else if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo() || CGM.getCodeGenOpts().EmitCodeView) { // Debug info for nested types is included in the member list only for // CodeView. if (const auto *nestedType = dyn_cast(I)) { diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h index baf2069745535..b287ce7b92eee 100644 --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -370,8 +370,6 @@ class CGDebugInfo { llvm::DIDerivedType *CreateRecordStaticField(const VarDecl *Var, llvm::DIType *RecordTy, const RecordDecl *RD); - void CollectRecordEnumType(const EnumDecl *ED, - SmallVectorImpl &elements); void CollectRecordNormalField(const FieldDecl *Field, uint64_t OffsetInBits, llvm::DIFile *F, SmallVectorImpl &E, diff --git a/clang/test/CodeGen/unused_nested_enump.cpp b/clang/test/CodeGen/unused_nested_enump.cpp index 1e7b39dbb7b1c..4e66c5153d213 100644 --- a/clang/test/CodeGen/unused_nested_enump.cpp +++ b/clang/test/CodeGen/unused_nested_enump.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -debug-info-kind=unused-types -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck --check-prefix=NOUNUSEDTYPE %s struct Type { enum { Unused }; @@ -9,7 +10,7 @@ int main() { return t.value; } -// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type +// CHECK: ![[ENUM_MEMBER:[0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type // CHECK-SAME: scope: ![[STRUCT:[0-9]+]] // CHECK-SAME: elements: ![[ELEMENTS:[0-9]+]] @@ -24,3 +25,6 @@ int main() { // CHECK: ![[ELEMENTS]] = !{![[ENUMERATOR:[0-9]+]]} // CHECK: ![[ENUMERATOR]] = !DIEnumerator(name: "Unused", value: 0 + + +// NOUNUSEDTYPE-NOT: !DIEnumerator(name: "Unused" From 9322f19530c94672778e0f405eabdfd33efd90c2 Mon Sep 17 00:00:00 2001 From: "Khatavkar, Yashasvi" Date: Fri, 2 May 2025 08:06:02 -0700 Subject: [PATCH 3/5] Apply clang-format --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index e7b5383dc688e..bacd6533bd47c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1987,7 +1987,8 @@ void CGDebugInfo::CollectRecordFields( // Bump field number for next field. ++fieldNo; - } else if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo() || CGM.getCodeGenOpts().EmitCodeView) { + } else if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo() || + CGM.getCodeGenOpts().EmitCodeView) { // Debug info for nested types is included in the member list only for // CodeView. if (const auto *nestedType = dyn_cast(I)) { From c8df3c27d4ac84951d9c62fe4e70a0e4500a9b08 Mon Sep 17 00:00:00 2001 From: "Khatavkar, Yashasvi" Date: Mon, 5 May 2025 09:26:55 -0700 Subject: [PATCH 4/5] Make the emission of nested enums Similar to nested structs/classes/unions --- clang/lib/CodeGen/CGDebugInfo.cpp | 3 +-- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/test/CodeGen/unused_nested_enump.cpp | 7 ------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index bacd6533bd47c..f3ec498d4064b 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1987,8 +1987,7 @@ void CGDebugInfo::CollectRecordFields( // Bump field number for next field. ++fieldNo; - } else if (CGM.getCodeGenOpts().hasMaybeUnusedDebugInfo() || - CGM.getCodeGenOpts().EmitCodeView) { + } else if (CGM.getCodeGenOpts().EmitCodeView) { // Debug info for nested types is included in the member list only for // CodeView. if (const auto *nestedType = dyn_cast(I)) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e917f3c42da06..d63829010b3de 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -7105,7 +7105,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { } // Emit any static data members, they may be definitions. for (auto *I : CRD->decls()) - if (isa(I) || isa(I)) + if (isa(I) || isa(I) || isa(I)) EmitTopLevelDecl(I); break; } diff --git a/clang/test/CodeGen/unused_nested_enump.cpp b/clang/test/CodeGen/unused_nested_enump.cpp index 4e66c5153d213..f8a627268f428 100644 --- a/clang/test/CodeGen/unused_nested_enump.cpp +++ b/clang/test/CodeGen/unused_nested_enump.cpp @@ -15,13 +15,6 @@ int main() { // CHECK-SAME: elements: ![[ELEMENTS:[0-9]+]] // CHECK: ![[STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type -// CHECK-SAME: elements: ![[STRUCT_ELEMENTS:[0-9]+]] - -// CHECK: ![[STRUCT_ELEMENTS]] = !{![[ENUM_MEMBER:[0-9]+]], ![[VALUE_MEMBER:[0-9]+]]} - -// CHECK: ![[VALUE_MEMBER]] = !DIDerivedType(tag: DW_TAG_member -// CHECK-SAME: name: "value" -// CHECK-SAME: scope: ![[STRUCT]] // CHECK: ![[ELEMENTS]] = !{![[ENUMERATOR:[0-9]+]]} // CHECK: ![[ENUMERATOR]] = !DIEnumerator(name: "Unused", value: 0 From a0a03608ec2ca66ce94b2ba9a5b1c1d09318cbb5 Mon Sep 17 00:00:00 2001 From: "Khatavkar, Yashasvi" Date: Mon, 5 May 2025 10:43:17 -0700 Subject: [PATCH 5/5] add name tag for struct --- clang/test/CodeGen/unused_nested_enump.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CodeGen/unused_nested_enump.cpp b/clang/test/CodeGen/unused_nested_enump.cpp index f8a627268f428..7689b5bd7561b 100644 --- a/clang/test/CodeGen/unused_nested_enump.cpp +++ b/clang/test/CodeGen/unused_nested_enump.cpp @@ -10,11 +10,11 @@ int main() { return t.value; } -// CHECK: ![[ENUM_MEMBER:[0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type // CHECK-SAME: scope: ![[STRUCT:[0-9]+]] // CHECK-SAME: elements: ![[ELEMENTS:[0-9]+]] -// CHECK: ![[STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type +// CHECK: ![[STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Type" // CHECK: ![[ELEMENTS]] = !{![[ENUMERATOR:[0-9]+]]} // CHECK: ![[ENUMERATOR]] = !DIEnumerator(name: "Unused", value: 0