Rollup merge of #138674 - oli-obk:llvm-cleanups, r=compiler-errors
Various codegen_llvm cleanups Mostly just adding safe wrappers and deduplicating code
This commit is contained in:
commit
5661e98058
6 changed files with 206 additions and 205 deletions
|
@ -2,6 +2,7 @@ use std::borrow::Cow;
|
|||
use std::fmt::{self, Write};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::{iter, ptr};
|
||||
|
||||
use libc::{c_char, c_longlong, c_uint};
|
||||
|
@ -38,8 +39,8 @@ use crate::debuginfo::metadata::type_map::build_type_with_children;
|
|||
use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind};
|
||||
use crate::llvm;
|
||||
use crate::llvm::debuginfo::{
|
||||
DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind,
|
||||
DebugNameTableKind,
|
||||
DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock,
|
||||
DIScope, DIType, DebugEmissionKind, DebugNameTableKind,
|
||||
};
|
||||
use crate::value::Value;
|
||||
|
||||
|
@ -68,7 +69,8 @@ pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
|||
|
||||
const NO_SCOPE_METADATA: Option<&DIScope> = None;
|
||||
/// A function that returns an empty list of generic parameter debuginfo nodes.
|
||||
const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<&'ll DIType> = |_| SmallVec::new();
|
||||
const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<Option<&'ll DIType>> =
|
||||
|_| SmallVec::new();
|
||||
|
||||
// SmallVec is used quite a bit in this module, so create a shorthand.
|
||||
// The actual number of elements is not so important.
|
||||
|
@ -243,7 +245,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
owner,
|
||||
addr_field_name,
|
||||
(addr_field.size, addr_field.align.abi),
|
||||
addr_field,
|
||||
layout.fields.offset(WIDE_PTR_ADDR),
|
||||
DIFlags::FlagZero,
|
||||
data_ptr_type_di_node,
|
||||
|
@ -253,7 +255,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
owner,
|
||||
extra_field_name,
|
||||
(extra_field.size, extra_field.align.abi),
|
||||
extra_field,
|
||||
layout.fields.offset(WIDE_PTR_EXTRA),
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, extra_field.ty),
|
||||
|
@ -311,12 +313,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
|
|||
|
||||
debug_context(cx).type_map.unique_id_to_di_node.borrow_mut().remove(&unique_type_id);
|
||||
|
||||
let fn_di_node = unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateSubroutineType(
|
||||
DIB(cx),
|
||||
create_DIArray(DIB(cx), &signature_di_nodes[..]),
|
||||
)
|
||||
};
|
||||
let fn_di_node = create_subroutine_type(cx, create_DIArray(DIB(cx), &signature_di_nodes[..]));
|
||||
|
||||
// This is actually a function pointer, so wrap it in pointer DI.
|
||||
let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false);
|
||||
|
@ -340,6 +337,13 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
|
|||
DINodeCreationResult::new(di_node, false)
|
||||
}
|
||||
|
||||
pub(super) fn create_subroutine_type<'ll>(
|
||||
cx: &CodegenCx<'ll, '_>,
|
||||
signature: &'ll DICompositeType,
|
||||
) -> &'ll DICompositeType {
|
||||
unsafe { llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(cx), signature) }
|
||||
}
|
||||
|
||||
/// Create debuginfo for `dyn SomeTrait` types. Currently these are empty structs
|
||||
/// we with the correct type name (e.g. "dyn SomeTrait<Foo, Item=u32> + Sync").
|
||||
fn build_dyn_type_di_node<'ll, 'tcx>(
|
||||
|
@ -487,26 +491,22 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
|
|||
// FIXME(mw): Cache this via a regular UniqueTypeId instead of an extra field in the debug context.
|
||||
fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll DIType {
|
||||
*debug_context(cx).recursion_marker_type.get_or_init(move || {
|
||||
unsafe {
|
||||
// The choice of type here is pretty arbitrary -
|
||||
// anything reading the debuginfo for a recursive
|
||||
// type is going to see *something* weird - the only
|
||||
// question is what exactly it will see.
|
||||
//
|
||||
// FIXME: the name `<recur_type>` does not fit the naming scheme
|
||||
// of other types.
|
||||
//
|
||||
// FIXME: it might make sense to use an actual pointer type here
|
||||
// so that debuggers can show the address.
|
||||
let name = "<recur_type>";
|
||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
||||
DIB(cx),
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
cx.tcx.data_layout.pointer_size.bits(),
|
||||
dwarf_const::DW_ATE_unsigned,
|
||||
)
|
||||
}
|
||||
// The choice of type here is pretty arbitrary -
|
||||
// anything reading the debuginfo for a recursive
|
||||
// type is going to see *something* weird - the only
|
||||
// question is what exactly it will see.
|
||||
//
|
||||
// FIXME: the name `<recur_type>` does not fit the naming scheme
|
||||
// of other types.
|
||||
//
|
||||
// FIXME: it might make sense to use an actual pointer type here
|
||||
// so that debuggers can show the address.
|
||||
create_basic_type(
|
||||
cx,
|
||||
"<recur_type>",
|
||||
cx.tcx.data_layout.pointer_size,
|
||||
dwarf_const::DW_ATE_unsigned,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -620,42 +620,38 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi
|
|||
let source =
|
||||
cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref());
|
||||
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateFile(
|
||||
DIB(cx),
|
||||
file_name.as_c_char_ptr(),
|
||||
file_name.len(),
|
||||
directory.as_c_char_ptr(),
|
||||
directory.len(),
|
||||
hash_kind,
|
||||
hash_value.as_c_char_ptr(),
|
||||
hash_value.len(),
|
||||
source.map_or(ptr::null(), |x| x.as_c_char_ptr()),
|
||||
source.map_or(0, |x| x.len()),
|
||||
)
|
||||
}
|
||||
create_file(DIB(cx), &file_name, &directory, &hash_value, hash_kind, source)
|
||||
}
|
||||
}
|
||||
|
||||
fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
||||
debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe {
|
||||
let file_name = "<unknown>";
|
||||
let directory = "";
|
||||
let hash_value = "";
|
||||
debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| {
|
||||
create_file(DIB(cx), "<unknown>", "", "", llvm::ChecksumKind::None, None)
|
||||
})
|
||||
}
|
||||
|
||||
fn create_file<'ll>(
|
||||
builder: &DIBuilder<'ll>,
|
||||
file_name: &str,
|
||||
directory: &str,
|
||||
hash_value: &str,
|
||||
hash_kind: llvm::ChecksumKind,
|
||||
source: Option<&Arc<String>>,
|
||||
) -> &'ll DIFile {
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateFile(
|
||||
DIB(cx),
|
||||
builder,
|
||||
file_name.as_c_char_ptr(),
|
||||
file_name.len(),
|
||||
directory.as_c_char_ptr(),
|
||||
directory.len(),
|
||||
llvm::ChecksumKind::None,
|
||||
hash_kind,
|
||||
hash_value.as_c_char_ptr(),
|
||||
hash_value.len(),
|
||||
ptr::null(),
|
||||
0,
|
||||
source.map_or(ptr::null(), |x| x.as_c_char_ptr()),
|
||||
source.map_or(0, |x| x.len()),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trait MsvcBasicName {
|
||||
|
@ -742,7 +738,7 @@ fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreation
|
|||
cx,
|
||||
float_di_node,
|
||||
"bits",
|
||||
cx.size_and_align_of(bits_ty),
|
||||
cx.layout_of(bits_ty),
|
||||
Size::ZERO,
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, bits_ty),
|
||||
|
@ -788,15 +784,7 @@ fn build_basic_type_di_node<'ll, 'tcx>(
|
|||
_ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"),
|
||||
};
|
||||
|
||||
let ty_di_node = unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
||||
DIB(cx),
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
cx.size_of(t).bits(),
|
||||
encoding,
|
||||
)
|
||||
};
|
||||
let ty_di_node = create_basic_type(cx, name, cx.size_of(t), encoding);
|
||||
|
||||
if !cpp_like_debuginfo {
|
||||
return DINodeCreationResult::new(ty_di_node, false);
|
||||
|
@ -824,6 +812,23 @@ fn build_basic_type_di_node<'ll, 'tcx>(
|
|||
DINodeCreationResult::new(typedef_di_node, false)
|
||||
}
|
||||
|
||||
fn create_basic_type<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
name: &str,
|
||||
size: Size,
|
||||
encoding: u32,
|
||||
) -> &'ll DIBasicType {
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
||||
DIB(cx),
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
size.bits(),
|
||||
encoding,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_foreign_type_di_node<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
t: Ty<'tcx>,
|
||||
|
@ -929,17 +934,13 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
|
|||
};
|
||||
|
||||
unsafe {
|
||||
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
|
||||
let compile_unit_file = create_file(
|
||||
debug_context.builder.as_ref(),
|
||||
name_in_debuginfo.as_c_char_ptr(),
|
||||
name_in_debuginfo.len(),
|
||||
work_dir.as_c_char_ptr(),
|
||||
work_dir.len(),
|
||||
&name_in_debuginfo,
|
||||
&work_dir,
|
||||
"",
|
||||
llvm::ChecksumKind::None,
|
||||
ptr::null(),
|
||||
0,
|
||||
ptr::null(),
|
||||
0,
|
||||
None,
|
||||
);
|
||||
|
||||
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
|
||||
|
@ -971,7 +972,7 @@ fn build_field_di_node<'ll, 'tcx>(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
owner: &'ll DIScope,
|
||||
name: &str,
|
||||
size_and_align: (Size, Align),
|
||||
layout: TyAndLayout<'tcx>,
|
||||
offset: Size,
|
||||
flags: DIFlags,
|
||||
type_di_node: &'ll DIType,
|
||||
|
@ -983,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),
|
||||
|
@ -991,8 +1016,8 @@ fn build_field_di_node<'ll, 'tcx>(
|
|||
name.len(),
|
||||
file_metadata,
|
||||
line_number,
|
||||
size_and_align.0.bits(),
|
||||
size_and_align.1.bits() as u32,
|
||||
layout.size.bits(),
|
||||
layout.align.abi.bits() as u32,
|
||||
offset.bits(),
|
||||
flags,
|
||||
type_di_node,
|
||||
|
@ -1076,7 +1101,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
owner,
|
||||
&field_name[..],
|
||||
(field_layout.size, field_layout.align.abi),
|
||||
field_layout,
|
||||
struct_type_and_layout.fields.offset(i),
|
||||
visibility_di_flags(cx, f.did, adt_def.did()),
|
||||
type_di_node(cx, field_layout.ty),
|
||||
|
@ -1126,7 +1151,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
|||
cx,
|
||||
closure_or_coroutine_di_node,
|
||||
capture_name.as_str(),
|
||||
cx.size_and_align_of(up_var_ty),
|
||||
cx.layout_of(up_var_ty),
|
||||
layout.fields.offset(index),
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, up_var_ty),
|
||||
|
@ -1171,7 +1196,7 @@ fn build_tuple_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
tuple_di_node,
|
||||
&tuple_field_name(index),
|
||||
cx.size_and_align_of(component_type),
|
||||
cx.layout_of(component_type),
|
||||
tuple_type_and_layout.fields.offset(index),
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, component_type),
|
||||
|
@ -1269,7 +1294,7 @@ fn build_union_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
owner,
|
||||
f.name.as_str(),
|
||||
size_and_align_of(field_layout),
|
||||
field_layout,
|
||||
Size::ZERO,
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, field_layout.ty),
|
||||
|
@ -1287,32 +1312,33 @@ fn build_union_type_di_node<'ll, 'tcx>(
|
|||
fn build_generic_type_param_di_nodes<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> SmallVec<&'ll DIType> {
|
||||
) -> SmallVec<Option<&'ll DIType>> {
|
||||
if let ty::Adt(def, args) = *ty.kind() {
|
||||
if args.types().next().is_some() {
|
||||
let generics = cx.tcx.generics_of(def.did());
|
||||
let names = get_parameter_names(cx, generics);
|
||||
let template_params: SmallVec<_> = iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
|
||||
let actual_type_di_node = type_di_node(cx, actual_type);
|
||||
let name = name.as_str();
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||
DIB(cx),
|
||||
None,
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
actual_type_di_node,
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let generics = cx.tcx.generics_of(def.did());
|
||||
return get_template_parameters(cx, generics, args);
|
||||
}
|
||||
|
||||
return template_params;
|
||||
}
|
||||
return smallvec![];
|
||||
}
|
||||
|
||||
pub(super) fn get_template_parameters<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
generics: &ty::Generics,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> SmallVec<Option<&'ll DIType>> {
|
||||
if args.types().next().is_some() {
|
||||
let names = get_parameter_names(cx, generics);
|
||||
let template_params: SmallVec<_> = iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
|
||||
let actual_type_di_node = type_di_node(cx, actual_type);
|
||||
Some(cx.create_template_type_parameter(name.as_str(), actual_type_di_node))
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
return template_params;
|
||||
}
|
||||
|
||||
return smallvec![];
|
||||
|
@ -1416,7 +1442,9 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
|
|||
let void_pointer_ty = Ty::new_imm_ptr(tcx, tcx.types.unit);
|
||||
let void_pointer_type_di_node = type_di_node(cx, void_pointer_ty);
|
||||
let usize_di_node = type_di_node(cx, tcx.types.usize);
|
||||
let (pointer_size, pointer_align) = cx.size_and_align_of(void_pointer_ty);
|
||||
let pointer_layout = cx.layout_of(void_pointer_ty);
|
||||
let pointer_size = pointer_layout.size;
|
||||
let pointer_align = pointer_layout.align.abi;
|
||||
// If `usize` is not pointer-sized and -aligned then the size and alignment computations
|
||||
// for the vtable as a whole would be wrong. Let's make sure this holds even on weird
|
||||
// platforms.
|
||||
|
@ -1472,7 +1500,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
vtable_type_di_node,
|
||||
&field_name,
|
||||
(pointer_size, pointer_align),
|
||||
pointer_layout,
|
||||
field_offset,
|
||||
DIFlags::FlagZero,
|
||||
field_type_di_node,
|
||||
|
|
|
@ -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};
|
||||
|
@ -370,9 +370,9 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
|
|||
cx,
|
||||
enum_type_di_node,
|
||||
&variant_union_field_name(variant_index),
|
||||
// NOTE: We use the size and align of the entire type, not from variant_layout
|
||||
// NOTE: We use the layout of the entire type, not from variant_layout
|
||||
// since the later is sometimes smaller (if it has fewer fields).
|
||||
size_and_align_of(enum_type_and_layout),
|
||||
enum_type_and_layout,
|
||||
Size::ZERO,
|
||||
visibility_flags,
|
||||
variant_struct_type_wrapper_di_node,
|
||||
|
@ -560,7 +560,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
wrapper_struct_type_di_node,
|
||||
"value",
|
||||
size_and_align_of(enum_or_coroutine_type_and_layout),
|
||||
enum_or_coroutine_type_and_layout,
|
||||
Size::ZERO,
|
||||
DIFlags::FlagZero,
|
||||
variant_struct_type_di_node,
|
||||
|
@ -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!(
|
||||
|
@ -874,7 +869,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
|
||||
if is_128_bits {
|
||||
let type_di_node = type_di_node(cx, cx.tcx.types.u64);
|
||||
let size_and_align = cx.size_and_align_of(cx.tcx.types.u64);
|
||||
let u64_layout = cx.layout_of(cx.tcx.types.u64);
|
||||
|
||||
let (lo_offset, hi_offset) = match cx.tcx.data_layout.endian {
|
||||
Endian::Little => (0, 8),
|
||||
|
@ -889,7 +884,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
cx,
|
||||
enum_type_di_node,
|
||||
TAG_FIELD_NAME_128_LO,
|
||||
size_and_align,
|
||||
u64_layout,
|
||||
lo_offset,
|
||||
di_flags,
|
||||
type_di_node,
|
||||
|
@ -900,7 +895,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
cx,
|
||||
enum_type_di_node,
|
||||
TAG_FIELD_NAME_128_HI,
|
||||
size_and_align,
|
||||
u64_layout,
|
||||
hi_offset,
|
||||
DIFlags::FlagZero,
|
||||
type_di_node,
|
||||
|
@ -911,7 +906,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
cx,
|
||||
enum_type_di_node,
|
||||
TAG_FIELD_NAME,
|
||||
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
||||
enum_type_and_layout.field(cx, tag_field),
|
||||
enum_type_and_layout.fields.offset(tag_field),
|
||||
di_flags,
|
||||
tag_base_type_di_node,
|
||||
|
|
|
@ -249,7 +249,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
struct_type_di_node,
|
||||
&field_name,
|
||||
(field_layout.size, field_layout.align.abi),
|
||||
field_layout,
|
||||
variant_layout.fields.offset(field_index),
|
||||
di_flags,
|
||||
type_di_node(cx, field_layout.ty),
|
||||
|
@ -332,7 +332,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
variant_struct_type_di_node,
|
||||
&field_name,
|
||||
cx.size_and_align_of(field_type),
|
||||
cx.layout_of(field_type),
|
||||
variant_layout.fields.offset(field_index),
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, field_type),
|
||||
|
@ -352,7 +352,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
cx,
|
||||
variant_struct_type_di_node,
|
||||
upvar_name.as_str(),
|
||||
cx.size_and_align_of(upvar_ty),
|
||||
cx.layout_of(upvar_ty),
|
||||
coroutine_type_and_layout.fields.offset(index),
|
||||
DIFlags::FlagZero,
|
||||
type_di_node(cx, upvar_ty),
|
||||
|
@ -363,6 +363,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
|
||||
state_specific_fields.into_iter().chain(common_fields).collect()
|
||||
},
|
||||
// FIXME: this is a no-op. `build_generic_type_param_di_nodes` only works for Adts.
|
||||
|cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
|
||||
)
|
||||
.di_node
|
||||
|
|
|
@ -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,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
stub_info: StubInfo<'ll, 'tcx>,
|
||||
members: impl FnOnce(&CodegenCx<'ll, 'tcx>, &'ll DIType) -> SmallVec<&'ll DIType>,
|
||||
generics: impl FnOnce(&CodegenCx<'ll, 'tcx>) -> SmallVec<&'ll DIType>,
|
||||
generics: impl FnOnce(&CodegenCx<'ll, 'tcx>) -> SmallVec<Option<&'ll DIType>>,
|
||||
) -> DINodeCreationResult<'ll> {
|
||||
assert_eq!(debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id), None);
|
||||
|
||||
|
@ -265,8 +265,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
|
|||
|
||||
let members: SmallVec<_> =
|
||||
members(cx, stub_info.metadata).into_iter().map(|node| Some(node)).collect();
|
||||
let generics: SmallVec<Option<&'ll DIType>> =
|
||||
generics(cx).into_iter().map(|node| Some(node)).collect();
|
||||
let generics = generics(cx);
|
||||
|
||||
if !(members.is_empty() && generics.is_empty()) {
|
||||
unsafe {
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
use std::cell::{OnceCell, RefCell};
|
||||
use std::ops::Range;
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
use std::{iter, ptr};
|
||||
|
||||
use libc::c_uint;
|
||||
use metadata::create_subroutine_type;
|
||||
use rustc_abi::Size;
|
||||
use rustc_codegen_ssa::debuginfo::type_names;
|
||||
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
||||
|
@ -34,8 +35,8 @@ use crate::builder::Builder;
|
|||
use crate::common::{AsCCharPtr, CodegenCx};
|
||||
use crate::llvm;
|
||||
use crate::llvm::debuginfo::{
|
||||
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
|
||||
DIVariable,
|
||||
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope,
|
||||
DITemplateTypeParameter, DIType, DIVariable,
|
||||
};
|
||||
use crate::value::Value;
|
||||
|
||||
|
@ -251,7 +252,7 @@ struct DebugLoc {
|
|||
col: u32,
|
||||
}
|
||||
|
||||
impl CodegenCx<'_, '_> {
|
||||
impl<'ll> CodegenCx<'ll, '_> {
|
||||
/// Looks up debug source information about a `BytePos`.
|
||||
// FIXME(eddyb) rename this to better indicate it's a duplicate of
|
||||
// `lookup_char_pos` rather than `dbg_loc`, perhaps by making
|
||||
|
@ -279,6 +280,22 @@ impl CodegenCx<'_, '_> {
|
|||
DebugLoc { file, line, col }
|
||||
}
|
||||
}
|
||||
|
||||
fn create_template_type_parameter(
|
||||
&self,
|
||||
name: &str,
|
||||
actual_type_metadata: &'ll DIType,
|
||||
) -> &'ll DITemplateTypeParameter {
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||
DIB(self),
|
||||
None,
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
actual_type_metadata,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
|
@ -325,10 +342,8 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
let loc = self.lookup_debug_loc(span.lo());
|
||||
let file_metadata = file_metadata(self, &loc.file);
|
||||
|
||||
let function_type_metadata = unsafe {
|
||||
let fn_signature = get_function_signature(self, fn_abi);
|
||||
llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(self), fn_signature)
|
||||
};
|
||||
let function_type_metadata =
|
||||
create_subroutine_type(self, get_function_signature(self, fn_abi));
|
||||
|
||||
let mut name = String::with_capacity(64);
|
||||
type_names::push_item_name(tcx, def_id, false, &mut name);
|
||||
|
@ -471,46 +486,10 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
generics: &ty::Generics,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> &'ll DIArray {
|
||||
if args.types().next().is_none() {
|
||||
return create_DIArray(DIB(cx), &[]);
|
||||
}
|
||||
|
||||
// Again, only create type information if full debuginfo is enabled
|
||||
let template_params: Vec<_> = if cx.sess().opts.debuginfo == DebugInfo::Full {
|
||||
let names = get_parameter_names(cx, generics);
|
||||
iter::zip(args, names)
|
||||
.filter_map(|(kind, name)| {
|
||||
kind.as_type().map(|ty| {
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(cx.typing_env(), ty);
|
||||
let actual_type_metadata = type_di_node(cx, actual_type);
|
||||
let name = name.as_str();
|
||||
unsafe {
|
||||
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||
DIB(cx),
|
||||
None,
|
||||
name.as_c_char_ptr(),
|
||||
name.len(),
|
||||
actual_type_metadata,
|
||||
))
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let template_params = metadata::get_template_parameters(cx, generics, args);
|
||||
create_DIArray(DIB(cx), &template_params)
|
||||
}
|
||||
|
||||
fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
|
||||
let mut names = generics.parent.map_or_else(Vec::new, |def_id| {
|
||||
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||
});
|
||||
names.extend(generics.own_params.iter().map(|param| param.name));
|
||||
names
|
||||
}
|
||||
|
||||
/// Returns a scope, plus `true` if that's a type scope for "class" methods,
|
||||
/// otherwise `false` for plain namespace scopes.
|
||||
fn get_containing_scope<'ll, 'tcx>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue