diff options
author | 2018-12-15 15:37:20 +0100 | |
---|---|---|
committer | 2018-12-15 15:37:20 +0100 | |
commit | c69ff66f4c1d353be5d683ca8c131a04e997e4ed (patch) | |
tree | 8565f0edc28016ea1acc1f14dd63591d21c3fe32 | |
parent | c7e6e5f78203b55b0094bd26d78e17c9c9d155a2 (diff) | |
download | cortex-m-c69ff66f4c1d353be5d683ca8c131a04e997e4ed.tar.gz cortex-m-c69ff66f4c1d353be5d683ca8c131a04e997e4ed.tar.zst cortex-m-c69ff66f4c1d353be5d683ca8c131a04e997e4ed.zip |
static mut transform: forward `#[cfg]`
-rw-r--r-- | cortex-m-rt/examples/cfg-static.rs | 25 | ||||
-rw-r--r-- | cortex-m-rt/macros/src/lib.rs | 41 |
2 files changed, 60 insertions, 6 deletions
diff --git a/cortex-m-rt/examples/cfg-static.rs b/cortex-m-rt/examples/cfg-static.rs new file mode 100644 index 0000000..2ffee13 --- /dev/null +++ b/cortex-m-rt/examples/cfg-static.rs @@ -0,0 +1,25 @@ +//! using `#[cfg]` on `static` shouldn't cause compile errors + +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] + +extern crate cortex_m_rt as rt; +extern crate panic_halt; + +use rt::{entry, exception}; + +#[entry] +fn main() -> ! { + #[cfg(never)] + static mut COUNT: u32 = 0; + + loop {} +} + +#[exception] +fn SysTick() { + #[cfg(never)] + static mut FOO: u32 = 0; +} diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 1013f5e..7528586 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -16,8 +16,8 @@ use std::collections::HashSet; use std::sync::atomic::{AtomicUsize, Ordering}; use std::time::{SystemTime, UNIX_EPOCH}; use syn::{ - parse, spanned::Spanned, FnArg, Ident, Item, ItemFn, ItemStatic, ReturnType, Stmt, Type, - Visibility, + parse, spanned::Spanned, AttrStyle, Attribute, FnArg, Ident, Item, ItemFn, ItemStatic, + PathArguments, ReturnType, Stmt, Type, Visibility, }; static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); @@ -128,15 +128,17 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { let vars = statics .into_iter() .map(|var| { - let attrs = var.attrs; + let (ref cfgs, ref attrs) = extract_cfgs(var.attrs); let ident = var.ident; let ty = var.ty; let expr = var.expr; quote!( #[allow(non_snake_case)] + #(#cfgs)* let #ident: &'static mut #ty = unsafe { #(#attrs)* + #(#cfgs)* static mut #ident: #ty = #expr; &mut #ident @@ -405,7 +407,6 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { // further type check of the input argument let #pat: &cortex_m_rt::ExceptionFrame = #pat; - #(#stmts)* } ) @@ -446,15 +447,17 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let vars = statics .into_iter() .map(|var| { - let attrs = var.attrs; + let (ref cfgs, ref attrs) = extract_cfgs(var.attrs); let ident = var.ident; let ty = var.ty; let expr = var.expr; quote!( #[allow(non_snake_case)] + #(#cfgs)* let #ident: &mut #ty = unsafe { #(#attrs)* + #(#cfgs)* static mut #ident: #ty = #expr; &mut #ident @@ -603,15 +606,17 @@ pub fn interrupt(args: TokenStream, input: TokenStream) -> TokenStream { let vars = statics .into_iter() .map(|var| { - let attrs = var.attrs; + let (ref cfgs, ref attrs) = extract_cfgs(var.attrs); let ident = var.ident; let ty = var.ty; let expr = var.expr; quote!( #[allow(non_snake_case)] + #(#cfgs)* let #ident: &mut #ty = unsafe { #(#attrs)* + #(#cfgs)* static mut #ident: #ty = #expr; &mut #ident @@ -776,3 +781,27 @@ fn extract_static_muts(stmts: Vec<Stmt>) -> Result<(Vec<ItemStatic>, Vec<Stmt>), Ok((statics, stmts)) } + +fn extract_cfgs(attrs: Vec<Attribute>) -> (Vec<Attribute>, Vec<Attribute>) { + let mut cfgs = vec![]; + let mut not_cfgs = vec![]; + + for attr in attrs { + if eq(&attr, "cfg") { + cfgs.push(attr); + } else { + not_cfgs.push(attr); + } + } + + (cfgs, not_cfgs) +} + +/// Returns `true` if `attr.path` matches `name` +fn eq(attr: &Attribute, name: &str) -> bool { + attr.style == AttrStyle::Outer && attr.path.segments.len() == 1 && { + let pair = attr.path.segments.first().unwrap(); + let segment = pair.value(); + segment.arguments == PathArguments::None && segment.ident.to_string() == name + } +} |