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::fmt::{self, Write};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::{iter, ptr};
|
use std::{iter, ptr};
|
||||||
|
|
||||||
use libc::{c_char, c_longlong, c_uint};
|
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::debuginfo::utils::{WidePtrKind, wide_pointer_kind};
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
use crate::llvm::debuginfo::{
|
use crate::llvm::debuginfo::{
|
||||||
DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind,
|
DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock,
|
||||||
DebugNameTableKind,
|
DIScope, DIType, DebugEmissionKind, DebugNameTableKind,
|
||||||
};
|
};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
|
@ -68,7 +69,8 @@ pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
||||||
|
|
||||||
const NO_SCOPE_METADATA: Option<&DIScope> = None;
|
const NO_SCOPE_METADATA: Option<&DIScope> = None;
|
||||||
/// A function that returns an empty list of generic parameter debuginfo nodes.
|
/// 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.
|
// SmallVec is used quite a bit in this module, so create a shorthand.
|
||||||
// The actual number of elements is not so important.
|
// The actual number of elements is not so important.
|
||||||
|
@ -243,7 +245,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
owner,
|
owner,
|
||||||
addr_field_name,
|
addr_field_name,
|
||||||
(addr_field.size, addr_field.align.abi),
|
addr_field,
|
||||||
layout.fields.offset(WIDE_PTR_ADDR),
|
layout.fields.offset(WIDE_PTR_ADDR),
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
data_ptr_type_di_node,
|
data_ptr_type_di_node,
|
||||||
|
@ -253,7 +255,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
owner,
|
owner,
|
||||||
extra_field_name,
|
extra_field_name,
|
||||||
(extra_field.size, extra_field.align.abi),
|
extra_field,
|
||||||
layout.fields.offset(WIDE_PTR_EXTRA),
|
layout.fields.offset(WIDE_PTR_EXTRA),
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, extra_field.ty),
|
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);
|
debug_context(cx).type_map.unique_id_to_di_node.borrow_mut().remove(&unique_type_id);
|
||||||
|
|
||||||
let fn_di_node = unsafe {
|
let fn_di_node = create_subroutine_type(cx, create_DIArray(DIB(cx), &signature_di_nodes[..]));
|
||||||
llvm::LLVMRustDIBuilderCreateSubroutineType(
|
|
||||||
DIB(cx),
|
|
||||||
create_DIArray(DIB(cx), &signature_di_nodes[..]),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is actually a function pointer, so wrap it in pointer DI.
|
// This is actually a function pointer, so wrap it in pointer DI.
|
||||||
let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false);
|
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)
|
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
|
/// 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").
|
/// we with the correct type name (e.g. "dyn SomeTrait<Foo, Item=u32> + Sync").
|
||||||
fn build_dyn_type_di_node<'ll, 'tcx>(
|
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.
|
// 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 {
|
fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll DIType {
|
||||||
*debug_context(cx).recursion_marker_type.get_or_init(move || {
|
*debug_context(cx).recursion_marker_type.get_or_init(move || {
|
||||||
unsafe {
|
// The choice of type here is pretty arbitrary -
|
||||||
// The choice of type here is pretty arbitrary -
|
// anything reading the debuginfo for a recursive
|
||||||
// anything reading the debuginfo for a recursive
|
// type is going to see *something* weird - the only
|
||||||
// type is going to see *something* weird - the only
|
// question is what exactly it will see.
|
||||||
// question is what exactly it will see.
|
//
|
||||||
//
|
// FIXME: the name `<recur_type>` does not fit the naming scheme
|
||||||
// FIXME: the name `<recur_type>` does not fit the naming scheme
|
// of other types.
|
||||||
// of other types.
|
//
|
||||||
//
|
// FIXME: it might make sense to use an actual pointer type here
|
||||||
// FIXME: it might make sense to use an actual pointer type here
|
// so that debuggers can show the address.
|
||||||
// so that debuggers can show the address.
|
create_basic_type(
|
||||||
let name = "<recur_type>";
|
cx,
|
||||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
"<recur_type>",
|
||||||
DIB(cx),
|
cx.tcx.data_layout.pointer_size,
|
||||||
name.as_c_char_ptr(),
|
dwarf_const::DW_ATE_unsigned,
|
||||||
name.len(),
|
)
|
||||||
cx.tcx.data_layout.pointer_size.bits(),
|
|
||||||
dwarf_const::DW_ATE_unsigned,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,42 +620,38 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi
|
||||||
let source =
|
let source =
|
||||||
cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref());
|
cx.sess().opts.unstable_opts.embed_source.then_some(()).and(source_file.src.as_ref());
|
||||||
|
|
||||||
unsafe {
|
create_file(DIB(cx), &file_name, &directory, &hash_value, hash_kind, source)
|
||||||
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()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
|
||||||
debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe {
|
debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| {
|
||||||
let file_name = "<unknown>";
|
create_file(DIB(cx), "<unknown>", "", "", llvm::ChecksumKind::None, None)
|
||||||
let directory = "";
|
})
|
||||||
let hash_value = "";
|
}
|
||||||
|
|
||||||
|
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(
|
llvm::LLVMRustDIBuilderCreateFile(
|
||||||
DIB(cx),
|
builder,
|
||||||
file_name.as_c_char_ptr(),
|
file_name.as_c_char_ptr(),
|
||||||
file_name.len(),
|
file_name.len(),
|
||||||
directory.as_c_char_ptr(),
|
directory.as_c_char_ptr(),
|
||||||
directory.len(),
|
directory.len(),
|
||||||
llvm::ChecksumKind::None,
|
hash_kind,
|
||||||
hash_value.as_c_char_ptr(),
|
hash_value.as_c_char_ptr(),
|
||||||
hash_value.len(),
|
hash_value.len(),
|
||||||
ptr::null(),
|
source.map_or(ptr::null(), |x| x.as_c_char_ptr()),
|
||||||
0,
|
source.map_or(0, |x| x.len()),
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MsvcBasicName {
|
trait MsvcBasicName {
|
||||||
|
@ -742,7 +738,7 @@ fn build_cpp_f16_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> DINodeCreation
|
||||||
cx,
|
cx,
|
||||||
float_di_node,
|
float_di_node,
|
||||||
"bits",
|
"bits",
|
||||||
cx.size_and_align_of(bits_ty),
|
cx.layout_of(bits_ty),
|
||||||
Size::ZERO,
|
Size::ZERO,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, bits_ty),
|
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"),
|
_ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty_di_node = unsafe {
|
let ty_di_node = create_basic_type(cx, name, cx.size_of(t), encoding);
|
||||||
llvm::LLVMRustDIBuilderCreateBasicType(
|
|
||||||
DIB(cx),
|
|
||||||
name.as_c_char_ptr(),
|
|
||||||
name.len(),
|
|
||||||
cx.size_of(t).bits(),
|
|
||||||
encoding,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if !cpp_like_debuginfo {
|
if !cpp_like_debuginfo {
|
||||||
return DINodeCreationResult::new(ty_di_node, false);
|
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)
|
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>(
|
fn build_foreign_type_di_node<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
|
@ -929,17 +934,13 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
|
let compile_unit_file = create_file(
|
||||||
debug_context.builder.as_ref(),
|
debug_context.builder.as_ref(),
|
||||||
name_in_debuginfo.as_c_char_ptr(),
|
&name_in_debuginfo,
|
||||||
name_in_debuginfo.len(),
|
&work_dir,
|
||||||
work_dir.as_c_char_ptr(),
|
"",
|
||||||
work_dir.len(),
|
|
||||||
llvm::ChecksumKind::None,
|
llvm::ChecksumKind::None,
|
||||||
ptr::null(),
|
None,
|
||||||
0,
|
|
||||||
ptr::null(),
|
|
||||||
0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
|
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
|
||||||
|
@ -971,7 +972,7 @@ fn build_field_di_node<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
owner: &'ll DIScope,
|
owner: &'ll DIScope,
|
||||||
name: &str,
|
name: &str,
|
||||||
size_and_align: (Size, Align),
|
layout: TyAndLayout<'tcx>,
|
||||||
offset: Size,
|
offset: Size,
|
||||||
flags: DIFlags,
|
flags: DIFlags,
|
||||||
type_di_node: &'ll DIType,
|
type_di_node: &'ll DIType,
|
||||||
|
@ -983,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),
|
||||||
|
@ -991,8 +1016,8 @@ fn build_field_di_node<'ll, 'tcx>(
|
||||||
name.len(),
|
name.len(),
|
||||||
file_metadata,
|
file_metadata,
|
||||||
line_number,
|
line_number,
|
||||||
size_and_align.0.bits(),
|
layout.size.bits(),
|
||||||
size_and_align.1.bits() as u32,
|
layout.align.abi.bits() as u32,
|
||||||
offset.bits(),
|
offset.bits(),
|
||||||
flags,
|
flags,
|
||||||
type_di_node,
|
type_di_node,
|
||||||
|
@ -1076,7 +1101,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
owner,
|
owner,
|
||||||
&field_name[..],
|
&field_name[..],
|
||||||
(field_layout.size, field_layout.align.abi),
|
field_layout,
|
||||||
struct_type_and_layout.fields.offset(i),
|
struct_type_and_layout.fields.offset(i),
|
||||||
visibility_di_flags(cx, f.did, adt_def.did()),
|
visibility_di_flags(cx, f.did, adt_def.did()),
|
||||||
type_di_node(cx, field_layout.ty),
|
type_di_node(cx, field_layout.ty),
|
||||||
|
@ -1126,7 +1151,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
closure_or_coroutine_di_node,
|
closure_or_coroutine_di_node,
|
||||||
capture_name.as_str(),
|
capture_name.as_str(),
|
||||||
cx.size_and_align_of(up_var_ty),
|
cx.layout_of(up_var_ty),
|
||||||
layout.fields.offset(index),
|
layout.fields.offset(index),
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, up_var_ty),
|
type_di_node(cx, up_var_ty),
|
||||||
|
@ -1171,7 +1196,7 @@ fn build_tuple_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
tuple_di_node,
|
tuple_di_node,
|
||||||
&tuple_field_name(index),
|
&tuple_field_name(index),
|
||||||
cx.size_and_align_of(component_type),
|
cx.layout_of(component_type),
|
||||||
tuple_type_and_layout.fields.offset(index),
|
tuple_type_and_layout.fields.offset(index),
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, component_type),
|
type_di_node(cx, component_type),
|
||||||
|
@ -1269,7 +1294,7 @@ fn build_union_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
owner,
|
owner,
|
||||||
f.name.as_str(),
|
f.name.as_str(),
|
||||||
size_and_align_of(field_layout),
|
field_layout,
|
||||||
Size::ZERO,
|
Size::ZERO,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, field_layout.ty),
|
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>(
|
fn build_generic_type_param_di_nodes<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> SmallVec<&'ll DIType> {
|
) -> SmallVec<Option<&'ll DIType>> {
|
||||||
if let ty::Adt(def, args) = *ty.kind() {
|
if let ty::Adt(def, args) = *ty.kind() {
|
||||||
if args.types().next().is_some() {
|
let generics = cx.tcx.generics_of(def.did());
|
||||||
let generics = cx.tcx.generics_of(def.did());
|
return get_template_parameters(cx, generics, args);
|
||||||
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();
|
|
||||||
|
|
||||||
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![];
|
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_ty = Ty::new_imm_ptr(tcx, tcx.types.unit);
|
||||||
let void_pointer_type_di_node = type_di_node(cx, void_pointer_ty);
|
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 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
|
// 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
|
// for the vtable as a whole would be wrong. Let's make sure this holds even on weird
|
||||||
// platforms.
|
// platforms.
|
||||||
|
@ -1472,7 +1500,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
vtable_type_di_node,
|
vtable_type_di_node,
|
||||||
&field_name,
|
&field_name,
|
||||||
(pointer_size, pointer_align),
|
pointer_layout,
|
||||||
field_offset,
|
field_offset,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
field_type_di_node,
|
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::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};
|
||||||
|
@ -370,9 +370,9 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
enum_type_di_node,
|
enum_type_di_node,
|
||||||
&variant_union_field_name(variant_index),
|
&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).
|
// 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,
|
Size::ZERO,
|
||||||
visibility_flags,
|
visibility_flags,
|
||||||
variant_struct_type_wrapper_di_node,
|
variant_struct_type_wrapper_di_node,
|
||||||
|
@ -560,7 +560,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
wrapper_struct_type_di_node,
|
wrapper_struct_type_di_node,
|
||||||
"value",
|
"value",
|
||||||
size_and_align_of(enum_or_coroutine_type_and_layout),
|
enum_or_coroutine_type_and_layout,
|
||||||
Size::ZERO,
|
Size::ZERO,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
variant_struct_type_di_node,
|
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));
|
.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!(
|
||||||
|
@ -874,7 +869,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
||||||
|
|
||||||
if is_128_bits {
|
if is_128_bits {
|
||||||
let type_di_node = type_di_node(cx, cx.tcx.types.u64);
|
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 {
|
let (lo_offset, hi_offset) = match cx.tcx.data_layout.endian {
|
||||||
Endian::Little => (0, 8),
|
Endian::Little => (0, 8),
|
||||||
|
@ -889,7 +884,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
enum_type_di_node,
|
enum_type_di_node,
|
||||||
TAG_FIELD_NAME_128_LO,
|
TAG_FIELD_NAME_128_LO,
|
||||||
size_and_align,
|
u64_layout,
|
||||||
lo_offset,
|
lo_offset,
|
||||||
di_flags,
|
di_flags,
|
||||||
type_di_node,
|
type_di_node,
|
||||||
|
@ -900,7 +895,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
enum_type_di_node,
|
enum_type_di_node,
|
||||||
TAG_FIELD_NAME_128_HI,
|
TAG_FIELD_NAME_128_HI,
|
||||||
size_and_align,
|
u64_layout,
|
||||||
hi_offset,
|
hi_offset,
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node,
|
type_di_node,
|
||||||
|
@ -911,7 +906,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
enum_type_di_node,
|
enum_type_di_node,
|
||||||
TAG_FIELD_NAME,
|
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),
|
enum_type_and_layout.fields.offset(tag_field),
|
||||||
di_flags,
|
di_flags,
|
||||||
tag_base_type_di_node,
|
tag_base_type_di_node,
|
||||||
|
|
|
@ -249,7 +249,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
struct_type_di_node,
|
struct_type_di_node,
|
||||||
&field_name,
|
&field_name,
|
||||||
(field_layout.size, field_layout.align.abi),
|
field_layout,
|
||||||
variant_layout.fields.offset(field_index),
|
variant_layout.fields.offset(field_index),
|
||||||
di_flags,
|
di_flags,
|
||||||
type_di_node(cx, field_layout.ty),
|
type_di_node(cx, field_layout.ty),
|
||||||
|
@ -332,7 +332,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
variant_struct_type_di_node,
|
variant_struct_type_di_node,
|
||||||
&field_name,
|
&field_name,
|
||||||
cx.size_and_align_of(field_type),
|
cx.layout_of(field_type),
|
||||||
variant_layout.fields.offset(field_index),
|
variant_layout.fields.offset(field_index),
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, field_type),
|
type_di_node(cx, field_type),
|
||||||
|
@ -352,7 +352,7 @@ fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
|
||||||
cx,
|
cx,
|
||||||
variant_struct_type_di_node,
|
variant_struct_type_di_node,
|
||||||
upvar_name.as_str(),
|
upvar_name.as_str(),
|
||||||
cx.size_and_align_of(upvar_ty),
|
cx.layout_of(upvar_ty),
|
||||||
coroutine_type_and_layout.fields.offset(index),
|
coroutine_type_and_layout.fields.offset(index),
|
||||||
DIFlags::FlagZero,
|
DIFlags::FlagZero,
|
||||||
type_di_node(cx, upvar_ty),
|
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()
|
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),
|
|cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
|
||||||
)
|
)
|
||||||
.di_node
|
.di_node
|
||||||
|
|
|
@ -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),
|
))
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
stub_info: StubInfo<'ll, 'tcx>,
|
stub_info: StubInfo<'ll, 'tcx>,
|
||||||
members: impl FnOnce(&CodegenCx<'ll, 'tcx>, &'ll DIType) -> SmallVec<&'ll DIType>,
|
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> {
|
) -> DINodeCreationResult<'ll> {
|
||||||
assert_eq!(debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id), None);
|
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<_> =
|
let members: SmallVec<_> =
|
||||||
members(cx, stub_info.metadata).into_iter().map(|node| Some(node)).collect();
|
members(cx, stub_info.metadata).into_iter().map(|node| Some(node)).collect();
|
||||||
let generics: SmallVec<Option<&'ll DIType>> =
|
let generics = generics(cx);
|
||||||
generics(cx).into_iter().map(|node| Some(node)).collect();
|
|
||||||
|
|
||||||
if !(members.is_empty() && generics.is_empty()) {
|
if !(members.is_empty() && generics.is_empty()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
use std::cell::{OnceCell, RefCell};
|
use std::cell::{OnceCell, RefCell};
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use std::ptr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{iter, ptr};
|
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
use metadata::create_subroutine_type;
|
||||||
use rustc_abi::Size;
|
use rustc_abi::Size;
|
||||||
use rustc_codegen_ssa::debuginfo::type_names;
|
use rustc_codegen_ssa::debuginfo::type_names;
|
||||||
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
use rustc_codegen_ssa::mir::debuginfo::VariableKind::*;
|
||||||
|
@ -34,8 +35,8 @@ use crate::builder::Builder;
|
||||||
use crate::common::{AsCCharPtr, CodegenCx};
|
use crate::common::{AsCCharPtr, CodegenCx};
|
||||||
use crate::llvm;
|
use crate::llvm;
|
||||||
use crate::llvm::debuginfo::{
|
use crate::llvm::debuginfo::{
|
||||||
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
|
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope,
|
||||||
DIVariable,
|
DITemplateTypeParameter, DIType, DIVariable,
|
||||||
};
|
};
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
|
@ -251,7 +252,7 @@ struct DebugLoc {
|
||||||
col: u32,
|
col: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodegenCx<'_, '_> {
|
impl<'ll> CodegenCx<'ll, '_> {
|
||||||
/// Looks up debug source information about a `BytePos`.
|
/// Looks up debug source information about a `BytePos`.
|
||||||
// FIXME(eddyb) rename this to better indicate it's a duplicate of
|
// FIXME(eddyb) rename this to better indicate it's a duplicate of
|
||||||
// `lookup_char_pos` rather than `dbg_loc`, perhaps by making
|
// `lookup_char_pos` rather than `dbg_loc`, perhaps by making
|
||||||
|
@ -279,6 +280,22 @@ impl CodegenCx<'_, '_> {
|
||||||
DebugLoc { file, line, col }
|
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> {
|
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 loc = self.lookup_debug_loc(span.lo());
|
||||||
let file_metadata = file_metadata(self, &loc.file);
|
let file_metadata = file_metadata(self, &loc.file);
|
||||||
|
|
||||||
let function_type_metadata = unsafe {
|
let function_type_metadata =
|
||||||
let fn_signature = get_function_signature(self, fn_abi);
|
create_subroutine_type(self, get_function_signature(self, fn_abi));
|
||||||
llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(self), fn_signature)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut name = String::with_capacity(64);
|
let mut name = String::with_capacity(64);
|
||||||
type_names::push_item_name(tcx, def_id, false, &mut name);
|
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,
|
generics: &ty::Generics,
|
||||||
args: GenericArgsRef<'tcx>,
|
args: GenericArgsRef<'tcx>,
|
||||||
) -> &'ll DIArray {
|
) -> &'ll DIArray {
|
||||||
if args.types().next().is_none() {
|
let template_params = metadata::get_template_parameters(cx, generics, args);
|
||||||
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![]
|
|
||||||
};
|
|
||||||
|
|
||||||
create_DIArray(DIB(cx), &template_params)
|
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,
|
/// Returns a scope, plus `true` if that's a type scope for "class" methods,
|
||||||
/// otherwise `false` for plain namespace scopes.
|
/// otherwise `false` for plain namespace scopes.
|
||||||
fn get_containing_scope<'ll, 'tcx>(
|
fn get_containing_scope<'ll, 'tcx>(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue