diff options
| author | bors <bors@rust-lang.org> | 2022-03-15 10:52:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-03-15 10:52:32 +0000 |
| commit | 040703018c51409ea8c9a0cfb8f829a138d2a411 (patch) | |
| tree | ff06562be82fd8cc0db38652629e7db98df14ffa /src | |
| parent | 3ba1ebea122238d1a5c613deb1bf60ce24bd8fd8 (diff) | |
| parent | aa2408aa84cb3f758fbf572b1000ceea27fddb7f (diff) | |
Auto merge of #94261 - michaelwoerister:debuginfo-types-refactor, r=wesleywiser
debuginfo: Refactor debuginfo generation for types This PR implements the refactoring of the `rustc_codegen_llvm::debuginfo::metadata` module as described in MCP https://github.com/rust-lang/compiler-team/issues/482. In particular it - changes names to use `di_node` instead of `metadata` - uniformly names all functions that build new debuginfo nodes `build_xyz_di_node` - renames `CrateDebugContext` to `CodegenUnitDebugContext` (which is more accurate) - removes outdated parts from `compiler/rustc_codegen_llvm/src/debuginfo/doc.md` - moves `TypeMap` and functions that work directly work with it to a new `type_map` module - moves enum related builder functions to a new `enums` module - splits enum debuginfo building for the native and cpp-like cases, since they are mostly separate - uses `SmallVec` instead of `Vec` in many places - removes the old infrastructure for dealing with recursion cycles (`create_and_register_recursive_type_forward_declaration()`, `RecursiveTypeDescription`, `set_members_of_composite_type()`, `MemberDescription`, `MemberDescriptionFactory`, `prepare_xyz_metadata()`, etc) - adds `type_map::build_type_with_children()` as a replacement for dealing with recursion cycles - adds many (doc-)comments explaining what's going on - changes cpp-like naming for C-Style enums so they don't get a `enum$<...>` name (because the NatVis visualizer does not apply to them) - fixes detection of what is a C-style enum because some enums where classified as C-style even though they have fields - changes cpp-like naming for generator enums so that NatVis works for them - changes the position of discriminant debuginfo node so it is consistently nested inside the top-level union instead of, sometimes, next to it The following could be done in subsequent PRs: - add caching for `closure_saved_names_of_captured_variables` - add caching for `generator_layout_and_saved_local_names` - fix inconsistent handling of what is considered a C-style enum wrt to debuginfo - rename `metadata` module to `types` - move common generator fields to front instead of appending them This PR is based on https://github.com/rust-lang/rust/pull/93644 which is not merged yet. Right now, the changes are all done in one big commit. They could be split into smaller commits but hopefully the list of changes above makes it tractable to review them as a single commit too. For now: r? `@ghost` (let's see if this affects compile times)
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/codegen/async-fn-debug-msvc.rs | 7 | ||||
| -rw-r--r-- | src/test/codegen/async-fn-debug.rs | 4 | ||||
| -rw-r--r-- | src/test/codegen/generator-debug-msvc.rs | 7 | ||||
| -rw-r--r-- | src/test/codegen/generator-debug.rs | 4 | ||||
| -rw-r--r-- | src/test/debuginfo/generator-objects.rs | 32 | ||||
| -rw-r--r-- | src/test/debuginfo/msvc-pretty-enums.rs | 14 | ||||
| -rw-r--r-- | src/test/debuginfo/type-names.rs | 25 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest.rs | 17 |
8 files changed, 77 insertions, 33 deletions
diff --git a/src/test/codegen/async-fn-debug-msvc.rs b/src/test/codegen/async-fn-debug-msvc.rs index a90c85a5449..8995605e3dd 100644 --- a/src/test/codegen/async-fn-debug-msvc.rs +++ b/src/test/codegen/async-fn-debug-msvc.rs @@ -16,8 +16,7 @@ async fn async_fn_test() { // FIXME: No way to reliably check the filename. -// CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test" -// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "async_fn_env$0" +// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<async_fn_debug_msvc::async_fn_test::async_fn_env$0>", // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]], // For brevity, we only check the struct name and members of the last variant. // CHECK-SAME: file: [[FILE:![0-9]*]], line: 11, @@ -40,10 +39,10 @@ async fn async_fn_test() { // CHECK-SAME: baseType: [[VARIANT:![0-9]*]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) -// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], +// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) -// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]] +// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]], diff --git a/src/test/codegen/async-fn-debug.rs b/src/test/codegen/async-fn-debug.rs index 8fbd2765fd7..9f6058a71b3 100644 --- a/src/test/codegen/async-fn-debug.rs +++ b/src/test/codegen/async-fn-debug.rs @@ -18,7 +18,7 @@ async fn async_fn_test() { // CHECK-DAG: [[ASYNC_FN:!.*]] = !DINamespace(name: "async_fn_test" // CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[ASYNC_FN]] -// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[ASYNC_FN]], +// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: discriminator: [[DISC:![0-9]*]] // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]], @@ -50,7 +50,7 @@ async fn async_fn_test() { // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) -// CHECK: [[DISC]] = !DIDerivedType(tag: DW_TAG_member, name: "__state", scope: [[ASYNC_FN]], +// CHECK: [[DISC]] = !DIDerivedType(tag: DW_TAG_member, name: "__state", scope: [[GEN]], // CHECK-SAME: flags: DIFlagArtificial fn main() { diff --git a/src/test/codegen/generator-debug-msvc.rs b/src/test/codegen/generator-debug-msvc.rs index fb8b9e09fd2..74b1eb948b0 100644 --- a/src/test/codegen/generator-debug-msvc.rs +++ b/src/test/codegen/generator-debug-msvc.rs @@ -20,8 +20,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> { // FIXME: No way to reliably check the filename. -// CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test" -// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "generator_env$0" +// CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum$<generator_debug_msvc::generator_test::generator_env$0>" // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "variant0", scope: [[GEN]], // For brevity, we only check the struct name and members of the last variant. // CHECK-SAME: file: [[FILE:![0-9]*]], line: 14, @@ -44,10 +43,10 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> { // CHECK-SAME: baseType: [[VARIANT:![0-9]*]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) -// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], +// CHECK: [[VARIANT]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) -// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]] +// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[VARIANT]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "discriminant", scope: [[GEN]], diff --git a/src/test/codegen/generator-debug.rs b/src/test/codegen/generator-debug.rs index e777fe3af63..3ec860f2cbc 100644 --- a/src/test/codegen/generator-debug.rs +++ b/src/test/codegen/generator-debug.rs @@ -22,7 +22,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> { // CHECK-DAG: [[GEN_FN:!.*]] = !DINamespace(name: "generator_test" // CHECK-DAG: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{generator_env#0}", scope: [[GEN_FN]] -// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN_FN]], +// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[GEN]], // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: discriminator: [[DISC:![0-9]*]] // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]], @@ -54,7 +54,7 @@ fn generator_test() -> impl Generator<Yield = i32, Return = ()> { // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]] // CHECK-NOT: flags: DIFlagArtificial // CHECK-SAME: ) -// CHECK: [[DISC]] = !DIDerivedType(tag: DW_TAG_member, name: "__state", scope: [[GEN_FN]], +// CHECK: [[DISC]] = !DIDerivedType(tag: DW_TAG_member, name: "__state", scope: [[GEN]], // CHECK-SAME: flags: DIFlagArtificial fn main() { diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs index aee19736e7e..d6d7e5b44aa 100644 --- a/src/test/debuginfo/generator-objects.rs +++ b/src/test/debuginfo/generator-objects.rs @@ -37,6 +37,37 @@ // lldb-command:print b // lldbg-check:(generator_objects::main::{generator_env#0}) $3 = +// === CDB TESTS =================================================================================== + +// cdb-command: g +// cdb-command: dx b +// cdb-check: b : Unresumed [Type: enum$<generator_objects::main::generator_env$0>] +// cdb-check: [variant] : Unresumed +// cdb-check: [+0x[...]] _ref__a : 0x[...] : 5 [Type: int *] + +// cdb-command: g +// cdb-command: dx b +// cdb-check: b : Suspend0 [Type: enum$<generator_objects::main::generator_env$0>] +// cdb-check: [variant] : Suspend0 +// cdb-check: [+0x[...]] c : 6 [Type: int] +// cdb-check: [+0x[...]] d : 7 [Type: int] +// cdb-check: [+0x[...]] _ref__a : 0x[...] : 5 [Type: int *] + +// cdb-command: g +// cdb-command: dx b +// cdb-check: b : Suspend1 [Type: enum$<generator_objects::main::generator_env$0>] +// cdb-check: [variant] : Suspend1 +// cdb-check: [+0x[...]] c : 7 [Type: int] +// cdb-check: [+0x[...]] d : 8 [Type: int] +// cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *] + +// cdb-command: g +// cdb-command: dx b +// cdb-check: b : Returned [Type: enum$<generator_objects::main::generator_env$0>] +// cdb-check: [<Raw View>] [Type: enum$<generator_objects::main::generator_env$0>] +// cdb-check: [variant] : Returned +// cdb-check: [+0x[...]] _ref__a : 0x[...] : 6 [Type: int *] + #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)] #![omit_gdb_pretty_printer_section] @@ -66,6 +97,7 @@ fn main() { _zzz(); // #break } +#[inline(never)] fn _zzz() { () } diff --git a/src/test/debuginfo/msvc-pretty-enums.rs b/src/test/debuginfo/msvc-pretty-enums.rs index 642694355ad..a153a9a4228 100644 --- a/src/test/debuginfo/msvc-pretty-enums.rs +++ b/src/test/debuginfo/msvc-pretty-enums.rs @@ -4,14 +4,14 @@ // cdb-command: g // cdb-command: dx a -// cdb-check:a : Some({...}) [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>] -// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>] +// cdb-check:a : Some({...}) [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>] +// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>] // cdb-check: [variant] : Some // cdb-check: [+0x000] __0 : Low (0x2) [Type: msvc_pretty_enums::CStyleEnum] // cdb-command: dx b -// cdb-check:b : None [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>] -// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<enum$<msvc_pretty_enums::CStyleEnum> >, 2, 16, Some>] +// cdb-check:b : None [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>] +// cdb-check: [<Raw View>] [Type: enum$<core::option::Option<msvc_pretty_enums::CStyleEnum>, 2, 16, Some>] // cdb-check: [variant] : None // cdb-command: dx c @@ -78,7 +78,7 @@ pub enum NicheLayoutEnum { Tag2, } -pub enum Empty { } +pub enum Empty {} fn main() { let a = Some(CStyleEnum::Low); @@ -97,4 +97,6 @@ fn main() { zzz(); // #break } -fn zzz() { () } +fn zzz() { + () +} diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index c9692128562..52841d50f64 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -33,10 +33,10 @@ // gdb-check:type = type_names::mod1::Enum2 // gdb-command:whatis generic_enum_1 -// gdb-check:type = type_names::mod1::mod2::Enum3 +// gdb-check:type = type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> // gdb-command:whatis generic_enum_2 -// gdb-check:type = type_names::mod1::mod2::Enum3 +// gdb-check:type = type_names::mod1::mod2::Enum3<type_names::Struct1> // TUPLES // gdb-command:whatis tuple1 @@ -159,10 +159,10 @@ // FOREIGN TYPES // gdb-command:whatis foreign1 -// gdb-check:type = *mut ForeignType1 +// gdb-check:type = *mut type_names::{extern#0}::ForeignType1 // gdb-command:whatis foreign2 -// gdb-check:type = *mut ForeignType2 +// gdb-check:type = *mut type_names::mod1::{extern#0}::ForeignType2 // === CDB TESTS ================================================================================== @@ -178,9 +178,9 @@ // cdb-command:dv /t *_enum_* // cdb-check:union enum$<type_names::Enum1> simple_enum_1 = [...] // cdb-check:union enum$<type_names::Enum1> simple_enum_2 = [...] -// cdb-check:type_names::mod1::Enum2 simple_enum_3 = [...] -// cdb-check:type_names::mod1::mod2::Enum3 generic_enum_1 = [...] -// cdb-check:type_names::mod1::mod2::Enum3 generic_enum_2 = [...] +// cdb-check:union enum$<type_names::mod1::Enum2> simple_enum_3 = [...] +// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::mod1::Struct2> > generic_enum_1 = [...] +// cdb-check:union enum$<type_names::mod1::mod2::Enum3<type_names::Struct1> > generic_enum_2 = [...] // TUPLES // cdb-command:dv /t tuple* @@ -258,8 +258,8 @@ // FOREIGN TYPES // cdb-command:dv /t foreign* -// cdb-check:struct ForeignType2 * foreign2 = [...] -// cdb-check:struct ForeignType1 * foreign1 = [...] +// cdb-check:struct type_names::mod1::extern$0::ForeignType2 * foreign2 = [...] +// cdb-check:struct type_names::extern$0::ForeignType1 * foreign1 = [...] #![allow(unused_variables)] #![feature(omit_gdb_pretty_printer_section)] @@ -283,7 +283,6 @@ extern "C" { } mod mod1 { - pub use self::Enum2::{Variant1, Variant2}; pub struct Struct2; pub enum Enum2 { @@ -367,14 +366,14 @@ fn main() { // Enums let simple_enum_1 = Variant1; let simple_enum_2 = Variant2(0); - let simple_enum_3 = mod1::Variant2(Struct1); + let simple_enum_3 = mod1::Enum2::Variant2(Struct1); let generic_enum_1: mod1::mod2::Enum3<mod1::Struct2> = mod1::mod2::Variant1; let generic_enum_2 = mod1::mod2::Variant2(Struct1); // Tuples let tuple1 = (8u32, Struct1, mod1::mod2::Variant2(mod1::Struct2)); - let tuple2 = ((Struct1, mod1::mod2::Struct3), mod1::Variant1, 'x'); + let tuple2 = ((Struct1, mod1::mod2::Struct3), mod1::Enum2::Variant1, 'x'); // Box let box1 = (Box::new(1f32), 0i32); @@ -404,7 +403,7 @@ fn main() { let vec1 = vec![0_usize, 2, 3]; let slice1 = &*vec1; - let vec2 = vec![mod1::Variant2(Struct1)]; + let vec2 = vec![mod1::Enum2::Variant2(Struct1)]; let slice2 = &*vec2; // Trait Objects diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 8431aa7b818..6b27d1ecbf5 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -661,6 +661,21 @@ impl<'test> TestCx<'test> { } fn run_debuginfo_cdb_test_no_opt(&self) { + let exe_file = self.make_exe_name(); + + // Existing PDB files are update in-place. When changing the debuginfo + // the compiler generates for something, this can lead to the situation + // where both the old and the new version of the debuginfo for the same + // type is present in the PDB, which is very confusing. + // Therefore we delete any existing PDB file before compiling the test + // case. + // FIXME: If can reliably detect that MSVC's link.exe is used, then + // passing `/INCREMENTAL:NO` might be a cleaner way to do this. + let pdb_file = exe_file.with_extension(".pdb"); + if pdb_file.exists() { + std::fs::remove_file(pdb_file).unwrap(); + } + // compile test file (it should have 'compile-flags:-g' in the header) let should_run = self.run_if_enabled(); let compile_result = self.compile_test(should_run, EmitMetadata::No); @@ -671,8 +686,6 @@ impl<'test> TestCx<'test> { return; } - let exe_file = self.make_exe_name(); - let prefixes = { static PREFIXES: &[&str] = &["cdb", "cdbg"]; // No "native rust support" variation for CDB yet. |
