7
7
///
8
8
/// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler,
9
9
/// see design document in the tracking issue #89653.
10
- use core:: fmt:: Display ;
11
10
use rustc_data_structures:: base_n;
12
11
use rustc_data_structures:: fx:: FxHashMap ;
13
12
use rustc_hir as hir;
13
+ use rustc_middle:: ty:: layout:: IntegerExt ;
14
14
use rustc_middle:: ty:: {
15
15
self , Const , ExistentialPredicate , FloatTy , FnSig , Instance , IntTy , List , Region , RegionKind ,
16
16
TermKind , Ty , TyCtxt , UintTy ,
@@ -19,6 +19,7 @@ use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
19
19
use rustc_span:: def_id:: DefId ;
20
20
use rustc_span:: sym;
21
21
use rustc_target:: abi:: call:: { Conv , FnAbi } ;
22
+ use rustc_target:: abi:: Integer ;
22
23
use rustc_target:: spec:: abi:: Abi ;
23
24
use std:: fmt:: Write as _;
24
25
@@ -93,44 +94,54 @@ fn encode_const<'tcx>(
93
94
dict : & mut FxHashMap < DictKey < ' tcx > , usize > ,
94
95
options : EncodeTyOptions ,
95
96
) -> String {
96
- // L<element-type>[n]<element-value>E as literal argument
97
+ // L<element-type>[n][ <element-value>] E as literal argument
97
98
let mut s = String :: from ( 'L' ) ;
98
99
99
- // Element type
100
- s. push_str ( & encode_ty ( tcx, c. ty ( ) , dict, options) ) ;
100
+ match c. kind ( ) {
101
+ // Const parameters
102
+ ty:: ConstKind :: Param ( ..) => {
103
+ // L<element-type>E as literal argument
101
104
102
- // The only allowed types of const parameters are bool, u8, u16, u32, u64, u128, usize i8, i16,
103
- // i32, i64, i128, isize, and char. The bool value false is encoded as 0 and true as 1.
104
- fn push_signed_value < T : Display + PartialOrd > ( s : & mut String , value : T , zero : T ) {
105
- if value < zero {
106
- s. push ( 'n' )
107
- } ;
108
- let _ = write ! ( s, "{value}" ) ;
109
- }
110
-
111
- fn push_unsigned_value < T : Display > ( s : & mut String , value : T ) {
112
- let _ = write ! ( s, "{value}" ) ;
113
- }
105
+ // Element type
106
+ s. push_str ( & encode_ty ( tcx, c. ty ( ) , dict, options) ) ;
107
+ }
114
108
115
- if let Some ( scalar_int) = c. try_to_scalar_int ( ) {
116
- let signed = c. ty ( ) . is_signed ( ) ;
117
- match scalar_int. size ( ) . bits ( ) {
118
- 8 if signed => push_signed_value ( & mut s, scalar_int. try_to_i8 ( ) . unwrap ( ) , 0 ) ,
119
- 16 if signed => push_signed_value ( & mut s, scalar_int. try_to_i16 ( ) . unwrap ( ) , 0 ) ,
120
- 32 if signed => push_signed_value ( & mut s, scalar_int. try_to_i32 ( ) . unwrap ( ) , 0 ) ,
121
- 64 if signed => push_signed_value ( & mut s, scalar_int. try_to_i64 ( ) . unwrap ( ) , 0 ) ,
122
- 128 if signed => push_signed_value ( & mut s, scalar_int. try_to_i128 ( ) . unwrap ( ) , 0 ) ,
123
- 8 => push_unsigned_value ( & mut s, scalar_int. try_to_u8 ( ) . unwrap ( ) ) ,
124
- 16 => push_unsigned_value ( & mut s, scalar_int. try_to_u16 ( ) . unwrap ( ) ) ,
125
- 32 => push_unsigned_value ( & mut s, scalar_int. try_to_u32 ( ) . unwrap ( ) ) ,
126
- 64 => push_unsigned_value ( & mut s, scalar_int. try_to_u64 ( ) . unwrap ( ) ) ,
127
- 128 => push_unsigned_value ( & mut s, scalar_int. try_to_u128 ( ) . unwrap ( ) ) ,
128
- _ => {
129
- bug ! ( "encode_const: unexpected size `{:?}`" , scalar_int. size( ) . bits( ) ) ;
109
+ // Literal arguments
110
+ ty:: ConstKind :: Value ( ..) => {
111
+ // L<element-type>[n]<element-value>E as literal argument
112
+
113
+ // Element type
114
+ s. push_str ( & encode_ty ( tcx, c. ty ( ) , dict, options) ) ;
115
+
116
+ // The only allowed types of const values are bool, u8, u16, u32,
117
+ // u64, u128, usize i8, i16, i32, i64, i128, isize, and char. The
118
+ // bool value false is encoded as 0 and true as 1.
119
+ match c. ty ( ) . kind ( ) {
120
+ ty:: Int ( ity) => {
121
+ let bits = c. eval_bits ( tcx, ty:: ParamEnv :: reveal_all ( ) , c. ty ( ) ) ;
122
+ let val = Integer :: from_int_ty ( & tcx, * ity) . size ( ) . sign_extend ( bits) as i128 ;
123
+ if val < 0 {
124
+ s. push ( 'n' ) ;
125
+ }
126
+ let _ = write ! ( s, "{val}" ) ;
127
+ }
128
+ ty:: Uint ( _) => {
129
+ let val = c. eval_bits ( tcx, ty:: ParamEnv :: reveal_all ( ) , c. ty ( ) ) ;
130
+ let _ = write ! ( s, "{val}" ) ;
131
+ }
132
+ ty:: Bool => {
133
+ let val = c. try_eval_bool ( tcx, ty:: ParamEnv :: reveal_all ( ) ) . unwrap ( ) ;
134
+ let _ = write ! ( s, "{val}" ) ;
135
+ }
136
+ _ => {
137
+ bug ! ( "encode_const: unexpected type `{:?}`" , c. ty( ) ) ;
138
+ }
130
139
}
131
- } ;
132
- } else {
133
- bug ! ( "encode_const: unexpected type `{:?}`" , c. ty( ) ) ;
140
+ }
141
+
142
+ _ => {
143
+ bug ! ( "encode_const: unexpected kind `{:?}`" , c. kind( ) ) ;
144
+ }
134
145
}
135
146
136
147
// Close the "L..E" pair
0 commit comments