linker_set_proc/
lib.rs

1#![warn(missing_docs)]
2
3//! Procedural macro crate to accompany the linker-set crate.
4
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::parse::{Parse, ParseStream};
8use syn::punctuated::Punctuated;
9use syn::{Ident, ItemStatic, Result, Token, parse_macro_input};
10
11struct Name(String);
12
13impl Parse for Name {
14    fn parse(input: ParseStream) -> Result<Self> {
15        let name = Punctuated::<Ident, Token![,]>::parse_terminated(input)?;
16        assert!(name.len() == 1, "set_entry macro takes one argument");
17        Ok(Self(name[0].to_string()))
18    }
19}
20
21/// Attribute macro that puts an item into a linker set.
22#[proc_macro_attribute]
23pub fn set_entry(meta: TokenStream, decl: TokenStream) -> TokenStream {
24    let meta = parse_macro_input!(meta as Name);
25    let decl = parse_macro_input!(decl as ItemStatic);
26
27    let set = meta.0;
28    let set_section = format!("set_{set}");
29
30    let g = quote! {
31        #[unsafe(link_section = #set_section)]
32        #[used]
33        #decl
34    };
35    TokenStream::from(g)
36}