Skip to content

Commit e3bc2db

Browse files
committed
Change Callbacks API.
1 parent 3b5ce9c commit e3bc2db

File tree

7 files changed

+173
-101
lines changed

7 files changed

+173
-101
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,11 @@
204204
# Unreleased
205205
## Added
206206
## Changed
207+
207208
- Add target mappings for riscv64imac and riscv32imafc.
209+
- `ParseCallbacks::int_macro` now takes an `i128` instead of an `i64`.
210+
- `ParseCallbacks::func_macro` was renamed to `ParseCallbacks::fn_macro` and now takes a single `FnMacroInfo` argument.
211+
208212
## Removed
209213
## Fixed
210214
## Security
@@ -328,7 +332,7 @@ This version was skipped due to some problems on the release workflow.
328332
* The `--wrap-static-fns` option can now wrap `va_list` functions as variadic functions
329333
with the experimental `ParseCallbacks::wrap_as_variadic_fn` method.
330334
* Add target mappings for riscv32imc and riscv32imac.
331-
* Add the `ParseCallbacks::field_visibility` method to modify field visibility.
335+
* Add the `ParseCallbacks::field_visibility` method to modify field visibility.
332336

333337
## Changed
334338

@@ -352,7 +356,7 @@ This version was skipped due to some problems on the release workflow.
352356
* Compute visibility of bitfield unit based on actual field visibility: A
353357
bitfield unit field and its related functions now have their visibility
354358
determined based on the most private between the default visibility and the
355-
actual visibility of the bitfields within the unit.
359+
actual visibility of the bitfields within the unit.
356360

357361
## Removed
358362
* Remove redundant Cargo features, which were all implicit:

bindgen-integration/build.rs

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ extern crate bindgen;
22
extern crate cc;
33

44
use bindgen::callbacks::{
5-
DeriveInfo, IntKind, MacroParsingBehavior, ParseCallbacks,
5+
DeriveInfo, FnMacroInfo, IntKind, MacroParsingBehavior, ParseCallbacks,
66
};
77
use bindgen::{Builder, CargoCallbacks, EnumVariation, Formatter};
88
use std::collections::HashSet;
@@ -28,7 +28,7 @@ impl ParseCallbacks for MacroCallback {
2828
MacroParsingBehavior::Default
2929
}
3030

