Skip to content

Commit 1c2d65f

Browse files
committed
codegen: Support new-type-alias constants
Fixes #3287
1 parent 1cf0a1f commit 1c2d65f

File tree

7 files changed

+296
-34
lines changed

7 files changed

+296
-34
lines changed

bindgen-integration/build.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ fn setup_macro_test() {
251251
.blocklist_function("my_prefixed_function_to_remove")
252252
.constified_enum("my_prefixed_enum_to_be_constified")
253253
.opaque_type("my_prefixed_templated_foo<my_prefixed_baz>")
254+
.new_type_alias("MyInt")
255+
.new_type_alias("MyBool")
256+
.new_type_alias("MyFloat")
257+
.new_type_alias("MyChar")
254258
.new_type_alias("TestDeriveOnAlias")
255259
.depfile(out_rust_file_relative.display().to_string(), &out_dep_file)
256260
.generate()

bindgen-integration/cpp/Test.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,3 +246,16 @@ enum MyOrderedEnum {
246246

247247
// Used to test custom derives on new-type alias. See `test_custom_derive`.
248248
typedef int TestDeriveOnAlias;
249+
250+
// Used to test new-type alias constants. See `test_new_type_alias_const`.
251+
typedef int MyInt;
252+
const MyInt MY_INT = 5;
253+
254+
typedef bool MyBool;
255+
const MyBool MY_BOOL = true;
256+
257+
typedef float MyFloat;
258+
const MyFloat MY_FLOAT = 1.23f;
259+
260+
typedef char MyChar;
261+
const MyChar MY_CHAR = 'a';

bindgen-integration/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,11 @@ fn test_colon_define() {
355355
let gold: u32 = (1u32 << 16) | 2;
356356
assert_eq!(gold, bindings::TESTMACRO_COLON_VALUE);
357357
}
358+
359+
#[test]
360+
fn test_new_type_alias_const() {
361+
assert_eq!(bindings::MY_INT.0, 5);
362+
assert_eq!(bindings::MY_BOOL.0, true);
363+
assert_eq!(bindings::MY_FLOAT.0, 1.23f32);
364+
assert_eq!(bindings::MY_CHAR.0, b'a' as std::ffi::c_char);
365+
}

bindgen-tests/tests/expectations/tests/new-type-alias.rs

Lines changed: 214 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// bindgen-flags: --new-type-alias (Foo|Bar|Baz|Bang)
2+
3+
#include <stdint.h>
4+
#include <stdbool.h>
5+
6+
typedef uint64_t Foo;
7+
static const Foo Foo_A = 1;
8+
9+
typedef char Bar;
10+
static const Bar Bar_A = 'a';
11+
12+
typedef float Baz;
13+
static const Baz Baz_A = 3.25;
14+
15+
typedef bool Bang;
16+
static const Bang Bang_A = true;
17+
18+
// Not wrapped
19+
typedef uint64_t Boom;
20+
static const Boom Boom_A = 2;

bindgen/codegen/mod.rs

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -681,13 +681,8 @@ impl CodeGenerator for Var {
681681
let ty = var_ty.to_rust_ty_or_opaque(ctx, &());
682682

683683
if let Some(val) = self.val() {
684-
match *val {
685-
VarType::Bool(val) => {
686-
result.push(quote! {
687-
#(#attrs)*
688-
pub const #canonical_ident : #ty = #val ;
689-
});
690-
}
684+
let const_expr = match *val {
685+
VarType::Bool(val) => Some(val.to_token_stream()),
691686
VarType::Int(val) => {
692687
let int_kind = var_ty
693688
.into_resolver()
@@ -702,10 +697,7 @@ impl CodeGenerator for Var {
702697
} else {
703698
helpers::ast_ty::uint_expr(val as _)
704699
};
705-
result.push(quote! {
706-
#(#attrs)*
707-
pub const #canonical_ident : #ty = #val ;
708-
});
700+
Some(val)
709701
}
710702
VarType::String(ref bytes) => {
711703
let prefix = ctx.trait_prefix();
@@ -758,21 +750,24 @@ impl CodeGenerator for Var {
758750
pub const #canonical_ident: &#(#lifetime )*#array_ty = #bytes ;
759751
});
760752
}
753+
None
761754
}
762-
VarType::Float(f) => {
763-
if let Ok(expr) = helpers::ast_ty::float_expr(f) {
764-
result.push(quote! {
765-
#(#attrs)*
766-
pub const #canonical_ident : #ty = #expr ;
767-
});
768-
}
769-
}
770-
VarType::Char(c) => {
771-
result.push(quote! {
772-
#(#attrs)*
773-
pub const #canonical_ident : #ty = #c ;
774-
});
755+
VarType::Float(f) => helpers::ast_ty::float_expr(f).ok(),
756+
VarType::Char(c) => Some(c.to_token_stream()),
757+
};
758+
759+
if let Some(mut val) = const_expr {
760+
let var_ty_item = ctx.resolve_item(var_ty);
761+
if matches!(
762+
var_ty_item.alias_style(ctx),
763+
AliasVariation::NewType | AliasVariation::NewTypeDeref
764+
) {
765+
val = quote! { #ty(#val) };
775766
}
767+
result.push(quote! {
768+
#(#attrs)*
769+
pub const #canonical_ident : #ty = #val ;
770+
});
776771
}
777772
} else {
778773
let symbol: &str = self.link_name().unwrap_or_else(|| {
@@ -1005,15 +1000,7 @@ impl CodeGenerator for Type {
10051000
quote! {}
10061001
};
10071002

1008-
let alias_style = if ctx.options().type_alias.matches(&name) {
1009-
AliasVariation::TypeAlias
1010-
} else if ctx.options().new_type_alias.matches(&name) {
1011-
AliasVariation::NewType
1012-
} else if ctx.options().new_type_alias_deref.matches(&name) {
1013-
AliasVariation::NewTypeDeref
1014-
} else {
1015-
ctx.options().default_alias_style
1016-
};
1003+
let alias_style = item.alias_style(ctx);
10171004

10181005
// We prefer using `pub use` over `pub type` because of:
10191006
// https://github.com/rust-lang/rust/issues/26264

bindgen/ir/item.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! Bindgen's core intermediate representation type.
22
3-
use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME};
3+
use super::super::codegen::{
4+
AliasVariation, EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME,
5+
};
46
use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult};
57
use super::annotations::Annotations;
68
use super::comp::{CompKind, MethodKind};
@@ -1103,6 +1105,20 @@ impl Item {
11031105
pub(crate) fn must_use(&self, ctx: &BindgenContext) -> bool {
11041106
self.annotations().must_use_type() || ctx.must_use_type_by_name(self)
11051107
}
1108+
1109+
/// Get the alias style for this item.
1110+
pub(crate) fn alias_style(&self, ctx: &BindgenContext) -> AliasVariation {
1111+
let name = self.canonical_name(ctx);
1112+
if ctx.options().type_alias.matches(&name) {
1113+
AliasVariation::TypeAlias
1114+
} else if ctx.options().new_type_alias.matches(&name) {
1115+
AliasVariation::NewType
1116+
} else if ctx.options().new_type_alias_deref.matches(&name) {
1117+
AliasVariation::NewTypeDeref
1118+
} else {
1119+
ctx.options().default_alias_style
1120+
}
1121+
}
11061122
}
11071123

11081124
impl<T> IsOpaque for T

0 commit comments

Comments
 (0)