Skip to content

Commit cbab8a9

Browse files
committed
Use syn::Type instead of raw TokenStream.
1 parent 83f729f commit cbab8a9

File tree

8 files changed

+290
-326
lines changed

8 files changed

+290
-326
lines changed

bindgen/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ experimental = ["annotate-snippets"]
5353

5454
## The following features are for internal use and they shouldn't be used if
5555
## you're not hacking on bindgen
56-
# Features used by `bindgen-cli`
56+
# Features used by `bindgen-cli`
5757
__cli = []
58-
# Features used for CI testing
58+
# Features used for CI testing
5959
__testing_only_extra_assertions = []
6060
__testing_only_libclang_9 = []
6161
__testing_only_libclang_5 = []

bindgen/codegen/error.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ pub(crate) enum Error {
1111
/// definition that is too difficult for us to understand (like a partial
1212
/// template specialization).
1313
InstantiationOfOpaqueType,
14+
15+
/// Function ABI is not supported.
16+
UnsupportedAbi(&'static str),
1417
}
1518

1619
impl fmt::Display for Error {
@@ -23,6 +26,13 @@ impl fmt::Display for Error {
2326
"Instantiation of opaque template type or partial template \
2427
specialization"
2528
}
29+
Error::UnsupportedAbi(abi) => {
30+
return write!(
31+
f,
32+
"{} ABI isn not supported by the configured Rust target",
33+
abi
34+
)
35+
}
2636
})
2737
}
2838
}

bindgen/codegen/helpers.rs

Lines changed: 85 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
33
use crate::ir::context::BindgenContext;
44
use crate::ir::layout::Layout;
5-
use proc_macro2::{Ident, Span, TokenStream};
6-
use quote::TokenStreamExt;
75

86
pub(crate) mod attributes {
97
use proc_macro2::{Ident, Span, TokenStream};
@@ -79,7 +77,7 @@ 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
@@ -90,103 +88,136 @@ pub(crate) fn blob(ctx: &BindgenContext, layout: Layout) -> TokenStream {
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+
syn::parse_quote! { #ty_name }
10599
} else {
106-
quote! {
107-
[ #ty_name ; #data_len ]
108-
}
100+
syn::parse_quote! { [ #ty_name ; #data_len ] }
109101
}
110102
}
111103

112104
/// Integer type of the same size as the given `Layout`.
113105
pub(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

141124
pub(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+
let ty = proc_macro2::TokenStream::from_str(name).unwrap();
205+
syn::parse_quote! { #ty }
206+
}
207+
IntKind::U128 => {
208+
if ctx.options().rust_features.i128_and_u128 {
209+
syn::parse_quote! { u128 }
210+
} else {
211+
// Best effort thing, but wrong alignment
212+
// unfortunately.
213+
syn::parse_quote! { [u64; 2] }
214+
}
215+
}
216+
IntKind::I128 => {
217+
if ctx.options().rust_features.i128_and_u128 {
218+
syn::parse_quote! { i128 }
219+
} else {
220+
syn::parse_quote! { [u64; 2] }
190221
}
191222
}
192223
}
@@ -196,42 +227,42 @@ pub(crate) mod ast_ty {
196227
ctx: &BindgenContext,
197228
fk: FloatKind,
198229
layout: Option<Layout>,
199-
) -> TokenStream {
230+
) -> syn::Type {
200231
// TODO: we probably should take the type layout into account more
201232
// often?
202233
//
203234
// Also, maybe this one shouldn't be the default?
204235
match (fk, ctx.options().convert_floats) {
205-
(FloatKind::Float, true) => quote! { f32 },
206-
(FloatKind::Double, true) => quote! { f64 },
236+
(FloatKind::Float, true) => syn::parse_quote! { f32 },
237+
(FloatKind::Double, true) => syn::parse_quote! { f64 },
207238
(FloatKind::Float, false) => raw_type(ctx, "c_float"),
208239
(FloatKind::Double, false) => raw_type(ctx, "c_double"),
209240
(FloatKind::LongDouble, _) => {
210241
match layout {
211242
Some(layout) => {
212243
match layout.size {
213-
4 => quote! { f32 },
214-
8 => quote! { f64 },
244+
4 => syn::parse_quote! { f32 },
245+
8 => syn::parse_quote! { f64 },
215246
// TODO(emilio): If rust ever gains f128 we should
216247
// use it here and below.
217248
_ => super::integer_type(ctx, layout)
218-
.unwrap_or(quote! { f64 }),
249+
.unwrap_or(syn::parse_quote! { f64 }),
219250
}
220251
}
221252
None => {
222253
debug_assert!(
223254
false,
224255
"How didn't we know the layout for a primitive type?"
225256
);
226-
quote! { f64 }
257+
syn::parse_quote! { f64 }
227258
}
228259
}
229260
}
230261
(FloatKind::Float128, _) => {
231262
if ctx.options().rust_features.i128_and_u128 {
232-
quote! { u128 }
263+
syn::parse_quote! { u128 }
233264
} else {
234-
quote! { [u64; 2] }
265+
syn::parse_quote! { [u64; 2] }
235266
}
236267
}
237268
}

0 commit comments

Comments
 (0)