1
Fork 0

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 { } else {
(unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) (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 { unsafe {
llvm::LLVMRustDIBuilderCreateMemberType( llvm::LLVMRustDIBuilderCreateMemberType(
DIB(cx), 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::type_map::{self, Stub, UniqueTypeId};
use crate::debuginfo::metadata::{ use crate::debuginfo::metadata::{
DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER, 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, build_field_di_node, create_member_type, file_metadata, file_metadata_from_def_id,
unknown_file_metadata, visibility_di_flags, size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
}; };
use crate::debuginfo::utils::DIB; use crate::debuginfo::utils::DIB;
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType}; 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)); .unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER));
let field_name = variant_union_field_name(variant_member_info.variant_index); 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( let variant_struct_type_wrapper = build_variant_struct_wrapper_type_di_node(
cx, 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, // the build_field_di_node() function does not support specifying a source location,
// which is something that we don't do anywhere else. // which is something that we don't do anywhere else.
unsafe { create_member_type(
llvm::LLVMRustDIBuilderCreateMemberType( cx,
DIB(cx), enum_type_di_node,
enum_type_di_node, &field_name,
field_name.as_c_char_ptr(), file_di_node,
field_name.len(), line_number,
file_di_node, // NOTE: We use the layout of the entire type, not from variant_layout
line_number, // since the later is sometimes smaller (if it has fewer fields).
// NOTE: We use the size and align of the entire type, not from variant_layout enum_type_and_layout,
// since the later is sometimes smaller (if it has fewer fields). // Union fields are always at offset zero
size.bits(), Size::ZERO,
align.bits() as u32, di_flags,
// Union fields are always at offset zero variant_struct_type_wrapper,
Size::ZERO.bits(), )
di_flags,
variant_struct_type_wrapper,
)
}
})); }));
assert_eq!( assert_eq!(

View file

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