Auto merge of #104342 - mweber15:add_file_location_to_more_types, r=wesleywiser

Require `type_map::stub` callers to supply file information

This change attaches file information (`DIFile` reference and line number) to struct debug info nodes.

Before:

```
; foo.ll
...
!5 = !DIFile(filename: "<unknown>", directory: "")
...
!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !5, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "4cb373851db92e732c4cb5651b886dd0")
...
```

After:

```
; foo.ll
...
!3 = !DIFile(filename: "foo.rs", directory: "/home/matt/src/rust98678", checksumkind: CSK_SHA1, checksum: "bcb9f08512c8f3b8181ef4726012bc6807bc9be4")
...
!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", scope: !2, file: !3, line: 3, size: 32, align: 32, elements: !17, templateParams: !19, identifier: "9e5968c7af39c148acb253912b7f409f")
...
```

Fixes #98678

r? `@wesleywiser`
This commit is contained in:
bors
2024-12-03 12:49:57 +00:00
12 changed files with 350 additions and 27 deletions

View File

@@ -4,7 +4,7 @@ use libc::c_uint;
use rustc_abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
use rustc_codegen_ssa::traits::ConstCodegenMethods;
use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods};
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
@@ -16,8 +16,8 @@ use crate::debuginfo::metadata::enums::DiscrResult;
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
use crate::debuginfo::metadata::{
DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER,
build_field_di_node, file_metadata, size_and_align_of, type_di_node, unknown_file_metadata,
visibility_di_flags,
build_field_di_node, file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node,
unknown_file_metadata, visibility_di_flags,
};
use crate::debuginfo::utils::DIB;
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};
@@ -192,6 +192,12 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout));
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(file_metadata_from_def_id(cx, Some(enum_adt_def.did())))
} else {
None
};
type_map::build_type_with_children(
cx,
type_map::stub(
@@ -199,6 +205,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
type_map::Stub::Union,
unique_type_id,
&enum_type_name,
def_location,
cx.size_and_align_of(enum_type),
NO_SCOPE_METADATA,
visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()),
@@ -262,6 +269,14 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
let coroutine_type = unique_type_id.expect_ty();
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
let &ty::Coroutine(coroutine_def_id, _) = coroutine_type.kind() else {
bug!("build_coroutine_di_node() called with non-coroutine type: `{:?}`", coroutine_type)
};
Some(file_metadata_from_def_id(cx, Some(coroutine_def_id)))
} else {
None
};
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
@@ -274,6 +289,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
type_map::Stub::Union,
unique_type_id,
&coroutine_type_name,
def_location,
size_and_align_of(coroutine_type_and_layout),
NO_SCOPE_METADATA,
DIFlags::FlagZero,
@@ -321,6 +337,12 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
let tag_base_type_di_node = type_di_node(cx, tag_base_type);
let tag_base_type_align = cx.align_of(tag_base_type);
let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(enum_adt_def.did())
} else {
None
};
let variant_names_type_di_node = build_variant_names_type_di_node(
cx,
enum_type_di_node,
@@ -328,6 +350,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
variant_index,
Cow::from(enum_adt_def.variant(variant_index).name.as_str()),
)),
enum_adt_def_id,
);
let variant_struct_type_wrapper_di_node = build_variant_struct_wrapper_type_di_node(
@@ -341,6 +364,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
tag_base_type_di_node,
tag_base_type,
DiscrResult::NoDiscriminant,
None,
);
smallvec![
@@ -354,6 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
Size::ZERO,
visibility_flags,
variant_struct_type_wrapper_di_node,
None,
),
unsafe {
llvm::LLVMRustDIBuilderCreateStaticMemberType(
@@ -383,6 +408,12 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
) -> SmallVec<&'ll DIType> {
let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout);
let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(enum_adt_def.did())
} else {
None
};
let variant_names_type_di_node = build_variant_names_type_di_node(
cx,
enum_type_di_node,
@@ -390,6 +421,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
let variant_name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
(variant_index, variant_name)
}),
enum_adt_def_id,
);
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
@@ -447,6 +479,7 @@ fn build_variant_names_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
containing_scope: &'ll DIType,
variants: impl Iterator<Item = (VariantIdx, Cow<'tcx, str>)>,
enum_def_id: Option<rustc_span::def_id::DefId>,
) -> &'ll DIType {
// Create an enumerator for each variant.
super::build_enumeration_type_di_node(
@@ -454,6 +487,7 @@ fn build_variant_names_type_di_node<'ll, 'tcx>(
"VariantNames",
variant_names_enum_base_type(cx),
variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32().into())),
enum_def_id,
containing_scope,
)
}
@@ -469,6 +503,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
tag_base_type_di_node: &'ll DIType,
tag_base_type: Ty<'tcx>,
discr: DiscrResult,
source_info: Option<(&'ll DIFile, c_uint)>,
) -> &'ll DIType {
type_map::build_type_with_children(
cx,
@@ -481,6 +516,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
variant_index,
),
&variant_struct_wrapper_type_name(variant_index),
source_info,
// NOTE: We use size and align of enum_type, not from variant_layout:
size_and_align_of(enum_or_coroutine_type_and_layout),
Some(enum_or_coroutine_type_di_node),
@@ -530,6 +566,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
Size::ZERO,
DIFlags::FlagZero,
variant_struct_type_di_node,
None,
));
let build_assoc_const =
@@ -684,6 +721,11 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
variant_range
.clone()
.map(|variant_index| (variant_index, CoroutineArgs::variant_name(variant_index))),
if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(coroutine_def_id)
} else {
None
},
);
let discriminants: IndexVec<VariantIdx, DiscrResult> = {
@@ -776,6 +818,11 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
tag_base_type_di_node,
tag_base_type,
variant_member_info.discr,
if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
variant_member_info.source_info
} else {
None
},
);
// We use LLVMRustDIBuilderCreateMemberType() member type directly because
@@ -831,6 +878,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
lo_offset,
di_flags,
type_di_node,
None,
));
unions_fields.push(build_field_di_node(
@@ -841,6 +889,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
hi_offset,
DIFlags::FlagZero,
type_di_node,
None,
));
} else {
unions_fields.push(build_field_di_node(
@@ -851,6 +900,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
enum_type_and_layout.fields.offset(tag_field),
di_flags,
tag_base_type_di_node,
None,
));
}

