diff options
| author | bors <bors@rust-lang.org> | 2023-12-15 17:13:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-15 17:13:04 +0000 |
| commit | 3f39cae1199a2a0217c3646a16d1ae7fa599130b (patch) | |
| tree | 0d76b542bb913cca9b76ed56b4c5fb33e0118cbc /compiler/rustc_codegen_llvm/src | |
| parent | e6707df0de337976dce7577e68fc57adcd5e4842 (diff) | |
| parent | ce290514df95113a51346b0bd046c0436b9cc92b (diff) | |
| download | rust-3f39cae1199a2a0217c3646a16d1ae7fa599130b.tar.gz rust-3f39cae1199a2a0217c3646a16d1ae7fa599130b.zip | |
Auto merge of #115165 - davidtwco:issue-9228-describe-item-member-visibility, r=wesleywiser
codegen_llvm: set `DW_AT_accessibility` Fixes #9228. Based on #74778. Sets the accessibility of types and fields in DWARF using `DW_AT_accessibility` attribute. `DW_AT_accessibility` (public/protected/private) isn't exactly right for Rust, but neither is `DW_AT_visibility` (local/exported/qualified), and there's no way to set `DW_AT_visbility` in LLVM's API. Debuggers will special-case the handling of these per-language anyway. r? `@wesleywiser` (visited in wg-debugging triage)
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
4 files changed, 47 insertions, 15 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 7968f238b40..30c2d633840 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -977,6 +977,27 @@ fn build_field_di_node<'ll, 'tcx>( } } +/// Returns the `DIFlags` corresponding to the visibility of the item identified by `did`. +/// +/// `DIFlags::Flag{Public,Protected,Private}` correspond to `DW_AT_accessibility` +/// (public/protected/private) aren't exactly right for Rust, but neither is `DW_AT_visibility` +/// (local/exported/qualified), and there's no way to set `DW_AT_visibility` in LLVM's API. +fn visibility_di_flags<'ll, 'tcx>( + cx: &CodegenCx<'ll, 'tcx>, + did: DefId, + type_did: DefId, +) -> DIFlags { + let parent_did = cx.tcx.parent(type_did); + let visibility = cx.tcx.visibility(did); + match visibility { + Visibility::Public => DIFlags::FlagPublic, + // Private fields have a restricted visibility of the module containing the type. + Visibility::Restricted(did) if did == parent_did => DIFlags::FlagPrivate, + // `pub(crate)`/`pub(super)` visibilities are any other restricted visibility. + Visibility::Restricted(..) => DIFlags::FlagProtected, + } +} + /// Creates the debuginfo node for a Rust struct type. Maybe be a regular struct or a tuple-struct. fn build_struct_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, @@ -1000,7 +1021,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( &compute_debuginfo_type_name(cx.tcx, struct_type, false), size_and_align_of(struct_type_and_layout), Some(containing_scope), - DIFlags::FlagZero, + visibility_di_flags(cx, adt_def.did(), adt_def.did()), ), // Fields: |cx, owner| { @@ -1023,7 +1044,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( &field_name[..], (field_layout.size, field_layout.align.abi), struct_type_and_layout.fields.offset(i), - DIFlags::FlagZero, + visibility_di_flags(cx, f.did, adt_def.did()), type_di_node(cx, field_layout.ty), ) }) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 7ef185250a3..4a2861af44c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -26,8 +26,8 @@ use crate::{ enums::{tag_base_type, DiscrResult}, file_metadata, size_and_align_of, type_di_node, type_map::{self, Stub, UniqueTypeId}, - unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA, - UNKNOWN_LINE_NUMBER, + unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec, + NO_GENERICS, NO_SCOPE_METADATA, UNKNOWN_LINE_NUMBER, }, utils::DIB, }, @@ -215,7 +215,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( &enum_type_name, cx.size_and_align_of(enum_type), NO_SCOPE_METADATA, - DIFlags::FlagZero, + visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()), ), |cx, enum_type_di_node| { match enum_type_and_layout.variants { @@ -320,6 +320,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( variant_index: VariantIdx, ) -> SmallVec<&'ll DIType> { let variant_layout = enum_type_and_layout.for_variant(cx, variant_index); + let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node( cx, enum_type_and_layout, @@ -327,6 +328,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( variant_index, enum_adt_def.variant(variant_index), variant_layout, + visibility_flags, ); let tag_base_type = cx.tcx.types.u32; @@ -364,7 +366,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( // since the later is sometimes smaller (if it has fewer fields). size_and_align_of(enum_type_and_layout), Size::ZERO, - DIFlags::FlagZero, + visibility_flags, variant_struct_type_wrapper_di_node, ), unsafe { @@ -376,7 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, variant_names_type_di_node, - DIFlags::FlagZero, + visibility_flags, Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)), tag_base_type_align.bits() as u32, ) @@ -403,6 +405,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( (variant_index, variant_name) }), ); + let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices .map(|variant_index| { @@ -417,6 +420,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( variant_index, variant_def, variant_layout, + visibility_flags, ); VariantFieldInfo { @@ -437,6 +441,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>( tag_base_type, tag_field, untagged_variant_index, + visibility_flags, ) } @@ -744,6 +749,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>( tag_base_type, tag_field, None, + DIFlags::FlagZero, ) } @@ -758,6 +764,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( tag_base_type: Ty<'tcx>, tag_field: usize, untagged_variant_index: Option<VariantIdx>, + di_flags: DIFlags, ) -> SmallVec<&'ll DIType> { let tag_base_type_di_node = type_di_node(cx, tag_base_type); let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1); @@ -801,7 +808,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( align.bits() as u32, // Union fields are always at offset zero Size::ZERO.bits(), - DIFlags::FlagZero, + di_flags, variant_struct_type_wrapper, ) } @@ -835,7 +842,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( TAG_FIELD_NAME_128_LO, size_and_align, lo_offset, - DIFlags::FlagZero, + di_flags, type_di_node, )); @@ -855,7 +862,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( TAG_FIELD_NAME, cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty), enum_type_and_layout.fields.offset(tag_field), - DIFlags::FlagZero, + di_flags, tag_base_type_di_node, )); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index df1df6d197e..02a1072df6d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -250,6 +250,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( variant_index: VariantIdx, variant_def: &VariantDef, variant_layout: TyAndLayout<'tcx>, + di_flags: DIFlags, ) -> &'ll DIType { debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty); @@ -267,7 +268,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( // NOTE: We use size and align of enum_type, not from variant_layout: size_and_align_of(enum_type_and_layout), Some(enum_type_di_node), - DIFlags::FlagZero, + di_flags, ), |cx, struct_type_di_node| { (0..variant_layout.fields.count()) @@ -289,7 +290,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( &field_name, (field_layout.size, field_layout.align.abi), variant_layout.fields.offset(field_index), - DIFlags::FlagZero, + di_flags, type_di_node(cx, field_layout.ty), ) }) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 130ca2727e4..cba4e3811d5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -7,8 +7,8 @@ use crate::{ enums::tag_base_type, file_metadata, size_and_align_of, type_di_node, type_map::{self, Stub, StubInfo, UniqueTypeId}, - unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, - UNKNOWN_LINE_NUMBER, + unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec, + NO_GENERICS, UNKNOWN_LINE_NUMBER, }, utils::{create_DIArray, get_namespace_for_item, DIB}, }, @@ -63,6 +63,8 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( let enum_type_and_layout = cx.layout_of(enum_type); let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false); + let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()); + debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout)); type_map::build_type_with_children( @@ -74,7 +76,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( &enum_type_name, size_and_align_of(enum_type_and_layout), Some(containing_scope), - DIFlags::FlagZero, + visibility_flags, ), |cx, enum_type_di_node| { // Build the struct type for each variant. These will be referenced by the @@ -92,6 +94,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>( variant_index, enum_adt_def.variant(variant_index), enum_type_and_layout.for_variant(cx, variant_index), + visibility_flags, ), source_info: None, }) |
