Skip to content

Commit 8fa42ef

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

File tree

6 files changed

+94
-17
lines changed

6 files changed

+94
-17
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
@@ -1453,8 +1453,19 @@ impl ToRustTy for Type {
14531453
IntKind::ULong => raw!(c_ulong),
14541454
IntKind::LongLong => raw!(c_longlong),
14551455
IntKind::ULongLong => raw!(c_ulonglong),
1456+
1457+
IntKind::I8 => aster::ty::TyBuilder::new().i8(),
1458+
IntKind::U8 => aster::ty::TyBuilder::new().u8(),
1459+
IntKind::I16 => aster::ty::TyBuilder::new().i16(),
14561460
IntKind::U16 => aster::ty::TyBuilder::new().u16(),
1461+
IntKind::I32 => aster::ty::TyBuilder::new().i32(),
14571462
IntKind::U32 => aster::ty::TyBuilder::new().u32(),
1463+
IntKind::I64 => aster::ty::TyBuilder::new().i64(),
1464+
IntKind::U64 => aster::ty::TyBuilder::new().u64(),
1465+
IntKind::Custom(name, _signed) => {
1466+
let ident = ctx.rust_ident_raw(name);
1467+
quote_ty!(ctx.ext_cx(), $ident)
1468+
}
14581469
// FIXME: This doesn't generate the proper alignment, but we
14591470
// can't do better right now. We should be able to use
14601471
// i128/u128 when they're available.

src/ir/context.rs

+2-2
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;
@@ -245,7 +245,7 @@ impl<'ctx> BindgenContext<'ctx> {
245245

246246
/// Returns a mangled name as a rust identifier.
247247
pub fn rust_ident_raw(&self, name: &str) -> Ident {
248-
self.ext_cx().ident_of(name.borrow())
248+
self.ext_cx().ident_of(name)
249249
}
250250

251251
/// 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

@@ -229,6 +231,13 @@ impl Builder {
229231
self
230232
}
231233

234+
/// Allows configuring types in different situations, see the `TypeChooser`
235+
/// documentation.
236+
pub fn type_chooser(mut self, cb: Box<chooser::TypeChooser>) -> Self {
237+
self.options.type_chooser = Some(cb);
238+
self
239+
}
240+
232241
/// Generate the Rust bindings using the options built up thus far.
233242
pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> {
234243
Bindings::generate(self.options, None)
@@ -320,6 +329,10 @@ pub struct BindgenOptions {
320329
/// Generate a dummy C/C++ file that includes the header and has dummy uses
321330
/// of all types defined therein. See the `uses` module for more.
322331
pub dummy_uses: Option<String>,
332+
333+
/// A user-provided type chooser to allow customizing different kinds of
334+
/// situations.
335+
pub type_chooser: Option<Box<chooser::TypeChooser>>,
323336
}
324337

325338
impl Default for BindgenOptions {
@@ -347,6 +360,7 @@ impl Default for BindgenOptions {
347360
clang_args: vec![],
348361
input_header: None,
349362
dummy_uses: None,
363+
type_chooser: None,
350364
}
351365
}
352366
}

0 commit comments

Comments
 (0)