Skip to content

Commit 256ea2e

Browse files
committed
Change Callbacks API.
1 parent 4b3cd6c commit 256ea2e

File tree

7 files changed

+169
-99
lines changed

7 files changed

+169
-99
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@
210210
## Changed
211211
- Remove which and lazy-static dependencies (#2809, #2817).
212212
- Generate compile-time layout tests (#2787).
213+
- `ParseCallbacks::int_macro` now takes an `i128` instead of an `i64`.
214+
- `ParseCallbacks::func_macro` was renamed to `ParseCallbacks::fn_macro` and now takes a single `FnMacroInfo` argument.
213215
## Removed
214216
## Fixed
215217
- Fix `--formatter=prettyplease` not working in `bindgen-cli` by adding `prettyplease` feature and

bindgen-integration/build.rs

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

33
use bindgen::callbacks::{
4-
DeriveInfo, IntKind, MacroParsingBehavior, ParseCallbacks,
4+
DeriveInfo, FnMacroInfo, IntKind, MacroParsingBehavior, ParseCallbacks,
55
};
66
use bindgen::{Builder, EnumVariation, Formatter};
77
use std::collections::HashSet;
@@ -27,7 +27,7 @@ impl ParseCallbacks for MacroCallback {
2727
MacroParsingBehavior::Default
2828
}
2929

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

62-
fn func_macro(&self, name: &str, value: &[&[u8]]) {
63-
match name {
62+
fn fn_macro(&self, info: &FnMacroInfo<'_>) {
63+
let args = info.args();
64+
let body = info.body();
65+
66+
match info.name() {
6467
"TESTMACRO_NONFUNCTIONAL" => {
65-
panic!("func_macro was called for a non-functional macro");
68+
panic!("fn_macro was called for a non-functional macro");
6669
}
67-
"TESTMACRO_FUNCTIONAL_NONEMPTY(TESTMACRO_INTEGER)" => {
70+
"TESTMACRO_FUNCTIONAL_NONEMPTY" => {
6871
// Spaces are inserted into the right-hand side of a functional
6972
// macro during reconstruction from the tokenization. This might
7073
// change in the future, but it is safe by the definition of a
7174
// token in C, whereas leaving the spaces out could change
7275
// tokenization.
73-
assert_eq!(value, &[b"-" as &[u8], b"TESTMACRO_INTEGER"]);
76+
assert_eq!(args, &["TESTMACRO_INTEGER"]);
77+
assert_eq!(body, &["-", "TESTMACRO_INTEGER"]);
7478
*self.seen_funcs.lock().unwrap() += 1;
7579
}
76-
"TESTMACRO_FUNCTIONAL_EMPTY(TESTMACRO_INTEGER)" => {
77-
assert_eq!(value, &[] as &[&[u8]]);
80+
"TESTMACRO_FUNCTIONAL_EMPTY" => {
81+
assert_eq!(args, &["TESTMACRO_INTEGER"]);
82+
assert_eq!(body, &[] as &[&str]);
7883
*self.seen_funcs.lock().unwrap() += 1;
7984
}
80-
"TESTMACRO_FUNCTIONAL_TOKENIZED(a,b,c,d,e)" => {
81-
assert_eq!(
82-
value,
83-
&[b"a" as &[u8], b"/", b"b", b"c", b"d", b"##", b"e"]
84-
);
85+
"TESTMACRO_FUNCTIONAL_TOKENIZED" => {
86+
assert_eq!(args, &["a", "b", "c", "d", "e"]);
87+
assert_eq!(body, &["a", "/", "b", "c", "d", "##", "e"]);
8588
*self.seen_funcs.lock().unwrap() += 1;
8689
}
87-
"TESTMACRO_FUNCTIONAL_SPLIT(a,b)" => {
88-
assert_eq!(value, &[b"b", b",", b"a"]);
90+
"TESTMACRO_FUNCTIONAL_SPLIT" => {
91+
assert_eq!(args, &["a", "b"]);
92+
assert_eq!(body, &["b", ",", "a"]);
8993
*self.seen_funcs.lock().unwrap() += 1;
9094
}
91-
"TESTMACRO_STRING_FUNC_NON_UTF8(x)" => {
92-
assert_eq!(
93-
value,
94-
&[b"(" as &[u8], b"x", b"\"\xff\xff\"", b")"]
95-
);
95+
"TESTMACRO_STRING_FUNC_NON_UTF8" => {
96+
assert_eq!(args, &["x"]);
97+
assert_eq!(body, &["(", "x", r#""\xFF\xFF""#, ")"]);
9698
*self.seen_funcs.lock().unwrap() += 1;
9799
}
98-
_ => {
100+
name => {
99101
// The system might provide lots of functional macros.
100102
// Ensure we did not miss handling one that we meant to handle.
101103
assert!(!name.starts_with("TESTMACRO_"), "name = {}", name);
@@ -145,7 +147,7 @@ impl Drop for MacroCallback {
145147
assert_eq!(
146148
*self.seen_funcs.lock().unwrap(),
147149
5,
148-
"func_macro handle was not called once for all relevant macros"
150+
"fn_macro handle was not called once for all relevant macros"
149151
);
150152
}
151153
}

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
@@ -27,82 +27,90 @@ pub trait ParseCallbacks: fmt::Debug {
2727
}
2828

2929
/// This function will be run on every macro that is identified.
30-
fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
30+
#[allow(unused_variables)]
31+
fn will_parse_macro(&self, name: &str) -> MacroParsingBehavior {
3132
MacroParsingBehavior::Default
3233
}
3334

3435
/// This function will run for every extern variable and function. The returned value determines
3536
/// the name visible in the bindings.
37+
#[allow(unused_variables)]
3638
fn generated_name_override(
3739
&self,
38-
_item_info: ItemInfo<'_>,
40+
item_info: ItemInfo<'_>,
3941
) -> Option<String> {
4042
None
4143
}
4244

4345
/// This function will run for every extern variable and function. The returned value determines
4446
/// the link name in the bindings.
47+
#[allow(unused_variables)]
4548
fn generated_link_name_override(
4649
&self,
47-
_item_info: ItemInfo<'_>,
50+
item_info: ItemInfo<'_>,
4851
) -> Option<String> {
4952
None
5053
}
5154

5255
/// The integer kind an integer macro should have, given a name and the
5356
/// value of that macro, or `None` if you want the default to be chosen.
54-
fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
57+
#[allow(unused_variables)]
58+
fn int_macro(&self, name: &str, value: i128) -> Option<IntKind> {
5559
None
5660
}
5761

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

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

7173
/// This function should return whether, given an enum variant
7274
/// name, and value, this enum variant will forcibly be a constant.
75+
#[allow(unused_variables)]
7376
fn enum_variant_behavior(
7477
&self,
75-
_enum_name: Option<&str>,
76-
_original_variant_name: &str,
77-
_variant_value: EnumVariantValue,
78+
enum_name: Option<&str>,
79+
original_variant_name: &str,
80+
variant_value: EnumVariantValue,
7881
) -> Option<EnumVariantCustomBehavior> {
7982
None
8083
}
8184

8285
/// Allows to rename an enum variant, replacing `_original_variant_name`.
86+
#[allow(unused_variables)]
8387
fn enum_variant_name(
8488
&self,
85-
_enum_name: Option<&str>,
86-
_original_variant_name: &str,
87-
_variant_value: EnumVariantValue,
89+
enum_name: Option<&str>,
90+
original_variant_name: &str,
91+
variant_value: EnumVariantValue,
8892
) -> Option<String> {
8993
None
9094
}
9195

9296
/// Allows to rename an item, replacing `_original_item_name`.
93-
fn item_name(&self, _original_item_name: &str) -> Option<String> {
97+
#[allow(unused_variables)]
98+
fn item_name(&self, original_item_name: &str) -> Option<String> {
9499
None
95100
}
96101

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

100106
/// This will be called on every file inclusion, with the full path of the included file.
101-
fn include_file(&self, _filename: &str) {}
107+
#[allow(unused_variables)]
108+
fn include_file(&self, filename: &str) {}
102109

103110
/// This will be called every time `bindgen` reads an environment variable whether it has any
104111
/// content or not.
105-
fn read_env_var(&self, _key: &str) {}
112+
#[allow(unused_variables)]
113+
fn read_env_var(&self, key: &str) {}
106114

107115
/// This will be called to determine whether a particular blocklisted type
108116
/// implements a trait or not. This will be used to implement traits on
@@ -113,10 +121,11 @@ pub trait ParseCallbacks: fmt::Debug {
113121
/// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't
114122
/// derive `_derive_trait` but can implemented it manually
115123
/// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait`
124+
#[allow(unused_variables)]
116125
fn blocklisted_type_implements_trait(
117126
&self,
118-
_name: &str,
119-
_derive_trait: DeriveTrait,
127+
name: &str,
128+
derive_trait: DeriveTrait,
120129
) -> Option<ImplementsTrait> {
121130
None
122131
}
@@ -125,22 +134,25 @@ pub trait ParseCallbacks: fmt::Debug {
125134
///
126135
/// If no additional attributes are wanted, this function should return an
127136
/// empty `Vec`.
128-
fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec<String> {
137+
#[allow(unused_variables)]
138+
fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> {
129139
vec![]
130140
}
131141

132142
/// Process a source code comment.
133-
fn process_comment(&self, _comment: &str) -> Option<String> {
143+
#[allow(unused_variables)]
144+
fn process_comment(&self, comment: &str) -> Option<String> {
134145
None
135146
}
136147

137148
/// Potentially override the visibility of a composite type field.
138149
///
139150
/// Caution: This allows overriding standard C++ visibility inferred by
140151
/// `respect_cxx_access_specs`.
152+
#[allow(unused_variables)]
141153
fn field_visibility(
142154
&self,
143-
_info: FieldInfo<'_>,
155+
info: FieldInfo<'_>,
144156
) -> Option<crate::FieldVisibilityKind> {
145157
None
146158
}
@@ -151,7 +163,8 @@ pub trait ParseCallbacks: fmt::Debug {
151163
///
152164
/// The returned string is new function name.
153165
#[cfg(feature = "experimental")]
154-
fn wrap_as_variadic_fn(&self, _name: &str) -> Option<String> {
166+
#[allow(unused_variables)]
167+
fn wrap_as_variadic_fn(&self, name: &str) -> Option<String> {
155168
None
156169
}
157170
}
@@ -206,3 +219,27 @@ pub struct FieldInfo<'a> {
206219
/// The name of the field.
207220
pub field_name: &'a str,
208221
}
222+
223+
/// A struct providing information about the function-like macro being passed to [`ParseCallbacks::fn_macro`].
224+
pub struct FnMacroInfo<'m> {
225+
pub(crate) name: &'m str,
226+
pub(crate) args: &'m [&'m str],
227+
pub(crate) body: &'m [&'m str],
228+
}
229+
230+
impl FnMacroInfo<'_> {
231+
/// The macro name.
232+
pub fn name(&self) -> &str {
233+
self.name
234+
}
235+
236+
/// The macro argument names.
237+
pub fn args(&self) -> &[&str] {
238+
self.args
239+
}
240+
241+
/// The macro body as delimited `clang` tokens.
242+
pub fn body(&self) -> &[&str] {
243+
self.body
244+
}
245+
}

bindgen/clang.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ impl Cursor {
792792
(kind == CXCursor_UnexposedAttr &&
793793
cur.tokens().iter().any(|t| {
794794
t.kind == attr.token_kind &&
795-
t.spelling() == attr.name
795+
t.spelling().to_bytes() == attr.name
796796
}))
797797
{
798798
*found_attr = true;
@@ -1040,12 +1040,9 @@ pub(crate) struct ClangToken {
10401040
}
10411041

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

10511048
/// Converts a ClangToken to a `cexpr` token if possible.
@@ -1068,7 +1065,7 @@ impl ClangToken {
10681065

10691066
Some(token::Token {
10701067
kind,
1071-
raw: self.spelling().to_vec().into_boxed_slice(),
1068+
raw: self.spelling().to_bytes().to_vec().into_boxed_slice(),
10721069
})
10731070
}
10741071
}

0 commit comments

Comments
 (0)