rustc: use Primitive instead of Integer for CEnum and General discriminants.
This commit is contained in:
parent
335bd8ea1b
commit
61c2bd9ca4
8 changed files with 57 additions and 63 deletions
|
@ -843,7 +843,7 @@ impl<'a, 'tcx> Struct {
|
|||
}
|
||||
(&CEnum { discr, .. }, &ty::TyAdt(def, _)) => {
|
||||
if def.discriminants(tcx).all(|d| d.to_u128_unchecked() != 0) {
|
||||
Ok(Some((Size::from_bytes(0), Int(discr))))
|
||||
Ok(Some((Size::from_bytes(0), discr)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
@ -1097,7 +1097,7 @@ pub enum Layout {
|
|||
|
||||
/// C-like enums; basically an integer.
|
||||
CEnum {
|
||||
discr: Integer,
|
||||
discr: Primitive,
|
||||
signed: bool,
|
||||
/// Inclusive discriminant range.
|
||||
/// If min > max, it represents min...u64::MAX followed by 0...max.
|
||||
|
@ -1118,7 +1118,7 @@ pub enum Layout {
|
|||
/// all space reserved for the discriminant, and their first field starts
|
||||
/// at a non-0 offset, after where the discriminant would go.
|
||||
General {
|
||||
discr: Integer,
|
||||
discr: Primitive,
|
||||
variants: Vec<Struct>,
|
||||
size: Size,
|
||||
align: Align,
|
||||
|
@ -1251,8 +1251,8 @@ impl<'a, 'tcx> Layout {
|
|||
}
|
||||
};
|
||||
let abi = match *layout {
|
||||
Scalar(value) => Abi::Scalar(value),
|
||||
CEnum { discr, .. } => Abi::Scalar(Int(discr)),
|
||||
Scalar(value) |
|
||||
CEnum { discr: value, .. } => Abi::Scalar(value),
|
||||
|
||||
Vector { .. } => Abi::Vector,
|
||||
|
||||
|
@ -1453,7 +1453,7 @@ impl<'a, 'tcx> Layout {
|
|||
// grok.
|
||||
let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
|
||||
return success(CEnum {
|
||||
discr,
|
||||
discr: Int(discr),
|
||||
signed,
|
||||
// FIXME: should be u128?
|
||||
min: min as u64,
|
||||
|
@ -1646,7 +1646,7 @@ impl<'a, 'tcx> Layout {
|
|||
}
|
||||
|
||||
General {
|
||||
discr: ity,
|
||||
discr: Int(ity),
|
||||
variants,
|
||||
size,
|
||||
align,
|
||||
|
@ -1722,7 +1722,7 @@ impl<'a, 'tcx> Layout {
|
|||
metadata.size(dl)).abi_align(self.align(dl))
|
||||
}
|
||||
|
||||
CEnum { discr, .. } => Int(discr).size(dl),
|
||||
CEnum { discr, .. } => discr.size(dl),
|
||||
General { size, .. } => size,
|
||||
UntaggedUnion(ref un) => un.stride(),
|
||||
|
||||
|
@ -1756,7 +1756,7 @@ impl<'a, 'tcx> Layout {
|
|||
Pointer.align(dl).max(metadata.align(dl))
|
||||
}
|
||||
|
||||
CEnum { discr, .. } => Int(discr).align(dl),
|
||||
CEnum { discr, .. } => discr.align(dl),
|
||||
Array { align, .. } | General { align, .. } => align,
|
||||
UntaggedUnion(ref un) => un.align,
|
||||
|
||||
|
@ -1858,7 +1858,7 @@ impl<'a, 'tcx> Layout {
|
|||
}
|
||||
};
|
||||
|
||||
let build_primitive_info = |name: ast::Name, value: &Primitive| {
|
||||
let build_primitive_info = |name: ast::Name, value: Primitive| {
|
||||
session::VariantInfo {
|
||||
name: Some(name.to_string()),
|
||||
kind: session::SizeKind::Exact,
|
||||
|
@ -1951,7 +1951,7 @@ impl<'a, 'tcx> Layout {
|
|||
variant_layout)
|
||||
})
|
||||
.collect();
|
||||
record(adt_kind.into(), Some(discr.size()), variant_infos);
|
||||
record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
|
||||
}
|
||||
|
||||
Layout::UntaggedUnion(ref un) => {
|
||||
|
@ -1966,11 +1966,10 @@ impl<'a, 'tcx> Layout {
|
|||
let variant_infos: Vec<_> =
|
||||
adt_def.variants.iter()
|
||||
.map(|variant_def| {
|
||||
build_primitive_info(variant_def.name,
|
||||
&Primitive::Int(discr))
|
||||
build_primitive_info(variant_def.name, discr)
|
||||
})
|
||||
.collect();
|
||||
record(adt_kind.into(), Some(discr.size()), variant_infos);
|
||||
record(adt_kind.into(), Some(discr.size(tcx)), variant_infos);
|
||||
}
|
||||
|
||||
// other cases provide little interesting (i.e. adjustable
|
||||
|
@ -2359,9 +2358,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
|
|||
match self.variant_index {
|
||||
None => match *self.layout {
|
||||
// Discriminant field for enums (where applicable).
|
||||
General { discr, .. } => {
|
||||
return [discr.to_ty(tcx, false)][i];
|
||||
}
|
||||
General { discr, .. } |
|
||||
NullablePointer { discr, .. } => {
|
||||
return [discr.to_ty(tcx)][i];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{Layout, LayoutOf, Primitive};
|
||||
use rustc::ty::layout::{Layout, LayoutOf};
|
||||
use middle::const_val::ConstVal;
|
||||
use rustc_const_eval::ConstContext;
|
||||
use util::nodemap::FxHashSet;
|
||||
|
@ -754,7 +754,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
|
|||
});
|
||||
|
||||
if let Layout::General { ref variants, ref size, discr, .. } = *layout {
|
||||
let discr_size = Primitive::Int(discr).size(cx.tcx).bytes();
|
||||
let discr_size = discr.size(cx.tcx).bytes();
|
||||
|
||||
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
|
||||
t, size.bytes(), layout);
|
||||
|
|
|
@ -474,7 +474,7 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
|||
|
||||
// Rust enum types that map onto C enums also need to follow
|
||||
// the target ABI zero-/sign-extension rules.
|
||||
Layout::CEnum { discr, signed, .. } => (discr, signed),
|
||||
Layout::CEnum { discr: layout::Int(i), signed, .. } => (i, signed),
|
||||
|
||||
_ => return
|
||||
};
|
||||
|
|
|
@ -103,7 +103,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||
let l = cx.layout_of(t);
|
||||
debug!("adt::generic_type_of t: {:?} name: {:?}", t, name);
|
||||
match *l {
|
||||
layout::CEnum { discr, .. } => Type::from_integer(cx, discr),
|
||||
layout::CEnum { discr, .. } => cx.llvm_type_of(discr.to_ty(cx.tcx())),
|
||||
layout::NullablePointer { nndiscr, ref nonnull, .. } => {
|
||||
if let layout::Abi::Scalar(_) = l.abi {
|
||||
return cx.llvm_type_of(l.field(cx, 0).ty);
|
||||
|
@ -236,11 +236,3 @@ pub fn is_discr_signed<'tcx>(l: &layout::Layout) -> bool {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assert_discr_in_range<D: PartialOrd>(min: D, max: D, discr: D) {
|
||||
if min <= max {
|
||||
assert!(min <= discr && discr <= max)
|
||||
} else {
|
||||
assert!(min <= discr || discr <= max)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1451,8 +1451,8 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||
})
|
||||
.collect();
|
||||
|
||||
let discriminant_type_metadata = |inttype: layout::Integer, signed: bool| {
|
||||
let disr_type_key = (enum_def_id, inttype);
|
||||
let discriminant_type_metadata = |discr: layout::Primitive, signed: bool| {
|
||||
let disr_type_key = (enum_def_id, discr);
|
||||
let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
|
||||
.borrow()
|
||||
.get(&disr_type_key).cloned();
|
||||
|
@ -1460,10 +1460,13 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||
Some(discriminant_type_metadata) => discriminant_type_metadata,
|
||||
None => {
|
||||
let (discriminant_size, discriminant_align) =
|
||||
(inttype.size(), inttype.align(cx));
|
||||
(discr.size(cx), discr.align(cx));
|
||||
let discriminant_base_type_metadata =
|
||||
type_metadata(cx,
|
||||
inttype.to_ty(cx.tcx(), signed),
|
||||
match discr {
|
||||
layout::Int(i) => i.to_ty(cx.tcx(), signed),
|
||||
_ => discr.to_ty(cx.tcx())
|
||||
},
|
||||
syntax_pos::DUMMY_SP);
|
||||
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ pub struct CrateDebugContext<'tcx> {
|
|||
llmod: ModuleRef,
|
||||
builder: DIBuilderRef,
|
||||
created_files: RefCell<FxHashMap<(Symbol, Symbol), DIFile>>,
|
||||
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Integer), DIType>>,
|
||||
created_enum_disr_types: RefCell<FxHashMap<(DefId, layout::Primitive), DIType>>,
|
||||
|
||||
type_map: RefCell<TypeMap<'tcx>>,
|
||||
namespace_map: RefCell<DefIdMap<DIScope>>,
|
||||
|
|
|
@ -1093,7 +1093,7 @@ fn trans_const_adt<'a, 'tcx>(
|
|||
_ => 0,
|
||||
};
|
||||
match *l {
|
||||
layout::CEnum { discr: d, min, max, .. } => {
|
||||
layout::CEnum { .. } => {
|
||||
let discr = match *kind {
|
||||
mir::AggregateKind::Adt(adt_def, _, _, _) => {
|
||||
adt_def.discriminant_for_variant(ccx.tcx(), variant_index)
|
||||
|
@ -1102,14 +1102,14 @@ fn trans_const_adt<'a, 'tcx>(
|
|||
_ => 0,
|
||||
};
|
||||
assert_eq!(vals.len(), 0);
|
||||
adt::assert_discr_in_range(min, max, discr);
|
||||
Const::new(C_int(Type::from_integer(ccx, d), discr as i64), t)
|
||||
Const::new(C_int(ccx.llvm_type_of(t), discr as i64), t)
|
||||
}
|
||||
layout::General { discr: d, ref variants, .. } => {
|
||||
layout::General { ref variants, .. } => {
|
||||
let discr_ty = l.field(ccx, 0).ty;
|
||||
let variant = &variants[variant_index];
|
||||
let lldiscr = C_int(Type::from_integer(ccx, d), variant_index as i64);
|
||||
let lldiscr = C_int(ccx.llvm_type_of(discr_ty), variant_index as i64);
|
||||
build_const_struct(ccx, l, &variant, vals,
|
||||
Some(Const::new(lldiscr, d.to_ty(ccx.tcx(), false))))
|
||||
Some(Const::new(lldiscr, discr_ty)))
|
||||
}
|
||||
layout::UntaggedUnion(ref un) => {
|
||||
assert_eq!(variant_index, 0);
|
||||
|
|
|
@ -351,25 +351,28 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
|||
}
|
||||
|
||||
/// Helper for cases where the discriminant is simply loaded.
|
||||
fn load_discr(self, bcx: &Builder, ity: layout::Integer, min: u64, max: u64) -> ValueRef {
|
||||
let bits = ity.size().bits();
|
||||
assert!(bits <= 64);
|
||||
let bits = bits as usize;
|
||||
let mask = !0u64 >> (64 - bits);
|
||||
// For a (max) discr of -1, max will be `-1 as usize`, which overflows.
|
||||
// However, that is fine here (it would still represent the full range),
|
||||
if max.wrapping_add(1) & mask == min & mask {
|
||||
// i.e., if the range is everything. The lo==hi case would be
|
||||
// rejected by the LLVM verifier (it would mean either an
|
||||
// empty set, which is impossible, or the entire range of the
|
||||
// type, which is pointless).
|
||||
bcx.load(self.llval, self.alignment.non_abi())
|
||||
} else {
|
||||
// llvm::ConstantRange can deal with ranges that wrap around,
|
||||
// so an overflow on (max + 1) is fine.
|
||||
bcx.load_range_assert(self.llval, min, max.wrapping_add(1), /* signed: */ llvm::True,
|
||||
self.alignment.non_abi())
|
||||
fn load_discr(self, bcx: &Builder, discr: layout::Primitive, min: u64, max: u64) -> ValueRef {
|
||||
if let layout::Int(ity) = discr {
|
||||
let bits = ity.size().bits();
|
||||
assert!(bits <= 64);
|
||||
let bits = bits as usize;
|
||||
let mask = !0u64 >> (64 - bits);
|
||||
// For a (max) discr of -1, max will be `-1 as usize`, which overflows.
|
||||
// However, that is fine here (it would still represent the full range),
|
||||
if max.wrapping_add(1) & mask == min & mask {
|
||||
// i.e., if the range is everything. The lo==hi case would be
|
||||
// rejected by the LLVM verifier (it would mean either an
|
||||
// empty set, which is impossible, or the entire range of the
|
||||
// type, which is pointless).
|
||||
} else {
|
||||
// llvm::ConstantRange can deal with ranges that wrap around,
|
||||
// so an overflow on (max + 1) is fine.
|
||||
return bcx.load_range_assert(self.llval, min, max.wrapping_add(1),
|
||||
/* signed: */ llvm::True,
|
||||
self.alignment.non_abi());
|
||||
}
|
||||
}
|
||||
bcx.load(self.llval, self.alignment.non_abi())
|
||||
}
|
||||
|
||||
/// Obtain the actual discriminant of a value.
|
||||
|
@ -406,14 +409,13 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
|||
.discriminant_for_variant(bcx.tcx(), variant_index)
|
||||
.to_u128_unchecked() as u64;
|
||||
match *l {
|
||||
layout::CEnum { discr, min, max, .. } => {
|
||||
adt::assert_discr_in_range(min, max, to);
|
||||
bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64),
|
||||
layout::CEnum { .. } => {
|
||||
bcx.store(C_int(bcx.ccx.llvm_type_of(self.ty.to_ty(bcx.tcx())), to as i64),
|
||||
self.llval, self.alignment.non_abi());
|
||||
}
|
||||
layout::General { discr, .. } => {
|
||||
layout::General { .. } => {
|
||||
let ptr = self.project_field(bcx, 0);
|
||||
bcx.store(C_int(Type::from_integer(bcx.ccx, discr), to as i64),
|
||||
bcx.store(C_int(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())), to as i64),
|
||||
ptr.llval, ptr.alignment.non_abi());
|
||||
}
|
||||
layout::Univariant { .. }
|
||||
|
|
Loading…
Reference in a new issue