cortex_m_rtic_macros/codegen/
assertions.rs
1use proc_macro2::TokenStream as TokenStream2;
2use quote::quote;
3
4use crate::{analyze::Analysis, check::Extra, codegen::util};
5use rtic_syntax::ast::App;
6
7pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
9 let mut stmts = vec![];
10
11 for ty in &analysis.send_types {
12 stmts.push(quote!(rtic::export::assert_send::<#ty>();));
13 }
14
15 for ty in &analysis.sync_types {
16 stmts.push(quote!(rtic::export::assert_sync::<#ty>();));
17 }
18
19 for (_, monotonic) in &app.monotonics {
20 let ty = &monotonic.ty;
21 stmts.push(quote!(rtic::export::assert_monotonic::<#ty>();));
22 }
23
24 let device = &extra.device;
25 let chunks_name = util::priority_mask_chunks_ident();
26 let no_basepri_checks: Vec<_> = app
27 .hardware_tasks
28 .iter()
29 .filter_map(|(_, task)| {
30 if !util::is_exception(&task.args.binds) {
31 let interrupt_name = &task.args.binds;
32 let cfgs = &task.cfgs;
33 Some(quote!(
34 #(#cfgs)*
35 if (#device::Interrupt::#interrupt_name as usize) >= (#chunks_name * 32) {
36 ::core::panic!("An interrupt out of range is used while in armv6 or armv8m.base");
37 }
38 ))
39 } else {
40 None
41 }
42 })
43 .collect();
44
45 let const_check = quote! {
46 const _CONST_CHECK: () = {
47 if !rtic::export::have_basepri() {
48 #(#no_basepri_checks)*
49 } else {
50 }
52 };
53
54 let _ = _CONST_CHECK;
55 };
56
57 stmts.push(const_check);
58
59 stmts
60}