Skip to content

Commit eb18bd6

Browse files
committed
add callback to add attributes based on comments
1 parent c41b3a9 commit eb18bd6

File tree

4 files changed

+214
-14
lines changed

4 files changed

+214
-14
lines changed

bindgen/callbacks.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub use crate::ir::analysis::DeriveTrait;
44
pub use crate::ir::derive::CanDerive as ImplementsTrait;
55
pub use crate::ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
66
pub use crate::ir::int::IntKind;
7+
use crate::CodeGenAttributes;
78
use std::fmt;
89

910
/// An enum to allow ignoring parsing of macros.
@@ -142,6 +143,14 @@ pub trait ParseCallbacks: fmt::Debug {
142143
None
143144
}
144145

146+
/// Add attributes based on documentation comments
147+
fn parse_comments_for_attributes(
148+
&self,
149+
_comment: &str,
150+
) -> Vec<CodeGenAttributes> {
151+
vec![]
152+
}
153+
145154
/// Potentially override the visibility of a composite type field.
146155
///
147156
/// Caution: This allows overriding standard C++ visibility inferred by

bindgen/codegen/helpers.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,42 @@ pub(crate) mod attributes {
99
use proc_macro2::{Ident, Span, TokenStream};
1010
use std::{borrow::Cow, str::FromStr};
1111

12+
/// Attributes which may be added ontop of items
13+
#[derive(Clone, Debug)]
14+
pub enum Attribute {
15+
/// `#[derive($inner)]`
16+
Derives(Vec<String>),
17+
/// `#[inline]`
18+
Inline,
19+
/// `#[must_use]`
20+
MustUse,
21+
/// `#[doc($inner)]`
22+
Doc(String),
23+
/// `#[cfg($inner)`
24+
Cfg(String),
25+
/// `#[cfg_attr($inner)`
26+
CfgAttr(String),
27+
/// `#[deprecated]` or `#[deprecated($inner)]`
28+
Deprecated(Option<String>),
29+
}
30+
31+
impl Attribute {
32+
pub(crate) fn to_tokenstream(&self) -> TokenStream {
33+
match self {
34+
Attribute::Derives(d) => {
35+
let tmp: Vec<&str> = d.iter().map(String::as_str).collect();
36+
derives(&tmp)
37+
}
38+
Attribute::Inline => inline(),
39+
Attribute::MustUse => must_use(),
40+
Attribute::Doc(comment) => doc(&comment),
41+
Attribute::Cfg(condition) => cfg(&condition),
42+
Attribute::CfgAttr(inner) => cfg_attr(&inner),
43+
Attribute::Deprecated(inner) => deprecated(inner.clone()),
44+
}
45+
}
46+
}
47+
1248
pub(crate) fn repr(which: &str) -> TokenStream {
1349
let which = Ident::new(which, Span::call_site());
1450
quote! {
@@ -60,6 +96,28 @@ pub(crate) mod attributes {
6096
}
6197
}
6298

99+
pub(crate) fn cfg(cfg: &str) -> TokenStream {
100+
let raw_cfg = TokenStream::from_str(cfg).expect("cfg to be valid");
101+
quote!(#[cfg(#raw_cfg)])
102+
}
103+
104+
pub(crate) fn cfg_attr(cfg: &str) -> TokenStream {
105+
let raw_cfg = TokenStream::from_str(cfg).expect("cfg to be valid");
106+
quote!(#[cfg_attr(#raw_cfg)])
107+
}
108+
109+
pub(crate) fn deprecated(inner: Option<String>) -> TokenStream {
110+
if let Some(inner) = inner {
111+
let raw =
112+
TokenStream::from_str(inner.as_str()).expect("cfg to be valid");
113+
quote! {
114+
#[deprecated(#raw)]
115+
}
116+
} else {
117+
quote!(#[deprecated])
118+
}
119+
}
120+
63121
pub(crate) fn link_name<const MANGLE: bool>(name: &str) -> TokenStream {
64122
// LLVM mangles the name by default but it's already mangled.
65123
// Prefixing the name with \u{1} should tell LLVM to not mangle it.

0 commit comments

Comments
 (0)