summaryrefslogtreecommitdiff
path: root/src/codegen/helpers.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-11-23 04:31:10 -0600
committerGitHub <noreply@github.com>2017-11-23 04:31:10 -0600
commit7c3584d7bc328a01ae5352e191f1fd41bb7fb1a9 (patch)
treeace279bfdbd625d446074c01b958d7b4d44c729a /src/codegen/helpers.rs
parente3e6c730393f97daae93c2394d4af7bc9a5183b4 (diff)
parentf0e05310b43e88e541ed011d20994c02fdcc1a3a (diff)
Auto merge of #1158 - glyn:large-bitfield-units, r=emilio
Support bitfield allocation units larger than 64 bits Individual bitfields are still limited to at most 64 bits, but this restriction can be weakened when Rust supports `u128`. This implements issue #816. Usage notes: * Since common code is added to each generated binding, a program which uses more than one binding may need to work around the duplication by including each binding in its own module. * The values created by bitfield allocation unit constructors can be assigned directly to the corresponding struct fields with no need for transmutation. Implementation notes: `__BindgenBitfieldUnit` represents a bitfield allocation unit using a `Storage` type accessible as a slice of `u8`. The alignment of the unit is inherited from an `Align` type by virtue of the field: ``` align: [Align; 0], ``` The position of this field in the struct is irrelevant. It is assumed that the alignment of the `Storage` type is no larger than the alignment of the `Align` type, which will be true if the `Storage` type is, for example, an array of `u8`. This assumption is checked in a debug assertion. Although the double underscore (__) prefix is reserved for implementations of C++, there are precedents for this convention elsewhere in bindgen and so the convention is adopted here too. Acknowledgement: Thanks to @fitzgen for an initial implementation of `__BindgenBitfieldUnit` and code to integrate it into bindgen. r? @emilio
Diffstat (limited to 'src/codegen/helpers.rs')
-rw-r--r--src/codegen/helpers.rs42
1 files changed, 35 insertions, 7 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs
index 4ff398c4..99054305 100644
--- a/src/codegen/helpers.rs
+++ b/src/codegen/helpers.rs
@@ -1,7 +1,9 @@
//! Helpers for code generation that don't need macro expansion.
+use ir::context::BindgenContext;
use ir::layout::Layout;
use quote;
+use std::mem;
pub mod attributes {
use quote;
@@ -86,6 +88,39 @@ pub fn blob(layout: Layout) -> quote::Tokens {
}
}
+/// Integer type of the same size as the given `Layout`.
+pub fn integer_type(layout: Layout) -> Option<quote::Tokens> {
+ // This guard can be weakened when Rust implements u128.
+ if layout.size > mem::size_of::<u64>() {
+ None
+ } else {
+ Some(blob(layout))
+ }
+}
+
+/// Generates a bitfield allocation unit type for a type with the given `Layout`.
+pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
+ let mut tokens = quote! {};
+
+ if ctx.options().enable_cxx_namespaces {
+ tokens.append(quote! { root:: });
+ }
+
+ let align = match layout.align {
+ n if n >= 8 => quote! { u64 },
+ 4 => quote! { u32 },
+ 2 => quote! { u16 },
+ _ => quote! { u8 },
+ };
+
+ let size = layout.size;
+ tokens.append(quote! {
+ __BindgenBitfieldUnit<[u8; #size], #align>
+ });
+
+ tokens
+}
+
pub mod ast_ty {
use ir::context::BindgenContext;
use ir::function::FunctionSig;
@@ -143,13 +178,6 @@ pub mod ast_ty {
tokens
}
- /// Returns hex representation of the given value.
- pub fn hex_expr(val: u64) -> quote::Tokens {
- let mut tokens = quote! {};
- tokens.append(format!("{:#x}", val));
- tokens
- }
-
pub fn byte_array_expr(bytes: &[u8]) -> quote::Tokens {
let mut bytes: Vec<_> = bytes.iter().cloned().collect();
bytes.push(0);