Skip to content

Commit

Permalink
Merge tag 'v0.24.3'
Browse files Browse the repository at this point in the history
v0.24.3

  * Make struct expressions correctly generated through typedefs (mozilla#768).
  • Loading branch information
mhallin committed May 25, 2024
2 parents 9a8f295 + f43ccfc commit 8ff7c56
Show file tree
Hide file tree
Showing 16 changed files with 270 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.24.3

* Make struct expressions correctly generated through typedefs (#768).

## 0.24.2

* Make bitfield operators use explicit constructors.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cbindgen"
version = "0.24.2"
version = "0.24.3"
authors = [
"Emilio Cobos Álvarez <emilio@crisal.io>",
"Jeff Muizelaar <jmuizelaar@mozilla.com>",
Expand Down
37 changes: 34 additions & 3 deletions src/bindgen/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::fs;
Expand All @@ -12,7 +13,7 @@ use std::rc::Rc;

use crate::bindgen::config::{Config, Language};
use crate::bindgen::ir::{
Constant, Function, ItemContainer, ItemMap, Path as BindgenPath, Static, Struct,
Constant, Function, ItemContainer, ItemMap, Path as BindgenPath, Static, Struct, Typedef,
};
use crate::bindgen::writer::{Source, SourceWriter};

Expand All @@ -22,6 +23,7 @@ pub struct Bindings {
/// The map from path to struct, used to lookup whether a given type is a
/// transparent struct. This is needed to generate code for constants.
struct_map: ItemMap<Struct>,
typedef_map: ItemMap<Typedef>,
struct_fileds_memo: RefCell<HashMap<BindgenPath, Rc<Vec<String>>>>,
globals: Vec<Static>,
constants: Vec<Constant>,
Expand All @@ -39,9 +41,11 @@ enum NamespaceOperation {
}

impl Bindings {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
config: Config,
struct_map: ItemMap<Struct>,
typedef_map: ItemMap<Typedef>,
constants: Vec<Constant>,
globals: Vec<Static>,
items: Vec<ItemContainer>,
Expand All @@ -51,6 +55,7 @@ impl Bindings {
Bindings {
config,
struct_map,
typedef_map,
struct_fileds_memo: Default::default(),
globals,
constants,
Expand All @@ -67,9 +72,30 @@ impl Bindings {
any
}

/// Peels through typedefs to allow resolving structs.
fn resolved_struct_path<'a>(&self, path: &'a BindgenPath) -> Cow<'a, BindgenPath> {
use crate::bindgen::ir::Type;

let mut resolved_path = Cow::Borrowed(path);
loop {
let mut found = None;
self.typedef_map.for_items(&resolved_path, |item| {
if let Type::Path(ref p) = item.aliased {
found = Some(p.path().clone());
}
});
resolved_path = match found {
Some(p) => Cow::Owned(p),
None => break,
}
}
resolved_path
}

pub fn struct_exists(&self, path: &BindgenPath) -> bool {
let mut any = false;
self.struct_map.for_items(path, |_| any = true);
self.struct_map
.for_items(&self.resolved_struct_path(path), |_| any = true);
any
}

Expand All @@ -79,8 +105,10 @@ impl Bindings {
return memo.clone();
}

let resolved_path = self.resolved_struct_path(path);

let mut fields = Vec::<String>::new();
self.struct_map.for_items(path, |st| {
self.struct_map.for_items(&resolved_path, |st| {
let mut pos: usize = 0;
for field in &st.fields {
if let Some(found_pos) = fields.iter().position(|v| *v == field.name) {
Expand All @@ -94,6 +122,9 @@ impl Bindings {

let fields = Rc::new(fields);
memos.insert(path.clone(), fields.clone());
if let Cow::Owned(p) = resolved_path {
memos.insert(p, fields.clone());
}
fields
}

Expand Down
9 changes: 7 additions & 2 deletions src/bindgen/ir/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ impl Struct {
out,
"return {} {{ static_cast<decltype(bits)>(this->bits {} {}.bits) }};",
self.export_name(),
operator, other
operator,
other
);
out.close_brace(false);

Expand Down Expand Up @@ -566,7 +567,11 @@ impl Source for Struct {
self.export_name()
);
out.open_brace();
write!(out, "return {} {{ static_cast<decltype(bits)>(~bits) }};", self.export_name());
write!(
out,
"return {} {{ static_cast<decltype(bits)>(~bits) }};",
self.export_name()
);
out.close_brace(false);
self.emit_bitflags_binop(constexpr_prefix, '|', &other, out);
self.emit_bitflags_binop(constexpr_prefix, '&', &other, out);
Expand Down
2 changes: 2 additions & 0 deletions src/bindgen/library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl Library {
Default::default(),
Default::default(),
Default::default(),
Default::default(),
true,
));
}
Expand Down Expand Up @@ -147,6 +148,7 @@ impl Library {
Ok(Bindings::new(
self.config,
self.structs,
self.typedefs,
constants,
globals,
items,
Expand Down
19 changes: 19 additions & 0 deletions tests/expectations/const_generics_constant.both.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#define FONT_WEIGHT_FRACTION_BITS 6

typedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS {
uint16_t value;
} FixedPoint_FONT_WEIGHT_FRACTION_BITS;

typedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

typedef struct FontWeight {
FontWeightFixedPoint _0;
} FontWeight;
#define FontWeight_NORMAL (FontWeight){ ._0 = (FontWeightFixedPoint){ .value = (400 << FONT_WEIGHT_FRACTION_BITS) } }

void root(struct FontWeight w);
27 changes: 27 additions & 0 deletions tests/expectations/const_generics_constant.both.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#define FONT_WEIGHT_FRACTION_BITS 6

typedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS {
uint16_t value;
} FixedPoint_FONT_WEIGHT_FRACTION_BITS;

typedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

typedef struct FontWeight {
FontWeightFixedPoint _0;
} FontWeight;
#define FontWeight_NORMAL (FontWeight){ ._0 = (FontWeightFixedPoint){ .value = (400 << FONT_WEIGHT_FRACTION_BITS) } }

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(struct FontWeight w);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
19 changes: 19 additions & 0 deletions tests/expectations/const_generics_constant.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#define FONT_WEIGHT_FRACTION_BITS 6

typedef struct {
uint16_t value;
} FixedPoint_FONT_WEIGHT_FRACTION_BITS;

typedef FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

typedef struct {
FontWeightFixedPoint _0;
} FontWeight;
#define FontWeight_NORMAL (FontWeight){ ._0 = (FontWeightFixedPoint){ .value = (400 << FONT_WEIGHT_FRACTION_BITS) } }

void root(FontWeight w);
27 changes: 27 additions & 0 deletions tests/expectations/const_generics_constant.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#define FONT_WEIGHT_FRACTION_BITS 6

typedef struct {
uint16_t value;
} FixedPoint_FONT_WEIGHT_FRACTION_BITS;

typedef FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

typedef struct {
FontWeightFixedPoint _0;
} FontWeight;
#define FontWeight_NORMAL (FontWeight){ ._0 = (FontWeightFixedPoint){ .value = (400 << FONT_WEIGHT_FRACTION_BITS) } }

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(FontWeight w);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
25 changes: 25 additions & 0 deletions tests/expectations/const_generics_constant.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>

constexpr static const uint16_t FONT_WEIGHT_FRACTION_BITS = 6;

template<uint16_t FRACTION_BITS>
struct FixedPoint {
uint16_t value;
};

using FontWeightFixedPoint = FixedPoint<FONT_WEIGHT_FRACTION_BITS>;

struct FontWeight {
FontWeightFixedPoint _0;
};
constexpr static const FontWeight FontWeight_NORMAL = FontWeight{ /* ._0 = */ FontWeightFixedPoint{ /* .value = */ (400 << FONT_WEIGHT_FRACTION_BITS) } };

extern "C" {

void root(FontWeight w);

} // extern "C"
20 changes: 20 additions & 0 deletions tests/expectations/const_generics_constant.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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 uint16_t FONT_WEIGHT_FRACTION_BITS # = 6

ctypedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS:
uint16_t value;

ctypedef FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

ctypedef struct FontWeight:
FontWeightFixedPoint _0;
const FontWeight FontWeight_NORMAL # = <FontWeight>{ <FontWeightFixedPoint>{ (400 << FONT_WEIGHT_FRACTION_BITS) } }

void root(FontWeight w);
19 changes: 19 additions & 0 deletions tests/expectations/const_generics_constant.tag.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#define FONT_WEIGHT_FRACTION_BITS 6

struct FixedPoint_FONT_WEIGHT_FRACTION_BITS {
uint16_t value;
};

typedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

struct FontWeight {
FontWeightFixedPoint _0;
};
#define FontWeight_NORMAL (FontWeight){ ._0 = (FontWeightFixedPoint){ .value = (400 << FONT_WEIGHT_FRACTION_BITS) } }

void root(struct FontWeight w);
27 changes: 27 additions & 0 deletions tests/expectations/const_generics_constant.tag.compat.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#define FONT_WEIGHT_FRACTION_BITS 6

struct FixedPoint_FONT_WEIGHT_FRACTION_BITS {
uint16_t value;
};

typedef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

struct FontWeight {
FontWeightFixedPoint _0;
};
#define FontWeight_NORMAL (FontWeight){ ._0 = (FontWeightFixedPoint){ .value = (400 << FONT_WEIGHT_FRACTION_BITS) } }

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(struct FontWeight w);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
20 changes: 20 additions & 0 deletions tests/expectations/const_generics_constant.tag.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
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 uint16_t FONT_WEIGHT_FRACTION_BITS # = 6

cdef struct FixedPoint_FONT_WEIGHT_FRACTION_BITS:
uint16_t value;

ctypedef FixedPoint_FONT_WEIGHT_FRACTION_BITS FontWeightFixedPoint;

cdef struct FontWeight:
FontWeightFixedPoint _0;
const FontWeight FontWeight_NORMAL # = <FontWeight>{ <FontWeightFixedPoint>{ (400 << FONT_WEIGHT_FRACTION_BITS) } }

void root(FontWeight w);
18 changes: 18 additions & 0 deletions tests/rust/const_generics_constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[repr(C)]
pub struct FixedPoint<const FRACTION_BITS: u16> {
value: u16,
}

pub const FONT_WEIGHT_FRACTION_BITS: u16 = 6;

pub type FontWeightFixedPoint = FixedPoint<FONT_WEIGHT_FRACTION_BITS>;

#[repr(C)]
pub struct FontWeight(FontWeightFixedPoint);

impl FontWeight {
pub const NORMAL: FontWeight = FontWeight(FontWeightFixedPoint { value: 400 << FONT_WEIGHT_FRACTION_BITS });
}

#[no_mangle]
pub extern "C" fn root(w: FontWeight) {}

0 comments on commit 8ff7c56

Please sign in to comment.