autocxx_bindgen/
callbacks.rs

1//! A public API for more fine-grained customization of bindgen behavior.
2
3pub use crate::ir::analysis::DeriveTrait;
4pub use crate::ir::comp::SpecialMemberKind;
5pub use crate::ir::derive::CanDerive as ImplementsTrait;
6pub use crate::ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
7pub use crate::ir::function::Visibility;
8pub use crate::ir::int::IntKind;
9pub use crate::ir::layout::Layout;
10use std::fmt;
11
12/// An enum to allow ignoring parsing of macros.
13#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
14pub enum MacroParsingBehavior {
15    /// Ignore the macro, generating no code for it, or anything that depends on
16    /// it.
17    Ignore,
18    /// The default behavior bindgen would have otherwise.
19    #[default]
20    Default,
21}
22
23/// A trait to allow configuring different kinds of types in different
24/// situations.
25pub trait ParseCallbacks: fmt::Debug {
26    #[cfg(feature = "__cli")]
27    #[doc(hidden)]
28    fn cli_args(&self) -> Vec<String> {
29        vec![]
30    }
31
32    /// This function will be run on every macro that is identified.
33    fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
34        MacroParsingBehavior::Default
35    }
36
37    /// This function will run for every extern variable and function. The returned value determines
38    /// the name visible in the bindings.
39    fn generated_name_override(
40        &self,
41        _item_info: ItemInfo<'_>,
42    ) -> Option<String> {
43        None
44    }
45
46    /// This function will run for every extern variable and function. The returned value determines
47    /// the link name in the bindings.
48    fn generated_link_name_override(
49        &self,
50        _item_info: ItemInfo<'_>,
51    ) -> Option<String> {
52        None
53    }
54
55    /// The integer kind an integer macro should have, given a name and the
56    /// value of that macro, or `None` if you want the default to be chosen.
57    fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
58        None
59    }
60
61    /// This will be run on every string macro. The callback cannot influence the further
62    /// treatment of the macro, but may use the value to generate additional code or configuration.
63    fn str_macro(&self, _name: &str, _value: &[u8]) {}
64
65    /// This will be run on every function-like macro. The callback cannot
66    /// influence the further treatment of the macro, but may use the value to
67    /// generate additional code or configuration.
68    ///
69    /// The first parameter represents the name and argument list (including the
70    /// parentheses) of the function-like macro. The second parameter represents
71    /// the expansion of the macro as a sequence of tokens.
72    fn func_macro(&self, _name: &str, _value: &[&[u8]]) {}
73
74    /// This function should return whether, given an enum variant
75    /// name, and value, this enum variant will forcibly be a constant.
76    fn enum_variant_behavior(
77        &self,
78        _enum_name: Option<&str>,
79        _original_variant_name: &str,
80        _variant_value: EnumVariantValue,
81    ) -> Option<EnumVariantCustomBehavior> {
82        None
83    }
84
85    /// Allows to rename an enum variant, replacing `_original_variant_name`.
86    fn enum_variant_name(
87        &self,
88        _enum_name: Option<&str>,
89        _original_variant_name: &str,
90        _variant_value: EnumVariantValue,
91    ) -> Option<String> {
92        None
93    }
94
95    /// Allows to rename an item, replacing `_original_item_name`.
96    fn item_name(&self, _original_item_name: &str) -> Option<String> {
97        None
98    }
99
100    /// This will be called on every header filename passed to (`Builder::header`)[`crate::Builder::header`].
101    fn header_file(&self, _filename: &str) {}
102
103    /// This will be called on every file inclusion, with the full path of the included file.
104    fn include_file(&self, _filename: &str) {}
105
106    /// This will be called every time `bindgen` reads an environment variable whether it has any
107    /// content or not.
108    fn read_env_var(&self, _key: &str) {}
109
110    /// This will be called to determine whether a particular blocklisted type
111    /// implements a trait or not. This will be used to implement traits on
112    /// other types containing the blocklisted type.
113    ///
114    /// * `None`: use the default behavior
115    /// * `Some(ImplementsTrait::Yes)`: `_name` implements `_derive_trait`
116    /// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't
117    ///   derive `_derive_trait` but can implemented it manually
118    /// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait`
119    fn blocklisted_type_implements_trait(
120        &self,
121        _name: &str,
122        _derive_trait: DeriveTrait,
123    ) -> Option<ImplementsTrait> {
124        None
125    }
126
127    /// Provide a list of custom derive attributes.
128    ///
129    /// If no additional attributes are wanted, this function should return an
130    /// empty `Vec`.
131    fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec<String> {
132        vec![]
133    }
134
135    /// Provide a list of custom attributes.
136    ///
137    /// If no additional attributes are wanted, this function should return an
138    /// empty `Vec`.
139    fn add_attributes(&self, _info: &AttributeInfo<'_>) -> Vec<String> {
140        vec![]
141    }
142
143    /// Process a source code comment.
144    fn process_comment(&self, _comment: &str) -> Option<String> {
145        None
146    }
147
148    /// Potentially override the visibility of a composite type field.
149    ///
150    /// Caution: This allows overriding standard C++ visibility inferred by
151    /// `respect_cxx_access_specs`.
152    fn field_visibility(
153        &self,
154        _info: FieldInfo<'_>,
155    ) -> Option<crate::FieldVisibilityKind> {
156        None
157    }
158
159    /// Process a function name that as exactly one `va_list` argument
160    /// to be wrapped as a variadic function with the wrapped static function
161    /// feature.
162    ///
163    /// The returned string is new function name.
164    #[cfg(feature = "experimental")]
165    fn wrap_as_variadic_fn(&self, _name: &str) -> Option<String> {
166        None
167    }
168
169    /// This will get called everytime an item (currently struct, union, and alias) is found with some information about it
170    fn new_item_found(&self, _id: DiscoveredItemId, _item: DiscoveredItem) {}
171
172    /// Where the original C++ name differs
173    fn denote_cpp_name(&self, _id: DiscoveredItemId, _original_name: Option<&str>, _namespace_mod: Option<DiscoveredItemId>) {}
174
175    /// Note that a function is a C++ virtual or pure virtual function.
176    fn denote_virtualness(&self, _id: DiscoveredItemId, _virtualness: Virtualness) {}
177
178    /// Note that a C++ function has been marked defaulted or deleted.
179    fn denote_explicit(&self, _id: DiscoveredItemId, _explicitness: Explicitness) {}
180
181    /// Note that a C++ function has been marked defaulted.
182    fn denote_special_member(&self, _id: DiscoveredItemId, _kind: SpecialMemberKind) {}
183
184    /// Note the visibility of a C++ function. Note that this is just reporting
185    /// the C++ visibility; as opposed to [`field_visibility`] this does not
186    /// allow changes.
187    fn denote_visibility(&self, _id: DiscoveredItemId, _visibility: Visibility) {}
188
189    /// Note where in the source code a given item was encountered.
190    fn denote_source_location(&self, _id: DiscoveredItemId, _location: &SourceLocation) {}
191
192    /// Notes the layout of an item.
193    fn denote_layout(&self, _id: DiscoveredItemId, _layout: &Layout) {}
194
195    /// Notes that this type does not use all the template params
196    /// which were present in C++. Sometimes those template parameters
197    /// are not useful in Rust because they don't actually impact the
198    /// data stored in the type, so bindgen drops them. But this also means
199    /// that the bindgen output does not contain full and comprehensive
200    /// output about the original nature of the C++ type, so higher level
201    /// code generators may wish to behave differently. For example,
202    /// it would not be OK to attempt to generate additional C++ code
203    /// based on this.
204    fn denote_discards_template_param(&self, _id: DiscoveredItemId) {}
205
206    // TODO add callback for ResolvedTypeRef
207}
208
209/// An identifier for a discovered item. Used to identify an aliased type (see [`DiscoveredItem::Alias`])
210#[derive(Ord, PartialOrd, PartialEq, Eq, Hash, Debug, Clone, Copy)]
211pub struct DiscoveredItemId(usize);
212
213impl DiscoveredItemId {
214    /// Constructor
215    pub fn new(value: usize) -> Self {
216        Self(value)
217    }
218}
219
220/// Struct passed to [`ParseCallbacks::new_item_found`] containing information about discovered
221/// items (struct, union, and alias)
222#[derive(Debug, Hash, Clone, Ord, PartialOrd, Eq, PartialEq)]
223pub enum DiscoveredItem {
224    /// Represents a struct with its original name in C and its generated binding name
225    Struct {
226        /// The original name (learnt from C) of the structure
227        /// Can be None if the union is anonymous.
228        original_name: Option<String>,
229
230        /// The name of the generated binding
231        final_name: String,
232    },
233
234    /// Represents a union with its original name in C and its generated binding name
235    Union {
236        /// The original name (learnt from C) of the structure.
237        /// Can be None if the union is anonymous.
238        original_name: Option<String>,
239
240        /// The name of the generated binding
241        final_name: String,
242    },
243
244    /// Represents an alias like a typedef
245    /// ```c
246    ///     typedef struct MyStruct {
247    ///         ...
248    ///     } StructAlias;
249    /// ```
250    /// Here, the name of the alias is `StructAlias` and it's an alias for `MyStruct`
251    Alias {
252        /// The name of the alias in C (`StructAlias`)
253        alias_name: String,
254
255        /// The identifier of the discovered type
256        alias_for: DiscoveredItemId,
257    },
258
259    /// Represents an enum.
260    Enum {
261        /// The final name of the generated binding
262        final_name: String,
263    },
264
265    /// A module, typically representing a C++ namespace.
266    Mod {
267        /// The final name used.
268        final_name: String,
269
270        /// The parent ID. Typically another module, indicating that C++
271        /// namespaces are in use. If it's the root module, will be None.
272        parent_id: Option<DiscoveredItemId>,
273    },
274
275    /// A function or method.
276    Function {
277        /// The final name used.
278        final_name: String,
279    },
280
281    /// A method.
282    Method {
283        /// The final name used.
284        final_name: String,
285
286        /// Type to which this method belongs.
287        parent: DiscoveredItemId,
288    }
289}
290
291/// Relevant information about a type to which new derive attributes will be added using
292/// [`ParseCallbacks::add_derives`].
293#[derive(Debug)]
294#[non_exhaustive]
295pub struct DeriveInfo<'a> {
296    /// The name of the type.
297    pub name: &'a str,
298    /// The kind of the type.
299    pub kind: TypeKind,
300}
301
302/// Relevant information about a type to which new attributes will be added using
303/// [`ParseCallbacks::add_attributes`].
304#[derive(Debug)]
305#[non_exhaustive]
306pub struct AttributeInfo<'a> {
307    /// The name of the type.
308    pub name: &'a str,
309    /// The kind of the type.
310    pub kind: TypeKind,
311}
312
313#[derive(Debug, Clone, Copy, PartialEq, Eq)]
314/// The kind of the current type.
315pub enum TypeKind {
316    /// The type is a Rust `struct`.
317    Struct,
318    /// The type is a Rust `enum`.
319    Enum,
320    /// The type is a Rust `union`.
321    Union,
322}
323
324/// A struct providing information about the item being passed to [`ParseCallbacks::generated_name_override`].
325#[non_exhaustive]
326pub struct ItemInfo<'a> {
327    /// The name of the item
328    pub name: &'a str,
329    /// The kind of item
330    pub kind: ItemKind,
331}
332
333/// An enum indicating the kind of item for an `ItemInfo`.
334#[non_exhaustive]
335pub enum ItemKind {
336    /// A Function
337    Function,
338    /// A Variable
339    Var,
340}
341
342/// Relevant information about a field for which visibility can be determined using
343/// [`ParseCallbacks::field_visibility`].
344#[derive(Debug)]
345#[non_exhaustive]
346pub struct FieldInfo<'a> {
347    /// The name of the type.
348    pub type_name: &'a str,
349    /// The name of the field.
350    pub field_name: &'a str,
351    /// The name of the type of the field.
352    pub field_type_name: Option<&'a str>,
353}
354
355/// Whether a method is virtual or pure virtual.
356#[derive(Copy, Clone, Debug, PartialEq, Eq)]
357pub enum Virtualness {
358    /// Not pure virtual.
359    Virtual,
360    /// Pure virtual.
361    PureVirtual
362}
363
364/// Whether a field is a regular lvalue reference or rvalue reference
365#[derive(Copy, Clone, Debug, PartialEq, Eq)]
366pub enum Referenceness {
367    /// Normal reference, i.e. lvalue
368    Reference,
369    /// RValue reference
370    RValueReference
371}
372
373/// Whether a C++ method has been explicitly defaulted or deleted.
374#[derive(Copy, Clone, Debug, PartialEq, Eq)]
375pub enum Explicitness {
376    /// Defaulted function, i.e. `=default`
377    Defaulted,
378    /// Deleted function, i.e. `=delete`
379    Deleted,
380}
381
382/// Location in the source code. Roughly equivalent to the same type
383/// within `clang_sys`.
384#[derive(Clone, Debug, PartialEq, Eq)]
385pub struct SourceLocation {
386    /// Line number.
387    pub line: usize,
388    /// Column number within line.
389    pub col: usize,
390    /// Byte offset within file.
391    pub byte_offset: usize,
392    /// Filename, if known.
393    pub file_name: Option<String>,
394}