From f58f37b2b9a292a0e0d0be7d8afbe4df651c3432 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Tj=C3=A4der?= Date: Wed, 8 Apr 2020 14:43:47 +0000 Subject: [PATCH] Retain cfg-attributes on resources --- examples/t-cfg-resources.rs | 40 +++++++++++++++++++++++++++++++++ macros/src/codegen.rs | 2 +- macros/src/codegen/init.rs | 6 ++++- macros/src/codegen/post_init.rs | 10 ++++++++- macros/src/codegen/resources.rs | 10 +++++++-- 5 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 examples/t-cfg-resources.rs diff --git a/examples/t-cfg-resources.rs b/examples/t-cfg-resources.rs new file mode 100644 index 0000000000..86b5ea20cc --- /dev/null +++ b/examples/t-cfg-resources.rs @@ -0,0 +1,40 @@ +//! [compile-pass] check that `#[cfg]` attributes applied on resources work +//! +#![no_main] +#![no_std] + +use panic_halt as _; + +#[cfg(rustc_is_nightly)] +mod example { + + #[rtfm::app(device = lm3s6965)] + const APP: () = { + struct Resources { + // A resource + #[init(0)] + shared: u32, + + // A conditionally compiled resource behind feature_x + #[cfg(feature = "feature_x")] + x: u32, + + dummy: (), + } + + #[init] + fn init(_: init::Context) -> init::LateResources { + init::LateResources { + // The feature needs to be applied everywhere x is defined or used + #[cfg(feature = "feature_x")] + x: 0, + dummy: () // dummy such that we have at least one late resource + } + } + + #[idle] + fn idle(_cx: idle::Context) -> ! { + loop {} + } + }; +} diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 0213848157..7d0d1220e3 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -39,7 +39,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { let (const_app_init, root_init, user_init, call_init) = init::codegen(core, app, analysis, extra); - let (const_app_post_init, post_init_stmts) = post_init::codegen(core, analysis, extra); + let (const_app_post_init, post_init_stmts) = post_init::codegen(core, &app, analysis, extra); let (const_app_idle, root_idle, user_idle, call_idle) = idle::codegen(core, app, analysis, extra); diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 9c8ce31c7c..f7e4674eb9 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -44,8 +44,12 @@ pub fn codegen( .iter() .map(|name| { let ty = &app.late_resources[name].ty; + let cfgs = &app.late_resources[name].cfgs; - quote!(pub #name: #ty) + quote!( + #(#cfgs)* + pub #name: #ty + ) }) .collect::>() }) diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index 19773e45bd..8578d5acee 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -1,11 +1,13 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; +use rtfm_syntax::ast::App; use crate::{analyze::Analysis, check::Extra, codegen::util}; /// Generates code that runs after `#[init]` returns pub fn codegen( core: u8, + app: &App, analysis: &Analysis, extra: &Extra, ) -> (Vec, Vec) { @@ -14,10 +16,16 @@ pub fn codegen( // initialize late resources if let Some(late_resources) = analysis.late_resources.get(&core) { + for name in late_resources { // if it's live + let cfgs = app.late_resources[name].cfgs.clone(); if analysis.locations.get(name).is_some() { - stmts.push(quote!(#name.as_mut_ptr().write(late.#name);)); + // Need to also include the cfgs + stmts.push(quote!( + #(#cfgs)* + #name.as_mut_ptr().write(late.#name); + )); } } } diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs index 8cb788d1ae..83bfabd705 100644 --- a/macros/src/codegen/resources.rs +++ b/macros/src/codegen/resources.rs @@ -101,9 +101,15 @@ pub fn codegen( )); let ptr = if expr.is_none() { - quote!(#name.as_mut_ptr()) + quote!( + #(#cfgs)* + #name.as_mut_ptr() + ) } else { - quote!(&mut #name) + quote!( + #(#cfgs)* + &mut #name + ) }; const_app.push(util::impl_mutex(