2
2
3
3
use crate :: ir:: context:: BindgenContext ;
4
4
use crate :: ir:: layout:: Layout ;
5
- use proc_macro2:: { Ident , Span , TokenStream } ;
6
- use quote:: TokenStreamExt ;
7
5
8
6
pub ( crate ) mod attributes {
9
7
use proc_macro2:: { Ident , Span , TokenStream } ;
@@ -79,114 +77,146 @@ pub(crate) mod attributes {
79
77
80
78
/// Generates a proper type for a field or type with a given `Layout`, that is,
81
79
/// a type with the correct size and alignment restrictions.
82
- pub ( crate ) fn blob ( ctx : & BindgenContext , layout : Layout ) -> TokenStream {
80
+ pub ( crate ) fn blob ( ctx : & BindgenContext , layout : Layout ) -> syn :: Type {
83
81
let opaque = layout. opaque ( ) ;
84
82
85
83
// FIXME(emilio, #412): We fall back to byte alignment, but there are
86
84
// some things that legitimately are more than 8-byte aligned.
87
85
//
88
86
// Eventually we should be able to `unwrap` here, but...
89
- let ty_name = match opaque. known_rust_type_for_array ( ctx) {
87
+ let ty = match opaque. known_rust_type_for_array ( ctx) {
90
88
Some ( ty) => ty,
91
89
None => {
92
90
warn ! ( "Found unknown alignment on code generation!" ) ;
93
- "u8"
91
+ syn :: parse_quote! { u8 }
94
92
}
95
93
} ;
96
94
97
- let ty_name = Ident :: new ( ty_name, Span :: call_site ( ) ) ;
98
-
99
95
let data_len = opaque. array_size ( ctx) . unwrap_or ( layout. size ) ;
100
96
101
97
if data_len == 1 {
102
- quote ! {
103
- #ty_name
104
- }
98
+ ty
105
99
} else {
106
- quote ! {
107
- [ #ty_name ; #data_len ]
108
- }
100
+ syn:: parse_quote! { [ #ty ; #data_len ] }
109
101
}
110
102
}
111
103
112
104
/// Integer type of the same size as the given `Layout`.
113
105
pub ( crate ) fn integer_type (
114
106
ctx : & BindgenContext ,
115
107
layout : Layout ,
116
- ) -> Option < TokenStream > {
117
- let name = Layout :: known_type_for_size ( ctx, layout. size ) ?;
118
- let name = Ident :: new ( name, Span :: call_site ( ) ) ;
119
- Some ( quote ! { #name } )
108
+ ) -> Option < syn:: Type > {
109
+ Layout :: known_type_for_size ( ctx, layout. size )
120
110
}
121
111
122
112
/// Generates a bitfield allocation unit type for a type with the given `Layout`.
123
- pub ( crate ) fn bitfield_unit (
124
- ctx : & BindgenContext ,
125
- layout : Layout ,
126
- ) -> TokenStream {
127
- let mut tokens = quote ! { } ;
113
+ pub ( crate ) fn bitfield_unit ( ctx : & BindgenContext , layout : Layout ) -> syn:: Type {
114
+ let size = layout. size ;
115
+ let ty = syn:: parse_quote! { __BindgenBitfieldUnit<[ u8 ; #size] > } ;
128
116
129
117
if ctx. options ( ) . enable_cxx_namespaces {
130
- tokens . append_all ( quote ! { root:: } ) ;
118
+ return syn :: parse_quote ! { root:: #ty } ;
131
119
}
132
120
133
- let size = layout. size ;
134
- tokens. append_all ( quote ! {
135
- __BindgenBitfieldUnit<[ u8 ; #size] >
136
- } ) ;
137
-
138
- tokens
121
+ ty
139
122
}
140
123
141
124
pub ( crate ) mod ast_ty {
142
125
use crate :: ir:: context:: BindgenContext ;
143
126
use crate :: ir:: function:: FunctionSig ;
144
127
use crate :: ir:: layout:: Layout ;
145
- use crate :: ir:: ty:: FloatKind ;
128
+ use crate :: ir:: ty:: { FloatKind , IntKind } ;
146
129
use proc_macro2:: { self , TokenStream } ;
147
130
use std:: str:: FromStr ;
148
131
149
- pub ( crate ) fn c_void ( ctx : & BindgenContext ) -> TokenStream {
132
+ pub ( crate ) fn c_void ( ctx : & BindgenContext ) -> syn :: Type {
150
133
// ctypes_prefix takes precedence
151
134
match ctx. options ( ) . ctypes_prefix {
152
135
Some ( ref prefix) => {
153
136
let prefix = TokenStream :: from_str ( prefix. as_str ( ) ) . unwrap ( ) ;
154
- quote ! {
155
- #prefix:: c_void
156
- }
137
+ syn:: parse_quote! { #prefix:: c_void }
157
138
}
158
139
None => {
159
140
if ctx. options ( ) . use_core &&
160
141
ctx. options ( ) . rust_features . core_ffi_c_void
161
142
{
162
- quote ! { :: core:: ffi:: c_void }
143
+ syn :: parse_quote ! { :: core:: ffi:: c_void }
163
144
} else {
164
- quote ! { :: std:: os:: raw:: c_void }
145
+ syn :: parse_quote ! { :: std:: os:: raw:: c_void }
165
146
}
166
147
}
167
148
}
168
149
}
169
150
170
- pub ( crate ) fn raw_type ( ctx : & BindgenContext , name : & str ) -> TokenStream {
151
+ pub ( crate ) fn raw_type ( ctx : & BindgenContext , name : & str ) -> syn :: Type {
171
152
let ident = ctx. rust_ident_raw ( name) ;
172
153
match ctx. options ( ) . ctypes_prefix {
173
154
Some ( ref prefix) => {
174
155
let prefix = TokenStream :: from_str ( prefix. as_str ( ) ) . unwrap ( ) ;
175
- quote ! {
176
- #prefix:: #ident
177
- }
156
+ syn:: parse_quote! { #prefix:: #ident }
178
157
}
179
158
None => {
180
159
if ctx. options ( ) . use_core &&
181
160
ctx. options ( ) . rust_features ( ) . core_ffi_c
182
161
{
183
- quote ! {
184
- :: core:: ffi:: #ident
185
- }
162
+ syn:: parse_quote! { :: core:: ffi:: #ident }
186
163
} else {
187
- quote ! {
188
- :: std:: os:: raw:: #ident
189
- }
164
+ syn:: parse_quote! { :: std:: os:: raw:: #ident }
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ pub ( crate ) fn int_kind_rust_type (
171
+ ctx : & BindgenContext ,
172
+ ik : IntKind ,
173
+ layout : Option < Layout > ,
174
+ ) -> syn:: Type {
175
+ match ik {
176
+ IntKind :: Bool => syn:: parse_quote! { bool } ,
177
+ IntKind :: Char { .. } => raw_type ( ctx, "c_char" ) ,
178
+ IntKind :: SChar => raw_type ( ctx, "c_schar" ) ,
179
+ IntKind :: UChar => raw_type ( ctx, "c_uchar" ) ,
180
+ IntKind :: Short => raw_type ( ctx, "c_short" ) ,
181
+ IntKind :: UShort => raw_type ( ctx, "c_ushort" ) ,
182
+ IntKind :: Int => raw_type ( ctx, "c_int" ) ,
183
+ IntKind :: UInt => raw_type ( ctx, "c_uint" ) ,
184
+ IntKind :: Long => raw_type ( ctx, "c_long" ) ,
185
+ IntKind :: ULong => raw_type ( ctx, "c_ulong" ) ,
186
+ IntKind :: LongLong => raw_type ( ctx, "c_longlong" ) ,
187
+ IntKind :: ULongLong => raw_type ( ctx, "c_ulonglong" ) ,
188
+ IntKind :: WChar => {
189
+ let layout =
190
+ layout. expect ( "Couldn't compute wchar_t's layout?" ) ;
191
+ Layout :: known_type_for_size ( ctx, layout. size )
192
+ . expect ( "Non-representable wchar_t?" )
193
+ }
194
+
195
+ IntKind :: I8 => syn:: parse_quote! { i8 } ,
196
+ IntKind :: U8 => syn:: parse_quote! { u8 } ,
197
+ IntKind :: I16 => syn:: parse_quote! { i16 } ,
198
+ IntKind :: U16 => syn:: parse_quote! { u16 } ,
199
+ IntKind :: I32 => syn:: parse_quote! { i32 } ,
200
+ IntKind :: U32 => syn:: parse_quote! { u32 } ,
201
+ IntKind :: I64 => syn:: parse_quote! { i64 } ,
202
+ IntKind :: U64 => syn:: parse_quote! { u64 } ,
203
+ IntKind :: Custom { name, .. } => {
204
+ syn:: parse_str ( name) . expect ( "Invalid integer type." )
205
+ }
206
+ IntKind :: U128 => {
207
+ if ctx. options ( ) . rust_features . i128_and_u128 {
208
+ syn:: parse_quote! { u128 }
209
+ } else {
210
+ // Best effort thing, but wrong alignment
211
+ // unfortunately.
212
+ syn:: parse_quote! { [ u64 ; 2 ] }
213
+ }
214
+ }
215
+ IntKind :: I128 => {
216
+ if ctx. options ( ) . rust_features . i128_and_u128 {
217
+ syn:: parse_quote! { i128 }
218
+ } else {
219
+ syn:: parse_quote! { [ u64 ; 2 ] }
190
220
}
191
221
}
192
222
}
@@ -196,42 +226,42 @@ pub(crate) mod ast_ty {
196
226
ctx : & BindgenContext ,
197
227
fk : FloatKind ,
198
228
layout : Option < Layout > ,
199
- ) -> TokenStream {
229
+ ) -> syn :: Type {
200
230
// TODO: we probably should take the type layout into account more
201
231
// often?
202
232
//
203
233
// Also, maybe this one shouldn't be the default?
204
234
match ( fk, ctx. options ( ) . convert_floats ) {
205
- ( FloatKind :: Float , true ) => quote ! { f32 } ,
206
- ( FloatKind :: Double , true ) => quote ! { f64 } ,
235
+ ( FloatKind :: Float , true ) => syn :: parse_quote ! { f32 } ,
236
+ ( FloatKind :: Double , true ) => syn :: parse_quote ! { f64 } ,
207
237
( FloatKind :: Float , false ) => raw_type ( ctx, "c_float" ) ,
208
238
( FloatKind :: Double , false ) => raw_type ( ctx, "c_double" ) ,
209
239
( FloatKind :: LongDouble , _) => {
210
240
match layout {
211
241
Some ( layout) => {
212
242
match layout. size {
213
- 4 => quote ! { f32 } ,
214
- 8 => quote ! { f64 } ,
243
+ 4 => syn :: parse_quote ! { f32 } ,
244
+ 8 => syn :: parse_quote ! { f64 } ,
215
245
// TODO(emilio): If rust ever gains f128 we should
216
246
// use it here and below.
217
247
_ => super :: integer_type ( ctx, layout)
218
- . unwrap_or ( quote ! { f64 } ) ,
248
+ . unwrap_or ( syn :: parse_quote ! { f64 } ) ,
219
249
}
220
250
}
221
251
None => {
222
252
debug_assert ! (
223
253
false ,
224
254
"How didn't we know the layout for a primitive type?"
225
255
) ;
226
- quote ! { f64 }
256
+ syn :: parse_quote ! { f64 }
227
257
}
228
258
}
229
259
}
230
260
( FloatKind :: Float128 , _) => {
231
261
if ctx. options ( ) . rust_features . i128_and_u128 {
232
- quote ! { u128 }
262
+ syn :: parse_quote ! { u128 }
233
263
} else {
234
- quote ! { [ u64 ; 2 ] }
264
+ syn :: parse_quote ! { [ u64 ; 2 ] }
235
265
}
236
266
}
237
267
}
0 commit comments