Auto merge of #41329 - nagisa:bitflags-repr-options, r=eddyb
Compress ReprOptions a little bit r? @eddyb
This commit is contained in:
commit
9af79f52d0
@ -162,7 +162,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
hir::ItemStruct(..) | hir::ItemUnion(..) => {
|
||||
let def_id = self.tcx.hir.local_def_id(item.id);
|
||||
let def = self.tcx.lookup_adt_def(def_id);
|
||||
self.struct_has_extern_repr = def.repr.c;
|
||||
self.struct_has_extern_repr = def.repr.c();
|
||||
|
||||
intravisit::walk_item(self, &item);
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ fn unpack_option_like<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_ => return ty
|
||||
};
|
||||
|
||||
if def.variants.len() == 2 && !def.repr.c && def.repr.int.is_none() {
|
||||
if def.variants.len() == 2 && !def.repr.c() && def.repr.int.is_none() {
|
||||
let data_idx;
|
||||
|
||||
if def.variants[0].fields.is_empty() {
|
||||
|
@ -15,7 +15,7 @@ pub use self::Primitive::*;
|
||||
use infer::InferCtxt;
|
||||
use session::Session;
|
||||
use traits;
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions};
|
||||
use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions, ReprFlags};
|
||||
|
||||
use syntax::ast::{FloatTy, IntTy, UintTy};
|
||||
use syntax::attr;
|
||||
@ -479,7 +479,7 @@ impl Integer {
|
||||
return (discr, ity.is_signed());
|
||||
}
|
||||
|
||||
if repr.c {
|
||||
if repr.c() {
|
||||
match &tcx.sess.target.target.arch[..] {
|
||||
// WARNING: the ARM EABI has two variants; the one corresponding
|
||||
// to `at_least == I32` appears to be used on Linux and NetBSD,
|
||||
@ -583,7 +583,7 @@ impl<'a, 'gcx, 'tcx> Struct {
|
||||
fn new(dl: &TargetDataLayout, fields: &Vec<&'a Layout>,
|
||||
repr: &ReprOptions, kind: StructKind,
|
||||
scapegoat: Ty<'gcx>) -> Result<Struct, LayoutError<'gcx>> {
|
||||
let packed = repr.packed;
|
||||
let packed = repr.packed();
|
||||
let mut ret = Struct {
|
||||
align: if packed { dl.i8_align } else { dl.aggregate_align },
|
||||
packed: packed,
|
||||
@ -598,7 +598,7 @@ impl<'a, 'gcx, 'tcx> Struct {
|
||||
// In addition, code in trans assume that 2-element structs can become pairs.
|
||||
// It's easier to just short-circuit here.
|
||||
let can_optimize = (fields.len() > 2 || StructKind::EnumVariant == kind)
|
||||
&& !(repr.c || repr.packed || repr.linear || repr.simd);
|
||||
&& (repr.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty();
|
||||
|
||||
let (optimize, sort_ascending) = match kind {
|
||||
StructKind::AlwaysSizedUnivariant => (can_optimize, false),
|
||||
@ -1177,7 +1177,7 @@ impl<'a, 'gcx, 'tcx> Layout {
|
||||
}
|
||||
|
||||
// SIMD vector types.
|
||||
ty::TyAdt(def, ..) if def.repr.simd => {
|
||||
ty::TyAdt(def, ..) if def.repr.simd() => {
|
||||
let element = ty.simd_type(tcx);
|
||||
match *element.layout(infcx)? {
|
||||
Scalar { value, .. } => {
|
||||
@ -1255,7 +1255,7 @@ impl<'a, 'gcx, 'tcx> Layout {
|
||||
field.ty(tcx, substs).layout(infcx)
|
||||
}).collect::<Result<Vec<_>, _>>()?;
|
||||
let layout = if def.is_union() {
|
||||
let mut un = Union::new(dl, def.repr.packed);
|
||||
let mut un = Union::new(dl, def.repr.packed());
|
||||
un.extend(dl, fields.iter().map(|&f| Ok(f)), ty)?;
|
||||
UntaggedUnion { variants: un }
|
||||
} else {
|
||||
@ -1925,7 +1925,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
|
||||
ty::TyTuple(tys, _) => tys[i],
|
||||
|
||||
// SIMD vector types.
|
||||
ty::TyAdt(def, ..) if def.repr.simd => {
|
||||
ty::TyAdt(def, ..) if def.repr.simd() => {
|
||||
self.ty.simd_type(tcx)
|
||||
}
|
||||
|
||||
|
@ -1438,51 +1438,81 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for AdtDef {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum AdtKind { Struct, Union, Enum }
|
||||
|
||||
bitflags! {
|
||||
#[derive(RustcEncodable, RustcDecodable, Default)]
|
||||
flags ReprFlags: u8 {
|
||||
const IS_C = 1 << 0,
|
||||
const IS_PACKED = 1 << 1,
|
||||
const IS_SIMD = 1 << 2,
|
||||
// Internal only for now. If true, don't reorder fields.
|
||||
const IS_LINEAR = 1 << 3,
|
||||
|
||||
// Any of these flags being set prevent field reordering optimisation.
|
||||
const IS_UNOPTIMISABLE = ReprFlags::IS_C.bits |
|
||||
ReprFlags::IS_PACKED.bits |
|
||||
ReprFlags::IS_SIMD.bits |
|
||||
ReprFlags::IS_LINEAR.bits,
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ReprFlags {
|
||||
bits
|
||||
});
|
||||
|
||||
|
||||
|
||||
/// Represents the repr options provided by the user,
|
||||
#[derive(Copy, Clone, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
|
||||
pub struct ReprOptions {
|
||||
pub c: bool,
|
||||
pub packed: bool,
|
||||
pub simd: bool,
|
||||
pub int: Option<attr::IntType>,
|
||||
// Internal only for now. If true, don't reorder fields.
|
||||
pub linear: bool,
|
||||
pub flags: ReprFlags,
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ReprOptions {
|
||||
c,
|
||||
packed,
|
||||
simd,
|
||||
int,
|
||||
linear
|
||||
flags
|
||||
});
|
||||
|
||||
impl ReprOptions {
|
||||
pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions {
|
||||
let mut ret = ReprOptions::default();
|
||||
let mut flags = ReprFlags::empty();
|
||||
let mut size = None;
|
||||
|
||||
for attr in tcx.get_attrs(did).iter() {
|
||||
for r in attr::find_repr_attrs(tcx.sess.diagnostic(), attr) {
|
||||
match r {
|
||||
attr::ReprExtern => ret.c = true,
|
||||
attr::ReprPacked => ret.packed = true,
|
||||
attr::ReprSimd => ret.simd = true,
|
||||
attr::ReprInt(i) => ret.int = Some(i),
|
||||
}
|
||||
flags.insert(match r {
|
||||
attr::ReprExtern => ReprFlags::IS_C,
|
||||
attr::ReprPacked => ReprFlags::IS_PACKED,
|
||||
attr::ReprSimd => ReprFlags::IS_SIMD,
|
||||
attr::ReprInt(i) => {
|
||||
size = Some(i);
|
||||
ReprFlags::empty()
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(eddyb) This is deprecated and should be removed.
|
||||
if tcx.has_attr(did, "simd") {
|
||||
ret.simd = true;
|
||||
flags.insert(ReprFlags::IS_SIMD);
|
||||
}
|
||||
|
||||
// This is here instead of layout because the choice must make it into metadata.
|
||||
ret.linear = !tcx.consider_optimizing(|| format!("Reorder fields of {:?}",
|
||||
tcx.item_path_str(did)));
|
||||
ret
|
||||
if !tcx.consider_optimizing(|| format!("Reorder fields of {:?}", tcx.item_path_str(did))) {
|
||||
flags.insert(ReprFlags::IS_LINEAR);
|
||||
}
|
||||
ReprOptions { int: size, flags: flags }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn simd(&self) -> bool { self.flags.contains(ReprFlags::IS_SIMD) }
|
||||
#[inline]
|
||||
pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) }
|
||||
#[inline]
|
||||
pub fn packed(&self) -> bool { self.flags.contains(ReprFlags::IS_PACKED) }
|
||||
#[inline]
|
||||
pub fn linear(&self) -> bool { self.flags.contains(ReprFlags::IS_LINEAR) }
|
||||
|
||||
pub fn discr_type(&self) -> attr::IntType {
|
||||
self.int.unwrap_or(attr::SignedInt(ast::IntTy::Is))
|
||||
}
|
||||
@ -1491,7 +1521,7 @@ impl ReprOptions {
|
||||
/// layout" optimizations, such as representing `Foo<&T>` as a
|
||||
/// single pointer.
|
||||
pub fn inhibit_enum_layout_opt(&self) -> bool {
|
||||
self.c || self.int.is_some()
|
||||
self.c() || self.int.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||
#[inline]
|
||||
pub fn is_simd(&self) -> bool {
|
||||
match self.sty {
|
||||
TyAdt(def, _) => def.repr.simd,
|
||||
TyAdt(def, _) => def.repr.simd(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
match def.adt_kind() {
|
||||
AdtKind::Struct => {
|
||||
if !def.repr.c {
|
||||
if !def.repr.c() {
|
||||
return FfiUnsafe("found struct without foreign-function-safe \
|
||||
representation annotation in foreign module, \
|
||||
consider adding a #[repr(C)] attribute to the type");
|
||||
@ -450,7 +450,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
if all_phantom { FfiPhantom } else { FfiSafe }
|
||||
}
|
||||
AdtKind::Union => {
|
||||
if !def.repr.c {
|
||||
if !def.repr.c() {
|
||||
return FfiUnsafe("found union without foreign-function-safe \
|
||||
representation annotation in foreign module, \
|
||||
consider adding a #[repr(C)] attribute to the type");
|
||||
@ -489,7 +489,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
|
||||
// Check for a repr() attribute to specify the size of the
|
||||
// discriminant.
|
||||
if !def.repr.c && def.repr.int.is_none() {
|
||||
if !def.repr.c() && def.repr.int.is_none() {
|
||||
// Special-case types like `Option<extern fn()>`.
|
||||
if !is_repr_nullable_ptr(cx, def, substs) {
|
||||
return FfiUnsafe("found enum without foreign-function-safe \
|
||||
|
@ -918,7 +918,7 @@ fn check_struct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def.destructor(tcx); // force the destructor to be evaluated
|
||||
check_representable(tcx, span, def_id);
|
||||
|
||||
if def.repr.simd {
|
||||
if def.repr.simd() {
|
||||
check_simd(tcx, span, def_id);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user