View File

@@ -3,6 +3,7 @@ use std::borrow::Cow;
use rustc_abi::{FieldIdx, TagEncoding, VariantIdx, Variants};
use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo};
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
use rustc_codegen_ssa::traits::MiscCodegenMethods;
use rustc_hir::def::CtorKind;
use rustc_index::IndexSlice;
use rustc_middle::bug;
@@ -16,8 +17,8 @@ use super::{SmallVec, size_and_align_of};
use crate::common::{AsCCharPtr, CodegenCx};
use crate::debuginfo::metadata::type_map::{self, Stub};
use crate::debuginfo::metadata::{
UNKNOWN_LINE_NUMBER, build_field_di_node, build_generic_type_param_di_nodes, type_di_node,
unknown_file_metadata,
UNKNOWN_LINE_NUMBER, build_field_di_node, build_generic_type_param_di_nodes,
file_metadata_from_def_id, type_di_node, unknown_file_metadata,
};
use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item};
use crate::llvm::debuginfo::{DIFlags, DIType};
@@ -68,6 +69,11 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
enum_type_and_layout: TyAndLayout<'tcx>,
) -> DINodeCreationResult<'ll> {
let containing_scope = get_namespace_for_item(cx, enum_adt_def.did());
let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(enum_adt_def.did())
} else {
None
};
DINodeCreationResult {
di_node: build_enumeration_type_di_node(
cx,
@@ -77,6 +83,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
(name, discr.val)
}),
enum_adt_def_id,
containing_scope,
),
already_stored_in_typemap: false,
@@ -92,6 +99,7 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
type_name: &str,
base_type: Ty<'tcx>,
enumerators: impl Iterator<Item = (Cow<'tcx, str>, u128)>,
def_id: Option<rustc_span::def_id::DefId>,
containing_scope: &'ll DIType,
) -> &'ll DIType {
let is_unsigned = match base_type.kind() {
@@ -115,14 +123,21 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
})
.collect();
let (file_metadata, line_number) = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers
{
file_metadata_from_def_id(cx, def_id)
} else {
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
};
unsafe {
llvm::LLVMRustDIBuilderCreateEnumerationType(
DIB(cx),
containing_scope,
type_name.as_c_char_ptr(),
type_name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
file_metadata,
line_number,
size.bits(),
align.bits() as u32,
create_DIArray(DIB(cx), &enumerator_di_nodes[..]),
@@ -193,6 +208,12 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
) -> &'ll DIType {
assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(file_metadata_from_def_id(cx, Some(variant_def.def_id)))
} else {
None
};
type_map::build_type_with_children(
cx,
type_map::stub(
@@ -204,6 +225,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
variant_index,
),
variant_def.name.as_str(),
def_location,
// 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),
@@ -231,6 +253,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
variant_layout.fields.offset(field_index),
di_flags,
type_di_node(cx, field_layout.ty),
None,
)
})
.collect::<SmallVec<_>>()
@@ -286,6 +309,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
Stub::Struct,
unique_type_id,
&variant_name,
None,
size_and_align_of(coroutine_type_and_layout),
Some(coroutine_type_di_node),
DIFlags::FlagZero,
@@ -312,6 +336,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
variant_layout.fields.offset(field_index),
DIFlags::FlagZero,
type_di_node(cx, field_type),
None,
)
})
.collect();
@@ -331,6 +356,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
coroutine_type_and_layout.fields.offset(index),
DIFlags::FlagZero,
type_di_node(cx, upvar_ty),
None,
)
})
.collect();

View File

