diff options
Diffstat (limited to 'compiler/rustc_codegen_llvm/src')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs | 162 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/lib.rs | 7 |
4 files changed, 74 insertions, 143 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 1e70664e64d..7e136c1b24c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -1,4 +1,3 @@ -use self::EnumTagInfo::*; use self::MemberDescriptionFactory::*; use self::RecursiveTypeDescription::*; @@ -28,7 +27,7 @@ use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ich::NodeIdHashingMode; -use rustc_middle::mir::{self, Field, GeneratorLayout}; +use rustc_middle::mir::{self, GeneratorLayout}; use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::Instance; @@ -471,21 +470,28 @@ fn trait_pointer_metadata( // type is assigned the correct name, size, namespace, and source location. // However, it does not describe the trait's methods. - let containing_scope = match trait_type.kind() { - ty::Dynamic(ref data, ..) => { - data.principal_def_id().map(|did| get_namespace_for_item(cx, did)) - } - _ => { - bug!( - "debuginfo: unexpected trait-object type in \ - trait_pointer_metadata(): {:?}", - trait_type - ); - } - }; + let (containing_scope, trait_type_name) = match trait_object_type { + Some(trait_object_type) => match trait_object_type.kind() { + ty::Adt(def, _) => ( + Some(get_namespace_for_item(cx, def.did)), + compute_debuginfo_type_name(cx.tcx, trait_object_type, false), + ), + ty::RawPtr(_) | ty::Ref(..) => { + (NO_SCOPE_METADATA, compute_debuginfo_type_name(cx.tcx, trait_object_type, true)) + } + _ => { + bug!( + "debuginfo: unexpected trait-object type in \ + trait_pointer_metadata(): {:?}", + trait_object_type + ); + } + }, - let trait_object_type = trait_object_type.unwrap_or(trait_type); - let trait_type_name = compute_debuginfo_type_name(cx.tcx, trait_object_type, false); + // No object type, use the trait type directly (no scope here since the type + // will be wrapped in the dyn$ synthetic type). + None => (NO_SCOPE_METADATA, compute_debuginfo_type_name(cx.tcx, trait_type, true)), + }; let file_metadata = unknown_file_metadata(cx); @@ -525,7 +531,7 @@ fn trait_pointer_metadata( composite_type_metadata( cx, - trait_object_type, + trait_object_type.unwrap_or(trait_type), &trait_type_name[..], unique_type_id, member_descriptions, @@ -1181,7 +1187,7 @@ enum MemberDescriptionFactory<'ll, 'tcx> { TupleMDF(TupleMemberDescriptionFactory<'tcx>), EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>), UnionMDF(UnionMemberDescriptionFactory<'tcx>), - VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>), + VariantMDF(VariantMemberDescriptionFactory<'tcx>), } impl MemberDescriptionFactory<'ll, 'tcx> { @@ -1498,14 +1504,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { } let variant_info = variant_info_for(index); - let (variant_type_metadata, member_description_factory) = describe_enum_variant( - cx, - self.layout, - variant_info, - None, - self_metadata, - self.span, - ); + let (variant_type_metadata, member_description_factory) = + describe_enum_variant(cx, self.layout, variant_info, self_metadata, self.span); let member_descriptions = member_description_factory.create_member_descriptions(cx); @@ -1517,7 +1517,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { Some(&self.common_members), ); vec![MemberDescription { - name: if fallback { String::new() } else { variant_info.variant_name() }, + name: variant_info.variant_name(), type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, @@ -1533,28 +1533,38 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { ref variants, .. } => { - let tag_info = if fallback { - // For MSVC, we generate a union of structs for each variant with an explicit - // discriminant field roughly equivalent to the following C: + let fallback_discr_variant = if fallback { + // For MSVC, we generate a union of structs for each variant and an + // explicit discriminant field roughly equivalent to the following C: // ```c // union enum$<{name}> { // struct {variant 0 name} { - // tag$ variant$; // <variant 0 fields> // } variant0; // <other variant structs> + // {name} discriminant; // } // ``` - // The natvis in `intrinsic.nativs` then matches on `this.variant0.variant$` to + // The natvis in `intrinsic.natvis` then matches on `this.discriminant` to // determine which variant is active and then displays it. - Some(DirectTag { - tag_field: Field::from(tag_field), - tag_type_metadata: self.tag_type_metadata.unwrap(), + let enum_layout = self.layout; + let offset = enum_layout.fields.offset(tag_field); + let discr_ty = enum_layout.field(cx, tag_field).ty; + let (size, align) = cx.size_and_align_of(discr_ty); + Some(MemberDescription { + name: "discriminant".into(), + type_metadata: self.tag_type_metadata.unwrap(), + offset, + size, + align, + flags: DIFlags::FlagZero, + discriminant: None, + source_info: None, }) } else { - // This doesn't matter in this case. None }; + variants .iter_enumerated() .map(|(i, _)| { @@ -1564,7 +1574,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info, - tag_info, self_metadata, self.span, ); @@ -1598,6 +1607,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { source_info: variant_info.source_info(cx), } }) + .chain(fallback_discr_variant.into_iter()) .collect() } Variants::Multiple { @@ -1695,7 +1705,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, dataful_variant_layout, variant_info, - Some(NicheTag), self_metadata, self.span, ); @@ -1747,7 +1756,6 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { cx, variant, variant_info, - Some(NicheTag), self_metadata, self.span, ); @@ -1784,39 +1792,27 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { } // Creates `MemberDescription`s for the fields of a single enum variant. -struct VariantMemberDescriptionFactory<'ll, 'tcx> { +struct VariantMemberDescriptionFactory<'tcx> { /// Cloned from the `layout::Struct` describing the variant. offsets: Vec<Size>, args: Vec<(String, Ty<'tcx>)>, - tag_type_metadata: Option<&'ll DIType>, span: Span, } -impl VariantMemberDescriptionFactory<'ll, 'tcx> { +impl VariantMemberDescriptionFactory<'tcx> { fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> { self.args .iter() .enumerate() .map(|(i, &(ref name, ty))| { - // Discriminant is always the first field of our variant - // when using the enum fallback. - let is_artificial_discr = use_enum_fallback(cx) && i == 0; let (size, align) = cx.size_and_align_of(ty); MemberDescription { name: name.to_string(), - type_metadata: if is_artificial_discr { - self.tag_type_metadata.unwrap_or_else(|| type_metadata(cx, ty, self.span)) - } else { - type_metadata(cx, ty, self.span) - }, + type_metadata: type_metadata(cx, ty, self.span), offset: self.offsets[i], size, align, - flags: if is_artificial_discr { - DIFlags::FlagArtificial - } else { - DIFlags::FlagZero - }, + flags: DIFlags::FlagZero, discriminant: None, source_info: None, } @@ -1826,12 +1822,6 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> { } #[derive(Copy, Clone)] -enum EnumTagInfo<'ll> { - DirectTag { tag_field: Field, tag_type_metadata: &'ll DIType }, - NicheTag, -} - -#[derive(Copy, Clone)] enum VariantInfo<'a, 'tcx> { Adt(&'tcx ty::VariantDef), Generator { @@ -1909,7 +1899,6 @@ fn describe_enum_variant( cx: &CodegenCx<'ll, 'tcx>, layout: layout::TyAndLayout<'tcx>, variant: VariantInfo<'_, 'tcx>, - discriminant_info: Option<EnumTagInfo<'ll>>, containing_scope: &'ll DIScope, span: Span, ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) { @@ -1928,50 +1917,13 @@ fn describe_enum_variant( ) }); - // Build an array of (field name, field type) pairs to be captured in the factory closure. - let (offsets, args) = if use_enum_fallback(cx) { - // If this is not a univariant enum, there is also the discriminant field. - let (discr_offset, discr_arg) = match discriminant_info { - Some(DirectTag { tag_field, .. }) => { - // We have the layout of an enum variant, we need the layout of the outer enum - let enum_layout = cx.layout_of(layout.ty); - let offset = enum_layout.fields.offset(tag_field.as_usize()); - let args = ("variant$".to_owned(), enum_layout.field(cx, tag_field.as_usize()).ty); - (Some(offset), Some(args)) - } - _ => (None, None), - }; - ( - discr_offset - .into_iter() - .chain((0..layout.fields.count()).map(|i| layout.fields.offset(i))) - .collect(), - discr_arg - .into_iter() - .chain( - (0..layout.fields.count()) - .map(|i| (variant.field_name(i), layout.field(cx, i).ty)), - ) - .collect(), - ) - } else { - ( - (0..layout.fields.count()).map(|i| layout.fields.offset(i)).collect(), - (0..layout.fields.count()) - .map(|i| (variant.field_name(i), layout.field(cx, i).ty)) - .collect(), - ) - }; + let offsets = (0..layout.fields.count()).map(|i| layout.fields.offset(i)).collect(); + let args = (0..layout.fields.count()) + .map(|i| (variant.field_name(i), layout.field(cx, i).ty)) + .collect(); - let member_description_factory = VariantMDF(VariantMemberDescriptionFactory { - offsets, - args, - tag_type_metadata: match discriminant_info { - Some(DirectTag { tag_type_metadata, .. }) => Some(tag_type_metadata), - _ => None, - }, - span, - }); + let member_description_factory = + VariantMDF(VariantMemberDescriptionFactory { offsets, args, span }); (metadata_stub, member_description_factory) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 2b99a2ebad9..8375d4c7ca5 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -5,7 +5,6 @@ use rustc_codegen_ssa::mir::debuginfo::VariableKind::*; use self::metadata::{file_metadata, type_metadata, TypeMap}; use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER}; use self::namespace::mangled_name_of_instance; -use self::type_names::compute_debuginfo_type_name; use self::utils::{create_DIArray, is_node_local_to_unit, DIB}; use crate::abi::FnAbi; @@ -311,10 +310,10 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(self), fn_signature) }; - // Find the enclosing function, in case this is a closure. - let def_key = self.tcx().def_key(def_id); - let mut name = def_key.disambiguated_data.data.to_string(); + let mut name = String::new(); + type_names::push_item_name(self.tcx(), def_id, false, &mut name); + // Find the enclosing function, in case this is a closure. let enclosing_fn_def_id = self.tcx().closure_base_def_id(def_id); // Get_template_parameters() will append a `<...>` clause to the function @@ -428,24 +427,16 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { substs: SubstsRef<'tcx>, name_to_append_suffix_to: &mut String, ) -> &'ll DIArray { + type_names::push_generic_params( + cx.tcx, + cx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs), + name_to_append_suffix_to, + ); + if substs.types().next().is_none() { return create_DIArray(DIB(cx), &[]); } - name_to_append_suffix_to.push('<'); - for (i, actual_type) in substs.types().enumerate() { - if i != 0 { - name_to_append_suffix_to.push(','); - } - - let actual_type = - cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), actual_type); - // Add actual type name to <...> clause of function name - let actual_type_name = compute_debuginfo_type_name(cx.tcx(), actual_type, true); - name_to_append_suffix_to.push_str(&actual_type_name[..]); - } - name_to_append_suffix_to.push('>'); - // 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); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs index 9945d4f4282..1cbf5386996 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs @@ -1,13 +1,13 @@ // Namespace Handling. use super::utils::{debug_context, DIB}; +use rustc_codegen_ssa::debuginfo::type_names; use rustc_middle::ty::{self, Instance}; use crate::common::CodegenCx; use crate::llvm; use crate::llvm::debuginfo::DIScope; use rustc_hir::def_id::DefId; -use rustc_hir::definitions::DefPathData; pub fn mangled_name_of_instance<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, @@ -27,25 +27,18 @@ pub fn item_namespace(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { .parent .map(|parent| item_namespace(cx, DefId { krate: def_id.krate, index: parent })); - let crate_name_as_str; - let name_to_string; - let namespace_name = match def_key.disambiguated_data.data { - DefPathData::CrateRoot => { - crate_name_as_str = cx.tcx.crate_name(def_id.krate).as_str(); - &*crate_name_as_str - } - data => { - name_to_string = data.to_string(); - &*name_to_string - } + let namespace_name_string = { + let mut output = String::new(); + type_names::push_item_name(cx.tcx, def_id, false, &mut output); + output }; let scope = unsafe { llvm::LLVMRustDIBuilderCreateNameSpace( DIB(cx), parent_scope, - namespace_name.as_ptr().cast(), - namespace_name.len(), + namespace_name_string.as_ptr().cast(), + namespace_name_string.len(), false, // ExportSymbols (only relevant for C++ anonymous namespaces) ) }; diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index fc890f23853..26fd1cfbcd0 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -292,12 +292,7 @@ impl CodegenBackend for LlvmCodegenBackend { // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. - link_binary::<LlvmArchiveBuilder<'_>>( - sess, - &codegen_results, - outputs, - &codegen_results.crate_info.local_crate_name.as_str(), - ); + link_binary::<LlvmArchiveBuilder<'_>>(sess, &codegen_results, outputs); Ok(()) } |
