1use proc_macro2::{Span, TokenStream};
2use quote::ToTokens as _;
3use syn::{
4 parse::Nothing, parse_macro_input, token, AttrStyle, Attribute, ImplItem, ItemImpl, Meta, Path,
5 Token,
6};
7
8#[proc_macro_attribute]
10pub fn no_mangle(
11 attr: proc_macro::TokenStream,
12 item: proc_macro::TokenStream,
13) -> proc_macro::TokenStream {
14 let config = parse_macro_input!(attr as Nothing);
15 let item = parse_macro_input!(item as ItemImpl);
16 expand(config, item)
17 .unwrap_or_else(syn::Error::into_compile_error)
18 .into()
19}
20
21fn expand(_: Nothing, mut item: ItemImpl) -> syn::Result<TokenStream> {
22 let span = Span::call_site();
23 for item in &mut item.items {
24 if let ImplItem::Fn(it) = item {
25 if !it.attrs.iter().any(|it| it.path().is_ident("no_mangle")) {
26 it.attrs.push(Attribute {
27 pound_token: Token,
28 style: AttrStyle::Outer,
29 bracket_token: token::Bracket(span),
30 meta: Meta::Path(Path::from(syn::Ident::new("no_mangle", span))),
31 });
32 }
33 }
34 }
35 Ok(item.into_token_stream())
36}