summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/var.rs54
-rw-r--r--src/lib.rs14
-rw-r--r--src/options.rs7
-rw-r--r--tests/expectations/tests/default-macro-constant-type-signed.rs12
-rw-r--r--tests/expectations/tests/default-macro-constant-type-unsigned.rs12
-rw-r--r--tests/expectations/tests/default-macro-constant-type.rs12
-rw-r--r--tests/expectations/tests/fit-macro-constant-types.rs54
-rw-r--r--tests/headers/default-macro-constant-type.h18
-rw-r--r--tests/headers/fit-macro-constant-types.h4
9 files changed, 176 insertions, 11 deletions
diff --git a/src/ir/var.rs b/src/ir/var.rs
index c6f121d7..64f15703 100644
--- a/src/ir/var.rs
+++ b/src/ir/var.rs
@@ -117,21 +117,53 @@ impl DotAttributes for Var {
}
}
-// TODO(emilio): we could make this more (or less) granular, I guess.
fn default_macro_constant_type(ctx: &BindgenContext, value: i64) -> IntKind {
- if value < 0 ||
- ctx.options().default_macro_constant_type ==
- MacroTypeVariation::Signed
- {
- if value < i32::min_value() as i64 || value > i32::max_value() as i64 {
- IntKind::I64
+ if ctx.options().fit_macro_constants {
+ if value < 0 ||
+ ctx.options().default_macro_constant_type ==
+ MacroTypeVariation::Signed
+ {
+ if value < i32::min_value() as i64 ||
+ value > i32::max_value() as i64
+ {
+ IntKind::I64
+ } else if value < i16::min_value() as i64 ||
+ value > i16::max_value() as i64
+ {
+ IntKind::I32
+ } else if value < i8::min_value() as i64 ||
+ value > i8::max_value() as i64
+ {
+ IntKind::I16
+ } else {
+ IntKind::I8
+ }
+ } else if value > u32::max_value() as i64 {
+ IntKind::U64
+ } else if value > u16::max_value() as i64 {
+ IntKind::U32
+ } else if value > u8::max_value() as i64 {
+ IntKind::U16
} else {
- IntKind::I32
+ IntKind::U8
}
- } else if value > u32::max_value() as i64 {
- IntKind::U64
} else {
- IntKind::U32
+ if value < 0 ||
+ ctx.options().default_macro_constant_type ==
+ MacroTypeVariation::Signed
+ {
+ if value < i32::min_value() as i64 ||
+ value > i32::max_value() as i64
+ {
+ IntKind::I64
+ } else {
+ IntKind::I32
+ }
+ } else if value > u32::max_value() as i64 {
+ IntKind::U64
+ } else {
+ IntKind::U32
+ }
}
}
diff --git a/src/lib.rs b/src/lib.rs
index ce0d5d4d..b9e1bcc5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -478,6 +478,10 @@ impl Builder {
output_vector.push("--no-prepend-enum-name".into());
}
+ if self.options.fit_macro_constants {
+ output_vector.push("--fit-macro-constant-types".into());
+ }
+
if self.options.array_pointers_in_arguments {
output_vector.push("--use-array-pointers-in-arguments".into());
}
@@ -1287,6 +1291,12 @@ impl Builder {
self
}
+ /// Whether to try to fit macro constants to types smaller than u32/i32
+ pub fn fit_macro_constants(mut self, doit: bool) -> Self {
+ self.options.fit_macro_constants = doit;
+ self
+ }
+
/// Prepend the enum name to constant or newtype variants.
pub fn prepend_enum_name(mut self, doit: bool) -> Self {
self.options.prepend_enum_name = doit;
@@ -1735,6 +1745,9 @@ struct BindgenOptions {
/// Whether to detect include paths using clang_sys.
detect_include_paths: bool,
+ /// Whether to try to fit macro constants into types smaller than u32/i32
+ fit_macro_constants: bool,
+
/// Whether to prepend the enum name to constant or newtype variants.
prepend_enum_name: bool,
@@ -1905,6 +1918,7 @@ impl Default for BindgenOptions {
block_extern_crate: false,
enable_mangling: true,
detect_include_paths: true,
+ fit_macro_constants: false,
prepend_enum_name: true,
time_phases: false,
record_matches: true,
diff --git a/src/options.rs b/src/options.rs
index 8beac469..7d3e077e 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -316,6 +316,9 @@ where
Arg::with_name("no-include-path-detection")
.long("no-include-path-detection")
.help("Do not try to detect default include paths"),
+ Arg::with_name("fit-macro-constant-types")
+ .long("fit-macro-constant-types")
+ .help("Try to fit macro constants into types smaller than u32/i32"),
Arg::with_name("unstable-rust")
.long("unstable-rust")
.help("Generate unstable Rust code (deprecated; use --rust-target instead).")
@@ -654,6 +657,10 @@ where
builder = builder.detect_include_paths(false);
}
+ if matches.is_present("fit-macro-constant-types") {
+ builder = builder.fit_macro_constants(true);
+ }
+
if matches.is_present("time-phases") {
builder = builder.time_phases(true);
}
diff --git a/tests/expectations/tests/default-macro-constant-type-signed.rs b/tests/expectations/tests/default-macro-constant-type-signed.rs
index eda3117d..38ebc531 100644
--- a/tests/expectations/tests/default-macro-constant-type-signed.rs
+++ b/tests/expectations/tests/default-macro-constant-type-signed.rs
@@ -10,6 +10,18 @@ pub const N1: i32 = 1;
pub const N2: i32 = 2;
pub const N_1: i32 = -1;
pub const N_2: i32 = -2;
+pub const MAX_U16: i32 = 65535;
+pub const MAX_I16: i32 = 32767;
+pub const MAX_I16_Plus1: i32 = 32768;
+pub const MAX_U16_Plus1: i32 = 65536;
+pub const MAX_I16_Minus1: i32 = 32766;
+pub const MAX_U16_Minus1: i32 = 65534;
+pub const MIN_U16: i32 = 0;
+pub const MIN_I16: i32 = -32768;
+pub const MIN_U16_Plus1: i32 = 1;
+pub const MIN_I16_Plus1: i32 = -32767;
+pub const MIN_U16_Minus1: i32 = -1;
+pub const MIN_I16_Minus1: i32 = -32769;
pub const MAX_U32: i64 = 4294967295;
pub const MAX_I32: i32 = 2147483647;
pub const MAX_I32_Plus1: i64 = 2147483648;
diff --git a/tests/expectations/tests/default-macro-constant-type-unsigned.rs b/tests/expectations/tests/default-macro-constant-type-unsigned.rs
index 241443aa..5571563b 100644
--- a/tests/expectations/tests/default-macro-constant-type-unsigned.rs
+++ b/tests/expectations/tests/default-macro-constant-type-unsigned.rs
@@ -10,6 +10,18 @@ pub const N1: u32 = 1;
pub const N2: u32 = 2;
pub const N_1: i32 = -1;
pub const N_2: i32 = -2;
+pub const MAX_U16: u32 = 65535;
+pub const MAX_I16: u32 = 32767;
+pub const MAX_I16_Plus1: u32 = 32768;
+pub const MAX_U16_Plus1: u32 = 65536;
+pub const MAX_I16_Minus1: u32 = 32766;
+pub const MAX_U16_Minus1: u32 = 65534;
+pub const MIN_U16: u32 = 0;
+pub const MIN_I16: i32 = -32768;
+pub const MIN_U16_Plus1: u32 = 1;
+pub const MIN_I16_Plus1: i32 = -32767;
+pub const MIN_U16_Minus1: i32 = -1;
+pub const MIN_I16_Minus1: i32 = -32769;
pub const MAX_U32: u32 = 4294967295;
pub const MAX_I32: u32 = 2147483647;
pub const MAX_I32_Plus1: u32 = 2147483648;
diff --git a/tests/expectations/tests/default-macro-constant-type.rs b/tests/expectations/tests/default-macro-constant-type.rs
index 241443aa..5571563b 100644
--- a/tests/expectations/tests/default-macro-constant-type.rs
+++ b/tests/expectations/tests/default-macro-constant-type.rs
@@ -10,6 +10,18 @@ pub const N1: u32 = 1;
pub const N2: u32 = 2;
pub const N_1: i32 = -1;
pub const N_2: i32 = -2;
+pub const MAX_U16: u32 = 65535;
+pub const MAX_I16: u32 = 32767;
+pub const MAX_I16_Plus1: u32 = 32768;
+pub const MAX_U16_Plus1: u32 = 65536;
+pub const MAX_I16_Minus1: u32 = 32766;
+pub const MAX_U16_Minus1: u32 = 65534;
+pub const MIN_U16: u32 = 0;
+pub const MIN_I16: i32 = -32768;
+pub const MIN_U16_Plus1: u32 = 1;
+pub const MIN_I16_Plus1: i32 = -32767;
+pub const MIN_U16_Minus1: i32 = -1;
+pub const MIN_I16_Minus1: i32 = -32769;
pub const MAX_U32: u32 = 4294967295;
pub const MAX_I32: u32 = 2147483647;
pub const MAX_I32_Plus1: u32 = 2147483648;
diff --git a/tests/expectations/tests/fit-macro-constant-types.rs b/tests/expectations/tests/fit-macro-constant-types.rs
new file mode 100644
index 00000000..d8d3f207
--- /dev/null
+++ b/tests/expectations/tests/fit-macro-constant-types.rs
@@ -0,0 +1,54 @@
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+pub const N0: u8 = 0;
+pub const N1: u8 = 1;
+pub const N2: u8 = 2;
+pub const N_1: i8 = -1;
+pub const N_2: i8 = -2;
+pub const MAX_U16: u16 = 65535;
+pub const MAX_I16: u16 = 32767;
+pub const MAX_I16_Plus1: u16 = 32768;
+pub const MAX_U16_Plus1: u32 = 65536;
+pub const MAX_I16_Minus1: u16 = 32766;
+pub const MAX_U16_Minus1: u16 = 65534;
+pub const MIN_U16: u8 = 0;
+pub const MIN_I16: i16 = -32768;
+pub const MIN_U16_Plus1: u8 = 1;
+pub const MIN_I16_Plus1: i16 = -32767;
+pub const MIN_U16_Minus1: i8 = -1;
+pub const MIN_I16_Minus1: i32 = -32769;
+pub const MAX_U32: u32 = 4294967295;
+pub const MAX_I32: u32 = 2147483647;
+pub const MAX_I32_Plus1: u32 = 2147483648;
+pub const MAX_U32_Plus1: u64 = 4294967296;
+pub const MAX_I32_Minus1: u32 = 2147483646;
+pub const MAX_U32_Minus1: u32 = 4294967294;
+pub const MIN_U32: u8 = 0;
+pub const MIN_I32: i32 = -2147483648;
+pub const MIN_U32_Plus1: u8 = 1;
+pub const MIN_I32_Plus1: i32 = -2147483647;
+pub const MIN_U32_Minus1: i8 = -1;
+pub const MIN_I32_Minus1: i64 = -2147483649;
+pub const LONG12: u64 = 123456789012;
+pub const LONG_12: i64 = -123456789012;
+extern "C" {
+ pub fn foo(
+ arg1: ::std::os::raw::c_int,
+ arg2: ::std::os::raw::c_int,
+ arg3: ::std::os::raw::c_uint,
+ arg4: ::std::os::raw::c_char,
+ arg5: ::std::os::raw::c_uchar,
+ arg6: ::std::os::raw::c_schar,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn bar(
+ arg1: ::std::os::raw::c_long,
+ arg2: ::std::os::raw::c_longlong,
+ ) -> ::std::os::raw::c_long;
+}
diff --git a/tests/headers/default-macro-constant-type.h b/tests/headers/default-macro-constant-type.h
index d11941b4..a863362c 100644
--- a/tests/headers/default-macro-constant-type.h
+++ b/tests/headers/default-macro-constant-type.h
@@ -8,6 +8,24 @@
#define N_1 (-1LL)
#define N_2 (-2LL)
+#define MAX_U16 0xFFFFULL
+#define MAX_I16 (0x8000ULL - 1)
+
+#define MAX_I16_Plus1 (MAX_I16 + 1)
+#define MAX_U16_Plus1 (MAX_U16 + 1)
+
+#define MAX_I16_Minus1 (MAX_I16 - 1)
+#define MAX_U16_Minus1 (MAX_U16 - 1)
+
+#define MIN_U16 0
+#define MIN_I16 (- (1ULL<<15))
+
+#define MIN_U16_Plus1 (MIN_U16 + 1)
+#define MIN_I16_Plus1 (MIN_I16 + 1)
+
+#define MIN_U16_Minus1 (MIN_U16 - 1)
+#define MIN_I16_Minus1 (MIN_I16 - 1)
+
#define MAX_U32 0xFFFFFFFFULL
#define MAX_I32 (0x80000000ULL - 1)
diff --git a/tests/headers/fit-macro-constant-types.h b/tests/headers/fit-macro-constant-types.h
new file mode 100644
index 00000000..b995bfc0
--- /dev/null
+++ b/tests/headers/fit-macro-constant-types.h
@@ -0,0 +1,4 @@
+// bindgen-flags: --fit-macro-constant-types
+// Test fitting macro constants into smaller integer types
+// Negative values are i8, i16, i32 or i64; others are u8, u16, u32 or u64.
+#include "default-macro-constant-type.h" \ No newline at end of file