Create a safe wrapper around LLVMRustDIBuilderCreateMemberType

This commit is contained in:
Oli Scherer 2025-03-17 17:00:52 +00:00
parent 1f34b19596
commit f4b0984854
3 changed files with 59 additions and 41 deletions

View file

@ -984,6 +984,30 @@ fn build_field_di_node<'ll, 'tcx>(
} else {
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
};
create_member_type(
cx,
owner,
name,
file_metadata,
line_number,
layout,
offset,
flags,
type_di_node,
)
}
fn create_member_type<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
owner: &'ll DIScope,
name: &str,
file_metadata: &'ll DIType,
line_number: u32,
layout: TyAndLayout<'tcx>,
offset: Size,
flags: DIFlags,
type_di_node: &'ll DIType,
) -> &'ll DIType {
unsafe {
llvm::LLVMRustDIBuilderCreateMemberType(
DIB(cx),

View file

@ -17,8 +17,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, file_metadata_from_def_id, size_and_align_of, type_di_node,
unknown_file_metadata, visibility_di_flags,
build_field_di_node, create_member_type, 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};
@ -820,7 +820,6 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
.unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER));
let field_name = variant_union_field_name(variant_member_info.variant_index);
let (size, align) = size_and_align_of(enum_type_and_layout);
let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node(
cx,
@ -840,27 +839,23 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
},
);
// We use LLVMRustDIBuilderCreateMemberType() member type directly because
// We use create_member_type() member type directly because
// the build_field_di_node() function does not support specifying a source location,
// which is something that we don't do anywhere else.
unsafe {
llvm::LLVMRustDIBuilderCreateMemberType(
DIB(cx),
enum_type_di_node,
field_name.as_c_char_ptr(),
field_name.len(),
file_di_node,
line_number,
// NOTE: We use the size and align of the entire type, not from variant_layout
// since the later is sometimes smaller (if it has fewer fields).
size.bits(),
align.bits() as u32,
// Union fields are always at offset zero
Size::ZERO.bits(),
di_flags,
variant_struct_type_wrapper,
)
}
create_member_type(
cx,
enum_type_di_node,
&field_name,
file_di_node,
line_number,
// NOTE: We use the layout of the entire type, not from variant_layout
// since the later is sometimes smaller (if it has fewer fields).
enum_type_and_layout,
// Union fields are always at offset zero
Size::ZERO,
di_flags,
variant_struct_type_wrapper,
)
}));
assert_eq!(

View file

@ -13,9 +13,9 @@ use smallvec::smallvec;
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,
file_metadata_from_def_id, size_and_align_of, type_di_node, unknown_file_metadata,
visibility_di_flags,
DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, create_member_type,
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, create_DIArray, get_namespace_for_item};
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};
@ -363,23 +363,22 @@ fn build_discr_member_di_node<'ll, 'tcx>(
&Variants::Multiple { tag_field, .. } => {
let tag_base_type = tag_base_type(cx.tcx, enum_or_coroutine_type_and_layout);
let (size, align) = cx.size_and_align_of(tag_base_type);
let ty = type_di_node(cx, tag_base_type);
let file = unknown_file_metadata(cx);
unsafe {
Some(llvm::LLVMRustDIBuilderCreateMemberType(
DIB(cx),
containing_scope,
tag_name.as_c_char_ptr(),
tag_name.len(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
size.bits(),
align.bits() as u32,
enum_or_coroutine_type_and_layout.fields.offset(tag_field).bits(),
DIFlags::FlagArtificial,
type_di_node(cx, tag_base_type),
))
}
let layout = cx.layout_of(tag_base_type);
Some(create_member_type(
cx,
containing_scope,
&tag_name,
file,
UNKNOWN_LINE_NUMBER,
layout,
enum_or_coroutine_type_and_layout.fields.offset(tag_field),
DIFlags::FlagArtificial,
ty,
))
}
}
}