31-
fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
31+
fn int_macro(&self, name: &str, _value: i128) -> Option<IntKind> {
3232
match name {
3333
"TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom {
3434
name: "crate::MacroInteger",
@@ -60,43 +60,45 @@ impl ParseCallbacks for MacroCallback {
6060
}
6161
}
6262

63-
fn func_macro(&self, name: &str, value: &[&[u8]]) {
64-
match name {
63+
fn fn_macro(&self, info: &FnMacroInfo<'_>) {
64+
let args = info.args();
65+
let body = info.body();
66+
67+
match info.name() {
6568
"TESTMACRO_NONFUNCTIONAL" => {
66-
panic!("func_macro was called for a non-functional macro");
69+
panic!("fn_macro was called for a non-functional macro");
6770
}
68-
"TESTMACRO_FUNCTIONAL_NONEMPTY(TESTMACRO_INTEGER)" => {
71+
"TESTMACRO_FUNCTIONAL_NONEMPTY" => {
6972
// Spaces are inserted into the right-hand side of a functional
7073
// macro during reconstruction from the tokenization. This might
7174
// change in the future, but it is safe by the definition of a
7275
// token in C, whereas leaving the spaces out could change
7376
// tokenization.
74-
assert_eq!(value, &[b"-" as &[u8], b"TESTMACRO_INTEGER"]);
77+
assert_eq!(args, &["TESTMACRO_INTEGER"]);
78+
assert_eq!(body, &["-", "TESTMACRO_INTEGER"]);
7579
*self.seen_funcs.lock().unwrap() += 1;
7680
}
77-
"TESTMACRO_FUNCTIONAL_EMPTY(TESTMACRO_INTEGER)" => {
78-
assert_eq!(value, &[] as &[&[u8]]);
81+
"TESTMACRO_FUNCTIONAL_EMPTY" => {
82+
assert_eq!(args, &["TESTMACRO_INTEGER"]);
83+
assert_eq!(body, &[] as &[&str]);
7984
*self.seen_funcs.lock().unwrap() += 1;
8085
}
81-
"TESTMACRO_FUNCTIONAL_TOKENIZED(a,b,c,d,e)" => {
82-
assert_eq!(
83-
value,
84-
&[b"a" as &[u8], b"/", b"b", b"c", b"d", b"##", b"e"]
85-
);
86+
"TESTMACRO_FUNCTIONAL_TOKENIZED" => {
87+
assert_eq!(args, &["a", "b", "c", "d", "e"]);
88+
assert_eq!(body, &["a", "/", "b", "c", "d", "##", "e"]);
8689
*self.seen_funcs.lock().unwrap() += 1;
8790
}
88-
"TESTMACRO_FUNCTIONAL_SPLIT(a,b)" => {
89-
assert_eq!(value, &[b"b", b",", b"a"]);
91+
"TESTMACRO_FUNCTIONAL_SPLIT" => {
92+
assert_eq!(args, &["a", "b"]);
93+
assert_eq!(body, &["b", ",", "a"]);
9094
*self.seen_funcs.lock().unwrap() += 1;
9195
}
92-
"TESTMACRO_STRING_FUNC_NON_UTF8(x)" => {
93-
assert_eq!(
94-
value,
95-
&[b"(" as &[u8], b"x", b"\"\xff\xff\"", b")"]
96-
);
96+
"TESTMACRO_STRING_FUNC_NON_UTF8" => {
97+
assert_eq!(args, &["x"]);
98+
assert_eq!(body, &["(", "x", r#""\xFF\xFF""#, ")"]);
9799
*self.seen_funcs.lock().unwrap() += 1;
98100
}
99-
_ => {
101+
name => {
100102
// The system might provide lots of functional macros.
101103
// Ensure we did not miss handling one that we meant to handle.
102104
assert!(!name.starts_with("TESTMACRO_"), "name = {}", name);
@@ -146,7 +148,7 @@ impl Drop for MacroCallback {
146148
assert_eq!(
147149
*self.seen_funcs.lock().unwrap(),
148150
5,
149-
"func_macro handle was not called once for all relevant macros"
151+
"fn_macro handle was not called once for all relevant macros"
150152
);
151153
}
152154
}

bindgen-integration/cpp/Test.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
a
2121
//#define TESTMACRO_INVALID("string") // A conforming preprocessor rejects this
2222
#define TESTMACRO_STRING_EXPR ("string")
23-
#define TESTMACRO_STRING_FUNC_NON_UTF8(x) (x "ÿÿ") /* invalid UTF-8 on purpose */
23+
#define TESTMACRO_STRING_FUNC_NON_UTF8(x) (x "\xFF\xFF") /* invalid UTF-8 on purpose */
2424

2525
enum {
2626
MY_ANNOYING_MACRO =

bindgen/callbacks.rs

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,82 +32,90 @@ pub trait ParseCallbacks: fmt::Debug {
3232
}
3333

3434
/// This function will be run on every macro that is identified.
35-
fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
35+
#[allow(unused_variables)]
36+
fn will_parse_macro(&self, name: &str) -> MacroParsingBehavior {
3637
MacroParsingBehavior::Default
3738
}
3839

3940
/// This function will run for every extern variable and function. The returned value determines
4041
/// the name visible in the bindings.
42+
#[allow(unused_variables)]
4143
fn generated_name_override(
4244
&self,
43-
_item_info: ItemInfo<'_>,
45+
item_info: ItemInfo<'_>,
4446
) -> Option<String> {
4547
None
4648
}
4749

4850
/// This function will run for every extern variable and function. The returned value determines
4951
/// the link name in the bindings.
52+
#[allow(unused_variables)]
5053
fn generated_link_name_override(
5154
&self,
52-
_item_info: ItemInfo<'_>,
55+
item_info: ItemInfo<'_>,
5356
) -> Option<String> {
5457
None
5558
}
5659

5760
/// The integer kind an integer macro should have, given a name and the
5861
/// value of that macro, or `None` if you want the default to be chosen.
59-
fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
62+
#[allow(unused_variables)]
63+
fn int_macro(&self, name: &str, value: i128) -> Option<IntKind> {
6064
None
6165
}
6266

6367
/// This will be run on every string macro. The callback cannot influence the further
6468
/// treatment of the macro, but may use the value to generate additional code or configuration.
65-
fn str_macro(&self, _name: &str, _value: &[u8]) {}
69+
#[allow(unused_variables)]
70+
fn str_macro(&self, name: &str, value: &[u8]) {}
6671

6772
/// This will be run on every function-like macro. The callback cannot
6873
/// influence the further treatment of the macro, but may use the value to
6974
/// generate additional code or configuration.
70-
///
71-
/// The first parameter represents the name and argument list (including the
72-
/// parentheses) of the function-like macro. The second parameter represents
73-
/// the expansion of the macro as a sequence of tokens.
74-
fn func_macro(&self, _name: &str, _value: &[&[u8]]) {}
75+
#[allow(unused_variables)]
76+
fn fn_macro(&self, info: &FnMacroInfo<'_>) {}
7577

7678
/// This function should return whether, given an enum variant
7779
/// name, and value, this enum variant will forcibly be a constant.
80+
#[allow(unused_variables)]
7881
fn enum_variant_behavior(
7982
&self,
80-
_enum_name: Option<&str>,
81-
_original_variant_name: &str,
82-
_variant_value: EnumVariantValue,
83+
enum_name: Option<&str>,
84+
original_variant_name: &str,
85+
variant_value: EnumVariantValue,
8386
) -> Option<EnumVariantCustomBehavior> {
8487
None
8588
}
8689

8790
/// Allows to rename an enum variant, replacing `_original_variant_name`.
91+
#[allow(unused_variables)]
8892
fn enum_variant_name(
8993
&self,
90-
_enum_name: Option<&str>,
91-
_original_variant_name: &str,
92-
_variant_value: EnumVariantValue,
94+
enum_name: Option<&str>,
95+
original_variant_name: &str,
96+
variant_value: EnumVariantValue,
9397
) -> Option<String> {
9498
None
9599
}
96100

97101
/// Allows to rename an item, replacing `_original_item_name`.
98-
fn item_name(&self, _original_item_name: &str) -> Option<String> {
102+
#[allow(unused_variables)]
103+
fn item_name(&self, original_item_name: &str) -> Option<String> {
99104
None
100105
}
101106

102107
/// This will be called on every header filename passed to (`Builder::header`)[`crate::Builder::header`].
103-
fn header_file(&self, _filename: &str) {}
108+
#[allow(unused_variables)]
109+
fn header_file(&self, filename: &str) {}
104110

105111
/// This will be called on every file inclusion, with the full path of the included file.
106-
fn include_file(&self, _filename: &str) {}
112+
#[allow(unused_variables)]
113+
fn include_file(&self, filename: &str) {}
107114

108115
/// This will be called every time `bindgen` reads an environment variable whether it has any
109116
/// content or not.
110-
fn read_env_var(&self, _key: &str) {}
117+
#[allow(unused_variables)]
118+
fn read_env_var(&self, key: &str) {}
111119

112120
/// This will be called to determine whether a particular blocklisted type
113121
/// implements a trait or not. This will be used to implement traits on
@@ -118,10 +126,11 @@ pub trait ParseCallbacks: fmt::Debug {
118126
/// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't
119127
/// derive `_derive_trait` but can implemented it manually
120128
/// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait`
129+
#[allow(unused_variables)]
121130
fn blocklisted_type_implements_trait(
122131
&self,
123-
_name: &str,
124-
_derive_trait: DeriveTrait,
132+
name: &str,
133+
derive_trait: DeriveTrait,
125134
) -> Option<ImplementsTrait> {
126135
None
127136
}
@@ -130,22 +139,25 @@ pub trait ParseCallbacks: fmt::Debug {
130139
///
131140
/// If no additional attributes are wanted, this function should return an
132141
/// empty `Vec`.
133-
fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec<String> {
142+
#[allow(unused_variables)]
143+
fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> {
134144
vec![]
135145
}
136146

137147
/// Process a source code comment.
138-
fn process_comment(&self, _comment: &str) -> Option<String> {
148+
#[allow(unused_variables)]
149+
fn process_comment(&self, comment: &str) -> Option<String> {
139150
None
140151
}
141152

142153
/// Potentially override the visibility of a composite type field.
143154
///
144155
/// Caution: This allows overriding standard C++ visibility inferred by
145156
/// `respect_cxx_access_specs`.
157+
#[allow(unused_variables)]
146158
fn field_visibility(
147159
&self,
148-
_info: FieldInfo<'_>,
160+
info: FieldInfo<'_>,
149161
) -> Option<crate::FieldVisibilityKind> {
150162
None
151163
}
@@ -156,7 +168,8 @@ pub trait ParseCallbacks: fmt::Debug {
156168
///
157169
/// The returned string is new function name.
158170
#[cfg(feature = "experimental")]
159-
fn wrap_as_variadic_fn(&self, _name: &str) -> Option<String> {
171+
#[allow(unused_variables)]
172+
fn wrap_as_variadic_fn(&self, name: &str) -> Option<String> {
160173
None
161174
}
162175
}
@@ -211,3 +224,27 @@ pub struct FieldInfo<'a> {
211224
/// The name of the field.
212225
pub field_name: &'a str,
213226
}
227+
228+
/// A struct providing information about the function-like macro being passed to [`ParseCallbacks::fn_macro`].
229+
pub struct FnMacroInfo<'m> {
230+
pub(crate) name: &'m str,
231+
pub(crate) args: &'m [&'m str],
232+
pub(crate) body: &'m [&'m str],
233+
}
234+
235+
impl FnMacroInfo<'_> {
236+
/// The macro name.
237+
pub fn name(&self) -> &str {
238+
self.name
239+
}
240+
241+
/// The macro argument names.
242+
pub fn args(&self) -> &[&str] {
243+
self.args
244+
}
245+
246+
/// The macro body as delimited `clang` tokens.
247+
pub fn body(&self) -> &[&str] {
248+
self.body
249+
}
250+
}

bindgen/clang.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,7 @@ impl Cursor {
790790
(kind == CXCursor_UnexposedAttr &&
791791
cur.tokens().iter().any(|t| {
792792
t.kind == attr.token_kind &&
793-
t.spelling() == attr.name
793+
t.spelling().to_bytes() == attr.name
794794
}))
795795
{
796796
*found_attr = true;
@@ -1038,12 +1038,9 @@ pub(crate) struct ClangToken {
10381038
}
10391039

10401040
impl ClangToken {
1041-
/// Get the token spelling, without being converted to utf-8.
1042-
pub(crate) fn spelling(&self) -> &[u8] {
1043-
let c_str = unsafe {
1044-
CStr::from_ptr(clang_getCString(self.spelling) as *const _)
1045-
};
1046-
c_str.to_bytes()
1041+
/// Returns the token spelling.
1042+
pub(crate) fn spelling(&self) -> &CStr {
1043+
unsafe { CStr::from_ptr(clang_getCString(self.spelling) as *const _) }
10471044
}
10481045

10491046
/// Converts a ClangToken to a `cexpr` token if possible.
@@ -1066,7 +1063,7 @@ impl ClangToken {
10661063

10671064
Some(token::Token {
10681065
kind,
1069-
raw: self.spelling().to_vec().into_boxed_slice(),
1066+
raw: self.spelling().to_bytes().to_vec().into_boxed_slice(),
10701067
})
10711068
}
10721069
}

0 commit comments

Comments
 (0)