Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bindgen-integration/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ fn setup_macro_test() {
.blocklist_function("my_prefixed_function_to_remove")
.constified_enum("my_prefixed_enum_to_be_constified")
.opaque_type("my_prefixed_templated_foo<my_prefixed_baz>")
.new_type_alias("MyInt")
.new_type_alias("MyBool")
.new_type_alias("MyFloat")
.new_type_alias("MyChar")
.new_type_alias("TestDeriveOnAlias")
.depfile(out_rust_file_relative.display().to_string(), &out_dep_file)
.generate()
Expand Down
13 changes: 13 additions & 0 deletions bindgen-integration/cpp/Test.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,16 @@ enum MyOrderedEnum {

// Used to test custom derives on new-type alias. See `test_custom_derive`.
typedef int TestDeriveOnAlias;

// Used to test new-type alias constants. See `test_new_type_alias_const`.
typedef int MyInt;
const MyInt MY_INT = 5;

typedef bool MyBool;
const MyBool MY_BOOL = true;

typedef float MyFloat;
const MyFloat MY_FLOAT = 1.23f;

typedef char MyChar;
const MyChar MY_CHAR = 'a';
8 changes: 8 additions & 0 deletions bindgen-integration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,11 @@ fn test_colon_define() {
let gold: u32 = (1u32 << 16) | 2;
assert_eq!(gold, bindings::TESTMACRO_COLON_VALUE);
}

#[test]
fn test_new_type_alias_const() {
assert_eq!(bindings::MY_INT.0, 5);
assert_eq!(bindings::MY_BOOL.0, true);
assert_eq!(bindings::MY_FLOAT.0, 1.23f32);
assert_eq!(bindings::MY_CHAR.0, b'a' as std::ffi::c_char);
}
20 changes: 20 additions & 0 deletions bindgen-tests/tests/expectations/tests/new-type-alias.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions bindgen-tests/tests/headers/new-type-alias.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// bindgen-flags: --new-type-alias (Foo|Bar|Baz|Bang)

// Fake stdint.h and stdbool.h
typedef __UINT64_TYPE__ uint64_t;
#define bool _Bool
#define true 1

typedef uint64_t Foo;
static const Foo Foo_A = 1;

typedef char Bar;
static const Bar Bar_A = 'a';

typedef float Baz;
static const Baz Baz_A = 3.25;

typedef bool Bang;
static const Bang Bang_A = true;

// Not wrapped
typedef uint64_t Boom;
static const Boom Boom_A = 2;
53 changes: 20 additions & 33 deletions bindgen/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,13 +681,8 @@ impl CodeGenerator for Var {
let ty = var_ty.to_rust_ty_or_opaque(ctx, &());

if let Some(val) = self.val() {
match *val {
VarType::Bool(val) => {
result.push(quote! {
#(#attrs)*
pub const #canonical_ident : #ty = #val ;
});
}
let const_expr = match *val {
VarType::Bool(val) => Some(val.to_token_stream()),
VarType::Int(val) => {
let int_kind = var_ty
.into_resolver()
Expand All @@ -702,10 +697,7 @@ impl CodeGenerator for Var {
} else {
helpers::ast_ty::uint_expr(val as _)
};
result.push(quote! {
#(#attrs)*
pub const #canonical_ident : #ty = #val ;
});
Some(val)
}
VarType::String(ref bytes) => {
let prefix = ctx.trait_prefix();
Expand Down Expand Up @@ -758,21 +750,24 @@ impl CodeGenerator for Var {
pub const #canonical_ident: &#(#lifetime )*#array_ty = #bytes ;
});
}
None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth just returning instead, but alright.

}
VarType::Float(f) => {
if let Ok(expr) = helpers::ast_ty::float_expr(f) {
result.push(quote! {
#(#attrs)*
pub const #canonical_ident : #ty = #expr ;
});
}
}
VarType::Char(c) => {
result.push(quote! {
#(#attrs)*
pub const #canonical_ident : #ty = #c ;
});
VarType::Float(f) => helpers::ast_ty::float_expr(f).ok(),
VarType::Char(c) => Some(c.to_token_stream()),
};

if let Some(mut val) = const_expr {
let var_ty_item = ctx.resolve_item(var_ty);
if matches!(
var_ty_item.alias_style(ctx),
AliasVariation::NewType | AliasVariation::NewTypeDeref
) {
val = quote! { #ty(#val) };
}
result.push(quote! {
#(#attrs)*
pub const #canonical_ident : #ty = #val ;
});
}
} else {
let symbol: &str = self.link_name().unwrap_or_else(|| {
Expand Down Expand Up @@ -1005,15 +1000,7 @@ impl CodeGenerator for Type {
quote! {}
};

let alias_style = if ctx.options().type_alias.matches(&name) {
AliasVariation::TypeAlias
} else if ctx.options().new_type_alias.matches(&name) {
AliasVariation::NewType
} else if ctx.options().new_type_alias_deref.matches(&name) {
AliasVariation::NewTypeDeref
} else {
ctx.options().default_alias_style
};
let alias_style = item.alias_style(ctx);

// We prefer using `pub use` over `pub type` because of:
// https://github.com/rust-lang/rust/issues/26264
Expand Down
18 changes: 17 additions & 1 deletion bindgen/ir/item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Bindgen's core intermediate representation type.
use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME};
use super::super::codegen::{
AliasVariation, EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME,
};
use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult};
use super::annotations::Annotations;
use super::comp::{CompKind, MethodKind};
Expand Down Expand Up @@ -1103,6 +1105,20 @@ impl Item {
pub(crate) fn must_use(&self, ctx: &BindgenContext) -> bool {
self.annotations().must_use_type() || ctx.must_use_type_by_name(self)
}

/// Get the alias style for this item.
pub(crate) fn alias_style(&self, ctx: &BindgenContext) -> AliasVariation {
let name = self.canonical_name(ctx);
if ctx.options().type_alias.matches(&name) {
AliasVariation::TypeAlias
} else if ctx.options().new_type_alias.matches(&name) {
AliasVariation::NewType
} else if ctx.options().new_type_alias_deref.matches(&name) {
AliasVariation::NewTypeDeref
} else {
ctx.options().default_alias_style
}
}
}

impl<T> IsOpaque for T
Expand Down