@@ -48,7 +48,8 @@ use rustc_session::cstore::CrateStoreDyn;
48
48
use rustc_span:: hygiene:: MacroKind ;
49
49
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
50
50
use rustc_span:: { ExpnId , Span } ;
51
- use rustc_target:: abi:: { Align , VariantIdx } ;
51
+ use rustc_target:: abi:: { Align , Integer , IntegerType , VariantIdx } ;
52
+ pub use rustc_target:: abi:: { ReprFlags , ReprOptions } ;
52
53
pub use subst:: * ;
53
54
pub use vtable:: * ;
54
55
@@ -1994,161 +1995,76 @@ impl Hash for FieldDef {
1994
1995
}
1995
1996
}
1996
1997
1997
- bitflags ! {
1998
- #[ derive( TyEncodable , TyDecodable , Default , HashStable ) ]
1999
- pub struct ReprFlags : u8 {
2000
- const IS_C = 1 << 0 ;
2001
- const IS_SIMD = 1 << 1 ;
2002
- const IS_TRANSPARENT = 1 << 2 ;
2003
- // Internal only for now. If true, don't reorder fields.
2004
- const IS_LINEAR = 1 << 3 ;
2005
- // If true, the type's layout can be randomized using
2006
- // the seed stored in `ReprOptions.layout_seed`
2007
- const RANDOMIZE_LAYOUT = 1 << 4 ;
2008
- // Any of these flags being set prevent field reordering optimisation.
2009
- const IS_UNOPTIMISABLE = ReprFlags :: IS_C . bits
2010
- | ReprFlags :: IS_SIMD . bits
2011
- | ReprFlags :: IS_LINEAR . bits;
2012
- }
2013
- }
2014
-
2015
- /// Represents the repr options provided by the user,
2016
- #[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Default , HashStable ) ]
2017
- pub struct ReprOptions {
2018
- pub int : Option < attr:: IntType > ,
2019
- pub align : Option < Align > ,
2020
- pub pack : Option < Align > ,
2021
- pub flags : ReprFlags ,
2022
- /// The seed to be used for randomizing a type's layout
2023
- ///
2024
- /// Note: This could technically be a `[u8; 16]` (a `u128`) which would
2025
- /// be the "most accurate" hash as it'd encompass the item and crate
2026
- /// hash without loss, but it does pay the price of being larger.
2027
- /// Everything's a tradeoff, a `u64` seed should be sufficient for our
2028
- /// purposes (primarily `-Z randomize-layout`)
2029
- pub field_shuffle_seed : u64 ,
2030
- }
2031
-
2032
- impl ReprOptions {
2033
- pub fn new ( tcx : TyCtxt < ' _ > , did : DefId ) -> ReprOptions {
2034
- let mut flags = ReprFlags :: empty ( ) ;
2035
- let mut size = None ;
2036
- let mut max_align: Option < Align > = None ;
2037
- let mut min_pack: Option < Align > = None ;
2038
-
2039
- // Generate a deterministically-derived seed from the item's path hash
2040
- // to allow for cross-crate compilation to actually work
2041
- let mut field_shuffle_seed = tcx. def_path_hash ( did) . 0 . to_smaller_hash ( ) ;
2042
-
2043
- // If the user defined a custom seed for layout randomization, xor the item's
2044
- // path hash with the user defined seed, this will allowing determinism while
2045
- // still allowing users to further randomize layout generation for e.g. fuzzing
2046
- if let Some ( user_seed) = tcx. sess . opts . unstable_opts . layout_seed {
2047
- field_shuffle_seed ^= user_seed;
2048
- }
2049
-
2050
- for attr in tcx. get_attrs ( did, sym:: repr) {
2051
- for r in attr:: parse_repr_attr ( & tcx. sess , attr) {
2052
- flags. insert ( match r {
2053
- attr:: ReprC => ReprFlags :: IS_C ,
2054
- attr:: ReprPacked ( pack) => {
2055
- let pack = Align :: from_bytes ( pack as u64 ) . unwrap ( ) ;
2056
- min_pack = Some ( if let Some ( min_pack) = min_pack {
2057
- min_pack. min ( pack)
2058
- } else {
2059
- pack
2060
- } ) ;
2061
- ReprFlags :: empty ( )
2062
- }
2063
- attr:: ReprTransparent => ReprFlags :: IS_TRANSPARENT ,
2064
- attr:: ReprSimd => ReprFlags :: IS_SIMD ,
2065
- attr:: ReprInt ( i) => {
2066
- size = Some ( i) ;
2067
- ReprFlags :: empty ( )
2068
- }
2069
- attr:: ReprAlign ( align) => {
2070
- max_align = max_align. max ( Some ( Align :: from_bytes ( align as u64 ) . unwrap ( ) ) ) ;
2071
- ReprFlags :: empty ( )
2072
- }
2073
- } ) ;
2074
- }
2075
- }
1998
+ pub fn repr_options_of_def ( tcx : TyCtxt < ' _ > , did : DefId ) -> ReprOptions {
1999
+ let mut flags = ReprFlags :: empty ( ) ;
2000
+ let mut size = None ;
2001
+ let mut max_align: Option < Align > = None ;
2002
+ let mut min_pack: Option < Align > = None ;
2076
2003
2077
- // If `-Z randomize-layout` was enabled for the type definition then we can
2078
- // consider performing layout randomization
2079
- if tcx. sess . opts . unstable_opts . randomize_layout {
2080
- flags. insert ( ReprFlags :: RANDOMIZE_LAYOUT ) ;
2081
- }
2004
+ // Generate a deterministically-derived seed from the item's path hash
2005
+ // to allow for cross-crate compilation to actually work
2006
+ let mut field_shuffle_seed = tcx. def_path_hash ( did) . 0 . to_smaller_hash ( ) ;
2082
2007
2083
- // This is here instead of layout because the choice must make it into metadata.
2084
- if !tcx. consider_optimizing ( || format ! ( "Reorder fields of {:?}" , tcx. def_path_str( did) ) ) {
2085
- flags. insert ( ReprFlags :: IS_LINEAR ) ;
2086
- }
2087
-
2088
- Self { int : size, align : max_align, pack : min_pack, flags, field_shuffle_seed }
2089
- }
2090
-
2091
- #[ inline]
2092
- pub fn simd ( & self ) -> bool {
2093
- self . flags . contains ( ReprFlags :: IS_SIMD )
2008
+ // If the user defined a custom seed for layout randomization, xor the item's
2009
+ // path hash with the user defined seed, this will allowing determinism while
2010
+ // still allowing users to further randomize layout generation for e.g. fuzzing
2011
+ if let Some ( user_seed) = tcx. sess . opts . unstable_opts . layout_seed {
2012
+ field_shuffle_seed ^= user_seed;
2094
2013
}
2095
2014
2096
- #[ inline]
2097
- pub fn c ( & self ) -> bool {
2098
- self . flags . contains ( ReprFlags :: IS_C )
2099
- }
2100
-
2101
- #[ inline]
2102
- pub fn packed ( & self ) -> bool {
2103
- self . pack . is_some ( )
2104
- }
2105
-
2106
- #[ inline]
2107
- pub fn transparent ( & self ) -> bool {
2108
- self . flags . contains ( ReprFlags :: IS_TRANSPARENT )
2109
- }
2110
-
2111
- #[ inline]
2112
- pub fn linear ( & self ) -> bool {
2113
- self . flags . contains ( ReprFlags :: IS_LINEAR )
2114
- }
2115
-
2116
- /// Returns the discriminant type, given these `repr` options.
2117
- /// This must only be called on enums!
2118
- pub fn discr_type ( & self ) -> attr:: IntType {
2119
- self . int . unwrap_or ( attr:: SignedInt ( ast:: IntTy :: Isize ) )
2120
- }
2121
-
2122
- /// Returns `true` if this `#[repr()]` should inhabit "smart enum
2123
- /// layout" optimizations, such as representing `Foo<&T>` as a
2124
- /// single pointer.
2125
- pub fn inhibit_enum_layout_opt ( & self ) -> bool {
2126
- self . c ( ) || self . int . is_some ( )
2127
- }
2128
-
2129
- /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
2130
- /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
2131
- pub fn inhibit_struct_field_reordering_opt ( & self ) -> bool {
2132
- if let Some ( pack) = self . pack {
2133
- if pack. bytes ( ) == 1 {
2134
- return true ;
2135
- }
2015
+ for attr in tcx. get_attrs ( did, sym:: repr) {
2016
+ for r in attr:: parse_repr_attr ( & tcx. sess , attr) {
2017
+ flags. insert ( match r {
2018
+ attr:: ReprC => ReprFlags :: IS_C ,
2019
+ attr:: ReprPacked ( pack) => {
2020
+ let pack = Align :: from_bytes ( pack as u64 ) . unwrap ( ) ;
2021
+ min_pack =
2022
+ Some ( if let Some ( min_pack) = min_pack { min_pack. min ( pack) } else { pack } ) ;
2023
+ ReprFlags :: empty ( )
2024
+ }
2025
+ attr:: ReprTransparent => ReprFlags :: IS_TRANSPARENT ,
2026
+ attr:: ReprSimd => ReprFlags :: IS_SIMD ,
2027
+ attr:: ReprInt ( i) => {
2028
+ size = Some ( match i {
2029
+ attr:: IntType :: SignedInt ( x) => match x {
2030
+ ast:: IntTy :: Isize => IntegerType :: Pointer ( true ) ,
2031
+ ast:: IntTy :: I8 => IntegerType :: Fixed ( Integer :: I8 , true ) ,
2032
+ ast:: IntTy :: I16 => IntegerType :: Fixed ( Integer :: I16 , true ) ,
2033
+ ast:: IntTy :: I32 => IntegerType :: Fixed ( Integer :: I32 , true ) ,
2034
+ ast:: IntTy :: I64 => IntegerType :: Fixed ( Integer :: I64 , true ) ,
2035
+ ast:: IntTy :: I128 => IntegerType :: Fixed ( Integer :: I128 , true ) ,
2036
+ } ,
2037
+ attr:: IntType :: UnsignedInt ( x) => match x {
2038
+ ast:: UintTy :: Usize => IntegerType :: Pointer ( false ) ,
2039
+ ast:: UintTy :: U8 => IntegerType :: Fixed ( Integer :: I8 , false ) ,
2040
+ ast:: UintTy :: U16 => IntegerType :: Fixed ( Integer :: I16 , false ) ,
2041
+ ast:: UintTy :: U32 => IntegerType :: Fixed ( Integer :: I32 , false ) ,
2042
+ ast:: UintTy :: U64 => IntegerType :: Fixed ( Integer :: I64 , false ) ,
2043
+ ast:: UintTy :: U128 => IntegerType :: Fixed ( Integer :: I128 , false ) ,
2044
+ } ,
2045
+ } ) ;
2046
+ ReprFlags :: empty ( )
2047
+ }
2048
+ attr:: ReprAlign ( align) => {
2049
+ max_align = max_align. max ( Some ( Align :: from_bytes ( align as u64 ) . unwrap ( ) ) ) ;
2050
+ ReprFlags :: empty ( )
2051
+ }
2052
+ } ) ;
2136
2053
}
2137
-
2138
- self . flags . intersects ( ReprFlags :: IS_UNOPTIMISABLE ) || self . int . is_some ( )
2139
2054
}
2140
2055
2141
- /// Returns `true` if this type is valid for reordering and `-Z randomize-layout`
2142
- /// was enabled for its declaration crate
2143
- pub fn can_randomize_type_layout ( & self ) -> bool {
2144
- !self . inhibit_struct_field_reordering_opt ( )
2145
- && self . flags . contains ( ReprFlags :: RANDOMIZE_LAYOUT )
2056
+ // If `-Z randomize-layout` was enabled for the type definition then we can
2057
+ // consider performing layout randomization
2058
+ if tcx. sess . opts . unstable_opts . randomize_layout {
2059
+ flags. insert ( ReprFlags :: RANDOMIZE_LAYOUT ) ;
2146
2060
}
2147
2061
2148
- /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations .
2149
- pub fn inhibit_union_abi_opt ( & self ) -> bool {
2150
- self . c ( )
2062
+ // This is here instead of layout because the choice must make it into metadata .
2063
+ if !tcx . consider_optimizing ( || format ! ( "Reorder fields of {:?}" , tcx . def_path_str ( did ) ) ) {
2064
+ flags . insert ( ReprFlags :: IS_LINEAR ) ;
2151
2065
}
2066
+
2067
+ ReprOptions { int : size, align : max_align, pack : min_pack, flags, field_shuffle_seed }
2152
2068
}
2153
2069
2154
2070
impl < ' tcx > FieldDef {
0 commit comments