Skip to content

Commit fff088d

Browse files
committed
Add a finer-grane and more generic API for choosing macro types.
1 parent 1ec3363 commit fff088d

File tree

6 files changed

+95
-20
lines changed

6 files changed

+95
-20
lines changed

src/chooser.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//! A public API for more fine-grained customization of bindgen behavior.
2+
3+
pub use ir::int::IntKind;
4+
use std::fmt;
5+
6+
/// A trait to allow configuring different kinds of types in different
7+
/// situations.
8+
pub trait TypeChooser: fmt::Debug {
9+
/// The integer kind an integer macro should have, given a name and the
10+
/// value of that macro, or `None` if you want the default to be chosen.
11+
fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
12+
None
13+
}
14+
}

src/codegen/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1446,8 +1446,19 @@ impl ToRustTy for Type {
14461446
IntKind::ULong => raw!(c_ulong),
14471447
IntKind::LongLong => raw!(c_longlong),
14481448
IntKind::ULongLong => raw!(c_ulonglong),
1449+
1450+
IntKind::I8 => aster::ty::TyBuilder::new().i8(),
1451+
IntKind::U8 => aster::ty::TyBuilder::new().u8(),
1452+
IntKind::I16 => aster::ty::TyBuilder::new().i16(),
14491453
IntKind::U16 => aster::ty::TyBuilder::new().u16(),
1454+
IntKind::I32 => aster::ty::TyBuilder::new().i32(),
14501455
IntKind::U32 => aster::ty::TyBuilder::new().u32(),
1456+
IntKind::I64 => aster::ty::TyBuilder::new().i64(),
1457+
IntKind::U64 => aster::ty::TyBuilder::new().u64(),
1458+
IntKind::Custom(name, _signed) => {
1459+
let ident = ctx.rust_ident_raw(name);
1460+
quote_ty!(ctx.ext_cx(), $ident)
1461+
}
14511462
// FIXME: This doesn't generate the proper alignment, but we
14521463
// can't do better right now. We should be able to use
14531464
// i128/u128 when they're available.

src/ir/context.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use BindgenOptions;
44
use cexpr;
55
use clang::{self, Cursor};
66
use parse::ClangItemParser;
7-
use std::borrow::{Borrow, Cow};
7+
use std::borrow::Cow;
88
use std::collections::{HashMap, hash_map};
99
use std::collections::btree_map::{self, BTreeMap};
1010
use std::fmt;
@@ -244,10 +244,8 @@ impl<'ctx> BindgenContext<'ctx> {
244244
}
245245

246246
/// Returns a mangled name as a rust identifier.
247-
pub fn rust_ident_raw<S>(&self, name: &S) -> Ident
248-
where S: Borrow<str>,
249-
{
250-
self.ext_cx().ident_of(name.borrow())
247+
pub fn rust_ident_raw(&self, name: &str) -> Ident {
248+
self.ext_cx().ident_of(name)
251249
}
252250

253251
/// Iterate over all items that have been defined.

src/ir/int.rs

+32-6
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,55 @@ pub enum IntKind {
3636
/// An `unsigned long long`.
3737
ULongLong,
3838

39+
/// A 8-bit signed integer.
40+
I8,
41+
42+
/// A 8-bit unsigned integer.
43+
U8,
44+
45+
/// A 16-bit signed integer.
46+
I16,
47+
3948
/// Either a `char16_t` or a `wchar_t`.
4049
U16,
4150

42-
/// A `char32_t`.
51+
/// A 32-bit signed integer.
52+
I32,
53+
54+
/// A 32-bit unsigned integer.
4355
U32,
4456

57+
/// A 64-bit signed integer.
58+
I64,
59+
60+
/// A 64-bit unsigned integer.
61+
U64,
62+
4563
/// An `int128_t`
4664
I128,
4765

4866
/// A `uint128_t`.
49-
U128, /* Though now we're at it we could add equivalents for the rust
50-
* types... */
67+
U128,
68+
69+
/// A custom integer type, used to allow custom macro types depending on
70+
/// range.
71+
///
72+
/// The boolean means a whether this is a signed integer type or not.
73+
Custom(&'static str, bool),
5174
}
5275

5376
impl IntKind {
5477
/// Is this integral type signed?
5578
pub fn is_signed(&self) -> bool {
5679
use self::IntKind::*;
5780
match *self {
58-
Bool | UChar | UShort | UInt | ULong | ULongLong | U16 | U32 |
59-
U128 => false,
81+
Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 |
82+
U32 | U64 | U128 => false,
83+
84+
Char | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 |
85+
I128 => true,
6086

61-
Char | Short | Int | Long | LongLong | I128 => true,
87+
Custom(_, signed) => signed,
6288
}
6389
}
6490
}

src/ir/var.rs

+21-9
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,28 @@ impl ClangSubItemParser for Var {
111111
EvalResult::Invalid => return Err(ParseError::Continue),
112112

113113
EvalResult::Int(Wrapping(value)) => {
114-
let kind = if value < 0 {
115-
if value < i32::min_value() as i64 {
116-
IntKind::LongLong
117-
} else {
118-
IntKind::Int
114+
let kind = match ctx.options().type_chooser {
115+
Some(ref chooser) => {
116+
chooser.int_macro(&name, value)
117+
}
118+
None => None,
119+
};
120+
121+
let kind = match kind {
122+
Some(kind) => kind,
123+
None => {
124+
if value < 0 {
125+
if value < i32::min_value() as i64 {
126+
IntKind::LongLong
127+
} else {
128+
IntKind::Int
129+
}
130+
} else if value > u32::max_value() as i64 {
131+
IntKind::ULongLong
132+
} else {
133+
IntKind::UInt
134+
}
119135
}
120-
} else if value > u32::max_value() as i64 {
121-
IntKind::ULongLong
122-
} else {
123-
IntKind::UInt
124136
};
125137

126138
(kind, value)

src/lib.rs

+14
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ mod parse;
6363
mod regex_set;
6464
mod uses;
6565

66+
pub mod chooser;
67+
6668
#[cfg(rustfmt)]
6769
mod codegen;
6870

@@ -211,6 +213,13 @@ impl Builder {
211213
self
212214
}
213215

216+
/// Allows configuring types in different situations, see the `TypeChooser`
217+
/// documentation.
218+
pub fn type_chooser(mut self, cb: Box<chooser::TypeChooser>) -> Self {
219+
self.options.type_chooser = Some(cb);
220+
self
221+
}
222+
214223
/// Generate the Rust bindings using the options built up thus far.
215224
pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
216225
Bindings::generate(self.options, None)
@@ -293,6 +302,10 @@ pub struct BindgenOptions {
293302
/// Generate a dummy C/C++ file that includes the header and has dummy uses
294303
/// of all types defined therein. See the `uses` module for more.
295304
pub dummy_uses: Option<String>,
305+
306+
/// A user-provided type chooser to allow customizing different kinds of
307+
/// situations.
308+
pub type_chooser: Option<Box<chooser::TypeChooser>>,
296309
}
297310

298311
impl Default for BindgenOptions {
@@ -317,6 +330,7 @@ impl Default for BindgenOptions {
317330
clang_args: vec![],
318331
input_header: None,
319332
dummy_uses: None,
333+
type_chooser: None,
320334
}
321335
}
322336
}

0 commit comments

Comments
 (0)