22
33use crate :: ir:: context:: BindgenContext ;
44use crate :: ir:: layout:: Layout ;
5- use proc_macro2:: { Ident , Span , TokenStream } ;
6- use quote:: TokenStreamExt ;
75
86pub ( crate ) mod attributes {
97 use proc_macro2:: { Ident , Span , TokenStream } ;
@@ -79,114 +77,146 @@ pub(crate) mod attributes {
7977
8078/// Generates a proper type for a field or type with a given `Layout`, that is,
8179/// 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 {
8381 let opaque = layout. opaque ( ) ;
8482
8583 // FIXME(emilio, #412): We fall back to byte alignment, but there are
8684 // some things that legitimately are more than 8-byte aligned.
8785 //
8886 // 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) {
9088 Some ( ty) => ty,
9189 None => {
9290 warn ! ( "Found unknown alignment on code generation!" ) ;
93- "u8"
91+ syn :: parse_quote! { u8 }
9492 }
9593 } ;
9694
97- let ty_name = Ident :: new ( ty_name, Span :: call_site ( ) ) ;
98-
9995 let data_len = opaque. array_size ( ctx) . unwrap_or ( layout. size ) ;
10096
10197 if data_len == 1 {
102- quote ! {
103- #ty_name
104- }
98+ ty
10599 } else {
106- quote ! {
107- [ #ty_name ; #data_len ]
108- }
100+ syn:: parse_quote! { [ #ty ; #data_len ] }
109101 }
110102}
111103
112104/// Integer type of the same size as the given `Layout`.
113105pub ( crate ) fn integer_type (
114106 ctx : & BindgenContext ,
115107 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 )
120110}
121111
122112/// 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] > } ;
128116
129117 if ctx. options ( ) . enable_cxx_namespaces {
130- tokens . append_all ( quote ! { root:: } ) ;
118+ return syn :: parse_quote ! { root:: #ty } ;
131119 }
132120
133- let size = layout. size ;
134- tokens. append_all ( quote ! {
135- __BindgenBitfieldUnit<[ u8 ; #size] >
136- } ) ;
137-
138- tokens
121+ ty
139122}
140123
141124pub ( crate ) mod ast_ty {
142125 use crate :: ir:: context:: BindgenContext ;
143126 use crate :: ir:: function:: FunctionSig ;
144127 use crate :: ir:: layout:: Layout ;
145- use crate :: ir:: ty:: FloatKind ;
128+ use crate :: ir:: ty:: { FloatKind , IntKind } ;
146129 use proc_macro2:: { self , TokenStream } ;
147130 use std:: str:: FromStr ;
148131
149- pub ( crate ) fn c_void ( ctx : & BindgenContext ) -> TokenStream {
132+ pub ( crate ) fn c_void ( ctx : & BindgenContext ) -> syn :: Type {
150133 // ctypes_prefix takes precedence
151134 match ctx. options ( ) . ctypes_prefix {
152135 Some ( ref prefix) => {
153136 let prefix = TokenStream :: from_str ( prefix. as_str ( ) ) . unwrap ( ) ;
154- quote ! {
155- #prefix:: c_void
156- }
137+ syn:: parse_quote! { #prefix:: c_void }
157138 }
158139 None => {
159140 if ctx. options ( ) . use_core &&
160141 ctx. options ( ) . rust_features . core_ffi_c_void
161142 {
162- quote ! { :: core:: ffi:: c_void }
143+ syn :: parse_quote ! { :: core:: ffi:: c_void }
163144 } else {
164- quote ! { :: std:: os:: raw:: c_void }
145+ syn :: parse_quote ! { :: std:: os:: raw:: c_void }
165146 }
166147 }
167148 }
168149 }
169150
170- pub ( crate ) fn raw_type ( ctx : & BindgenContext , name : & str ) -> TokenStream {
151+ pub ( crate ) fn raw_type ( ctx : & BindgenContext , name : & str ) -> syn :: Type {
171152 let ident = ctx. rust_ident_raw ( name) ;
172153 match ctx. options ( ) . ctypes_prefix {
173154 Some ( ref prefix) => {
174155 let prefix = TokenStream :: from_str ( prefix. as_str ( ) ) . unwrap ( ) ;
175- quote ! {
176- #prefix:: #ident
177- }
156+ syn:: parse_quote! { #prefix:: #ident }
178157 }
179158 None => {
180159 if ctx. options ( ) . use_core &&
181160 ctx. options ( ) . rust_features ( ) . core_ffi_c
182161 {
183- quote ! {
184- :: core:: ffi:: #ident
185- }
162+ syn:: parse_quote! { :: core:: ffi:: #ident }
186163 } 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 ] }
190220 }
191221 }
192222 }
@@ -196,42 +226,42 @@ pub(crate) mod ast_ty {
196226 ctx : & BindgenContext ,
197227 fk : FloatKind ,
198228 layout : Option < Layout > ,
199- ) -> TokenStream {
229+ ) -> syn :: Type {
200230 // TODO: we probably should take the type layout into account more
201231 // often?
202232 //
203233 // Also, maybe this one shouldn't be the default?
204234 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 } ,
207237 ( FloatKind :: Float , false ) => raw_type ( ctx, "c_float" ) ,
208238 ( FloatKind :: Double , false ) => raw_type ( ctx, "c_double" ) ,
209239 ( FloatKind :: LongDouble , _) => {
210240 match layout {
211241 Some ( layout) => {
212242 match layout. size {
213- 4 => quote ! { f32 } ,
214- 8 => quote ! { f64 } ,
243+ 4 => syn :: parse_quote ! { f32 } ,
244+ 8 => syn :: parse_quote ! { f64 } ,
215245 // TODO(emilio): If rust ever gains f128 we should
216246 // use it here and below.
217247 _ => super :: integer_type ( ctx, layout)
218- . unwrap_or ( quote ! { f64 } ) ,
248+ . unwrap_or ( syn :: parse_quote ! { f64 } ) ,
219249 }
220250 }
221251 None => {
222252 debug_assert ! (
223253 false ,
224254 "How didn't we know the layout for a primitive type?"
225255 ) ;
226- quote ! { f64 }
256+ syn :: parse_quote ! { f64 }
227257 }
228258 }
229259 }
230260 ( FloatKind :: Float128 , _) => {
231261 if ctx. options ( ) . rust_features . i128_and_u128 {
232- quote ! { u128 }
262+ syn :: parse_quote ! { u128 }
233263 } else {
234- quote ! { [ u64 ; 2 ] }
264+ syn :: parse_quote ! { [ u64 ; 2 ] }
235265 }
236266 }
237267 }
0 commit comments