@@ -4,7 +4,7 @@ use libc::c_uint;
use rustc_abi::{Size, TagEncoding, VariantIdx, Variants};
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
use rustc_codegen_ssa::traits::ConstCodegenMethods;
use rustc_codegen_ssa::traits::{ConstCodegenMethods, MiscCodegenMethods};
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{self};
@@ -14,7 +14,8 @@ use crate::common::{AsCCharPtr, CodegenCx};
use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId};
use crate::debuginfo::metadata::{
DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, file_metadata,
size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
file_metadata_from_def_id, size_and_align_of, type_di_node, unknown_file_metadata,
visibility_di_flags,
};
use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item};
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};
@@ -55,6 +56,12 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout));
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(file_metadata_from_def_id(cx, Some(enum_adt_def.did())))
} else {
None
};
type_map::build_type_with_children(
cx,
type_map::stub(
@@ -62,6 +69,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
Stub::Struct,
unique_type_id,
&enum_type_name,
def_location,
size_and_align_of(enum_type_and_layout),
Some(containing_scope),
visibility_flags,
@@ -84,14 +92,27 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
enum_type_and_layout.for_variant(cx, variant_index),
visibility_flags,
),
source_info: None,
source_info: if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(file_metadata_from_def_id(
cx,
Some(enum_adt_def.variant(variant_index).def_id),
))
} else {
None
},
})
.collect();
let enum_adt_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(enum_adt_def.did())
} else {
None
};
smallvec![build_enum_variant_part_di_node(
cx,
enum_type_and_layout,
enum_type_di_node,
enum_adt_def_id,
&variant_member_infos[..],
)]
},
@@ -134,6 +155,12 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(file_metadata_from_def_id(cx, Some(coroutine_def_id)))
} else {
None
};
type_map::build_type_with_children(
cx,
type_map::stub(
@@ -141,6 +168,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
Stub::Struct,
unique_type_id,
&coroutine_type_name,
def_location,
size_and_align_of(coroutine_type_and_layout),
Some(containing_scope),
DIFlags::FlagZero,
@@ -197,10 +225,16 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
})
.collect();
let coroutine_def_id = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers {
Some(coroutine_def_id)
} else {
None
};
smallvec![build_enum_variant_part_di_node(
cx,
coroutine_type_and_layout,
coroutine_type_di_node,
coroutine_def_id,
&variant_struct_type_di_nodes[..],
)]
},
@@ -228,6 +262,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>,
enum_type_di_node: &'ll DIType,
enum_type_def_id: Option<rustc_span::def_id::DefId>,
variant_member_infos: &[VariantMemberInfo<'_, 'll>],
) -> &'ll DIType {
let tag_member_di_node =
@@ -236,6 +271,13 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>(
let variant_part_unique_type_id =
UniqueTypeId::for_enum_variant_part(cx.tcx, enum_type_and_layout.ty);
let (file_metadata, line_number) = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers
{
file_metadata_from_def_id(cx, enum_type_def_id)
} else {
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
};
let stub = StubInfo::new(
cx,
variant_part_unique_type_id,
@@ -246,8 +288,8 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>(
enum_type_di_node,
variant_part_name.as_c_char_ptr(),
variant_part_name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
file_metadata,
line_number,
enum_type_and_layout.size.bits(),
enum_type_and_layout.align.abi.bits() as u32,
DIFlags::FlagZero,

View File

@@ -8,7 +8,7 @@ use rustc_macros::HashStable;
use rustc_middle::bug;
use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt};
use super::{SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata};
use crate::common::{AsCCharPtr, CodegenCx};
use crate::debuginfo::utils::{DIB, create_DIArray, debug_context};
use crate::llvm::debuginfo::{DIFlags, DIScope, DIType};
@@ -186,6 +186,7 @@ pub(super) fn stub<'ll, 'tcx>(
kind: Stub<'ll>,
unique_type_id: UniqueTypeId<'tcx>,
name: &str,
def_location: Option<DefinitionLocation<'ll>>,
(size, align): (Size, Align),
containing_scope: Option<&'ll DIScope>,
flags: DIFlags,
@@ -193,6 +194,12 @@ pub(super) fn stub<'ll, 'tcx>(
let empty_array = create_DIArray(DIB(cx), &[]);
let unique_type_id_str = unique_type_id.generate_unique_id_string(cx.tcx);
let (file_metadata, line_number) = if let Some(def_location) = def_location {
(def_location.0, def_location.1)
} else {
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
};
let metadata = match kind {
Stub::Struct | Stub::VTableTy { .. } => {
let vtable_holder = match kind {
@@ -205,8 +212,8 @@ pub(super) fn stub<'ll, 'tcx>(
containing_scope,
name.as_c_char_ptr(),
name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
file_metadata,
line_number,
size.bits(),
align.bits() as u32,
flags,
@@ -225,8 +232,8 @@ pub(super) fn stub<'ll, 'tcx>(
containing_scope,
name.as_c_char_ptr(),
name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
file_metadata,
line_number,
size.bits(),
align.bits() as u32,
flags,