From e620376ea8a4bc9f54f88977c516d4530e1df45e Mon Sep 17 00:00:00 2001 From: "Nicholas R. Smith" Date: Fri, 22 Aug 2025 19:12:35 -0700 Subject: [PATCH 1/2] feat(const-config): add the ability to disable inlining of associated constants --- src/bindgen/config.rs | 3 +++ src/bindgen/ir/constant.rs | 8 +++++++- template.toml | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index e92b6547e..a0d92836b 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -714,6 +714,8 @@ pub struct ConstantConfig { pub allow_static_const: bool, /// Whether a generated constant should be constexpr in C++ mode. pub allow_constexpr: bool, + /// Whether a generated constexpr should be inlined + pub allow_inline: bool, /// Sort key for constants pub sort_by: Option, } @@ -723,6 +725,7 @@ impl Default for ConstantConfig { ConstantConfig { allow_static_const: true, allow_constexpr: true, + allow_inline: true, sort_by: None, } } diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index 50bee8292..117c420fd 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -726,7 +726,13 @@ impl Constant { } if config.constant.allow_static_const { - out.write(if in_body { "inline " } else { "static " }); + out.write(if in_body && config.constant.allow_inline { + "inline " + } else if !in_body { + "static " + } else { + "" + }); } if let Type::Ptr { is_const: true, .. } = self.ty { diff --git a/template.toml b/template.toml index ff3b32322..9ef7e0d18 100644 --- a/template.toml +++ b/template.toml @@ -129,6 +129,7 @@ private_default_tagged_enum_constructor = false [const] allow_static_const = true allow_constexpr = false +allow_inline = true # Set to 'false' if compiling before C++17 sort_by = "Name" From cdee5c9ab60e76b802e441174c480284fdd24017 Mon Sep 17 00:00:00 2001 From: "Nicholas R. Smith" Date: Fri, 22 Aug 2025 19:15:18 -0700 Subject: [PATCH 2/2] test(const-config): add test where we specifically turn off inlining in C++ code generation to support older C++ compilers --- .../no_inline_constant_constexpr.compat.c | 19 +++++++++++++++ .../no_inline_constant_constexpr.cpp | 23 +++++++++++++++++++ .../no_inline_constant_constexpr.pyx | 21 +++++++++++++++++ ...no_inline_constant_constexpr_both.compat.c | 19 +++++++++++++++ .../no_inline_constant_constexpr_tag.compat.c | 19 +++++++++++++++ .../no_inline_constant_constexpr_tag.pyx | 21 +++++++++++++++++ tests/rust/no_inline_constant_constexpr.rs | 14 +++++++++++ tests/rust/no_inline_constant_constexpr.toml | 6 +++++ 8 files changed, 142 insertions(+) create mode 100644 tests/expectations/no_inline_constant_constexpr.compat.c create mode 100644 tests/expectations/no_inline_constant_constexpr.cpp create mode 100644 tests/expectations/no_inline_constant_constexpr.pyx create mode 100644 tests/expectations/no_inline_constant_constexpr_both.compat.c create mode 100644 tests/expectations/no_inline_constant_constexpr_tag.compat.c create mode 100644 tests/expectations/no_inline_constant_constexpr_tag.pyx create mode 100644 tests/rust/no_inline_constant_constexpr.rs create mode 100644 tests/rust/no_inline_constant_constexpr.toml diff --git a/tests/expectations/no_inline_constant_constexpr.compat.c b/tests/expectations/no_inline_constant_constexpr.compat.c new file mode 100644 index 000000000..a389d0626 --- /dev/null +++ b/tests/expectations/no_inline_constant_constexpr.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +#define CONSTANT_I64 216 + +#define CONSTANT_FLOAT32 312.292 + +#define DELIMITER ':' + +#define LEFTCURLY '{' + +typedef struct { + int32_t x; +} Foo; +#define Foo_CONSTANT_I64_BODY 216 + +#define SomeFoo (Foo){ .x = 99 } diff --git a/tests/expectations/no_inline_constant_constexpr.cpp b/tests/expectations/no_inline_constant_constexpr.cpp new file mode 100644 index 000000000..76434a829 --- /dev/null +++ b/tests/expectations/no_inline_constant_constexpr.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +static const int64_t CONSTANT_I64 = 216; + +static const float CONSTANT_FLOAT32 = 312.292; + +static const uint32_t DELIMITER = ':'; + +static const uint32_t LEFTCURLY = '{'; + +struct Foo { + int32_t x; + static const int64_t CONSTANT_I64_BODY; +}; +const int64_t Foo::CONSTANT_I64_BODY = 216; + +static const Foo SomeFoo = Foo{ + /* .x = */ 99 +}; diff --git a/tests/expectations/no_inline_constant_constexpr.pyx b/tests/expectations/no_inline_constant_constexpr.pyx new file mode 100644 index 000000000..52d03fe02 --- /dev/null +++ b/tests/expectations/no_inline_constant_constexpr.pyx @@ -0,0 +1,21 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + const int64_t CONSTANT_I64 # = 216 + + const float CONSTANT_FLOAT32 # = 312.292 + + const uint32_t DELIMITER # = ':' + + const uint32_t LEFTCURLY # = '{' + + ctypedef struct Foo: + int32_t x; + const int64_t Foo_CONSTANT_I64_BODY # = 216 + + const Foo SomeFoo # = { 99 } diff --git a/tests/expectations/no_inline_constant_constexpr_both.compat.c b/tests/expectations/no_inline_constant_constexpr_both.compat.c new file mode 100644 index 000000000..77e9b4809 --- /dev/null +++ b/tests/expectations/no_inline_constant_constexpr_both.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +#define CONSTANT_I64 216 + +#define CONSTANT_FLOAT32 312.292 + +#define DELIMITER ':' + +#define LEFTCURLY '{' + +typedef struct Foo { + int32_t x; +} Foo; +#define Foo_CONSTANT_I64_BODY 216 + +#define SomeFoo (Foo){ .x = 99 } diff --git a/tests/expectations/no_inline_constant_constexpr_tag.compat.c b/tests/expectations/no_inline_constant_constexpr_tag.compat.c new file mode 100644 index 000000000..6f1fde28d --- /dev/null +++ b/tests/expectations/no_inline_constant_constexpr_tag.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +#define CONSTANT_I64 216 + +#define CONSTANT_FLOAT32 312.292 + +#define DELIMITER ':' + +#define LEFTCURLY '{' + +struct Foo { + int32_t x; +}; +#define Foo_CONSTANT_I64_BODY 216 + +#define SomeFoo (Foo){ .x = 99 } diff --git a/tests/expectations/no_inline_constant_constexpr_tag.pyx b/tests/expectations/no_inline_constant_constexpr_tag.pyx new file mode 100644 index 000000000..0d42b0b21 --- /dev/null +++ b/tests/expectations/no_inline_constant_constexpr_tag.pyx @@ -0,0 +1,21 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + const int64_t CONSTANT_I64 # = 216 + + const float CONSTANT_FLOAT32 # = 312.292 + + const uint32_t DELIMITER # = ':' + + const uint32_t LEFTCURLY # = '{' + + cdef struct Foo: + int32_t x; + const int64_t Foo_CONSTANT_I64_BODY # = 216 + + const Foo SomeFoo # = { 99 } diff --git a/tests/rust/no_inline_constant_constexpr.rs b/tests/rust/no_inline_constant_constexpr.rs new file mode 100644 index 000000000..c4d2b8cd0 --- /dev/null +++ b/tests/rust/no_inline_constant_constexpr.rs @@ -0,0 +1,14 @@ +pub const CONSTANT_I64: i64 = 216; +pub const CONSTANT_FLOAT32: f32 = 312.292; +pub const DELIMITER: char = ':'; +pub const LEFTCURLY: char = '{'; +#[repr(C)] +struct Foo { + x: i32, +} + +pub const SomeFoo: Foo = Foo { x: 99, }; + +impl Foo { + pub const CONSTANT_I64_BODY: i64 = 216; +} diff --git a/tests/rust/no_inline_constant_constexpr.toml b/tests/rust/no_inline_constant_constexpr.toml new file mode 100644 index 000000000..14ec45c2d --- /dev/null +++ b/tests/rust/no_inline_constant_constexpr.toml @@ -0,0 +1,6 @@ +[const] +allow_constexpr = false +allow_inline = false + +[struct] +associated_constants_in_body = true