diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-03-31 19:19:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-31 19:19:50 +0200 |
| commit | 0171fe55986abd7e9ac33839db1676fd3ed6c03a (patch) | |
| tree | 55e75e3988fd19867ef0b73c980add642145605b /src/librustc_codegen_llvm/debuginfo | |
| parent | 245a0afb52d18e906c1f042165559c57261e754a (diff) | |
| parent | 5b7f4e9e2106f5e83fc650e8185d59a57e27ad09 (diff) | |
| download | rust-0171fe55986abd7e9ac33839db1676fd3ed6c03a.tar.gz rust-0171fe55986abd7e9ac33839db1676fd3ed6c03a.zip | |
Rollup merge of #59519 - eddyb:layout-variants-refactor, r=oli-obk
rustc_target: factor out common fields of non-Single Variants. @tmandry and I were discussing ways to generalize the current variants/discriminant layout to allow more fields in the "`enum`" (or another multi-variant types, such as potentially generator state, in the future), shared by all variants, than just the tag/niche discriminant. This refactor should make it easier to extend multi-variant layouts, as nothing is duplicating anymore between "tagged enums" and "niche-filling enums". r? @oli-obk
Diffstat (limited to 'src/librustc_codegen_llvm/debuginfo')
| -rw-r--r-- | src/librustc_codegen_llvm/debuginfo/metadata.rs | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index e50839cd598..e549b120da9 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1246,7 +1246,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { } ] } - layout::Variants::Tagged { ref variants, .. } => { + layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Tag, + ref variants, + .. + } => { let discriminant_info = if fallback { RegularDiscriminant(self.discriminant_type_metadata .expect("")) @@ -1288,12 +1292,14 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { } }).collect() } - layout::Variants::NicheFilling { - ref niche_variants, - niche_start, + layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Niche { + ref niche_variants, + niche_start, + dataful_variant, + }, + ref discr, ref variants, - dataful_variant, - ref niche, } => { if fallback { let variant = self.layout.for_variant(cx, dataful_variant); @@ -1380,7 +1386,11 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { let value = (i.as_u32() as u128) .wrapping_sub(niche_variants.start().as_u32() as u128) .wrapping_add(niche_start); - let value = truncate(value, niche.value.size(cx)); + let value = truncate(value, discr.value.size(cx)); + // NOTE(eddyb) do *NOT* remove this assert, until + // we pass the full 128-bit value to LLVM, otherwise + // truncation will be silent and remain undetected. + assert_eq!(value as u64 as u128, value); Some(value as u64) }; @@ -1597,8 +1607,11 @@ fn prepare_enum_metadata( let layout = cx.layout_of(enum_type); match (&layout.abi, &layout.variants) { - (&layout::Abi::Scalar(_), &layout::Variants::Tagged {ref tag, .. }) => - return FinalMetadata(discriminant_type_metadata(tag.value)), + (&layout::Abi::Scalar(_), &layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Tag, + ref discr, + .. + }) => return FinalMetadata(discriminant_type_metadata(discr.value)), _ => {} } @@ -1610,9 +1623,16 @@ fn prepare_enum_metadata( if use_enum_fallback(cx) { let discriminant_type_metadata = match layout.variants { layout::Variants::Single { .. } | - layout::Variants::NicheFilling { .. } => None, - layout::Variants::Tagged { ref tag, .. } => { - Some(discriminant_type_metadata(tag.value)) + layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Niche { .. }, + .. + } => None, + layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Tag, + ref discr, + .. + } => { + Some(discriminant_type_metadata(discr.value)) } }; @@ -1647,16 +1667,20 @@ fn prepare_enum_metadata( ); } - let discriminator_metadata = match &layout.variants { + let discriminator_metadata = match layout.variants { // A single-variant enum has no discriminant. - &layout::Variants::Single { .. } => None, + layout::Variants::Single { .. } => None, - &layout::Variants::NicheFilling { ref niche, .. } => { + layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Niche { .. }, + ref discr, + .. + } => { // Find the integer type of the correct size. - let size = niche.value.size(cx); - let align = niche.value.align(cx); + let size = discr.value.size(cx); + let align = discr.value.align(cx); - let discr_type = match niche.value { + let discr_type = match discr.value { layout::Int(t, _) => t, layout::Float(layout::FloatTy::F32) => Integer::I32, layout::Float(layout::FloatTy::F64) => Integer::I64, @@ -1679,8 +1703,12 @@ fn prepare_enum_metadata( } }, - &layout::Variants::Tagged { ref tag, .. } => { - let discr_type = tag.value.to_ty(cx.tcx); + layout::Variants::Multiple { + discr_kind: layout::DiscriminantKind::Tag, + ref discr, + .. + } => { + let discr_type = discr.value.to_ty(cx.tcx); let (size, align) = cx.size_and_align_of(discr_type); let discr_metadata = basic_type_metadata(cx, discr_type); |
