From ec1ca5129826bdaf4f6f1c97255547bfc8d12b77 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 26 Oct 2024 02:56:22 -0500 Subject: [PATCH] Vendor `cfg_if::cfg_if!` `cfg_if` is helpful for applying `cfg` attributes to groups of items, like we will need to do with architecture-specific modules of `f16` and `f128`. However, `libm` can't have dependencies. The `cfg_if` macro is complex but small, so just vendor it here. --- .../libm/src/math/support/macros.rs | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/library/compiler-builtins/libm/src/math/support/macros.rs b/library/compiler-builtins/libm/src/math/support/macros.rs index 6bc75837a349..39a6fe827725 100644 --- a/library/compiler-builtins/libm/src/math/support/macros.rs +++ b/library/compiler-builtins/libm/src/math/support/macros.rs @@ -1,6 +1,46 @@ -/// Choose among using an intrinsic (if available) and falling back to the default function body. -/// Returns directly if the intrinsic version is used, otherwise continues to the rest of the -/// function. +/// `libm` cannot have dependencies, so this is vendored directly from the `cfg-if` crate +/// (with some comments stripped for compactness). +macro_rules! cfg_if { + // match if/else chains with a final `else` + ($( + if #[cfg($meta:meta)] { $($tokens:tt)* } + ) else * else { + $($tokens2:tt)* + }) => { + cfg_if! { @__items () ; $( ( ($meta) ($($tokens)*) ), )* ( () ($($tokens2)*) ), } + }; + + // match if/else chains lacking a final `else` + ( + if #[cfg($i_met:meta)] { $($i_tokens:tt)* } + $( else if #[cfg($e_met:meta)] { $($e_tokens:tt)* } )* + ) => { + cfg_if! { + @__items + () ; + ( ($i_met) ($($i_tokens)*) ), + $( ( ($e_met) ($($e_tokens)*) ), )* + ( () () ), + } + }; + + // Internal and recursive macro to emit all the items + // + // Collects all the negated cfgs in a list at the beginning and after the + // semicolon is all the remaining items + (@__items ($($not:meta,)*) ; ) => {}; + (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($tokens:tt)*) ), $($rest:tt)*) => { + #[cfg(all($($m,)* not(any($($not),*))))] cfg_if! { @__identity $($tokens)* } + cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } + }; + + // Internal macro to make __apply work out right for different match types, + // because of how macros matching/expand stuff. + (@__identity $($tokens:tt)*) => { $($tokens)* }; +} + +/// Choose between using an intrinsic (if available) and the function body. Returns directly if +/// the intrinsic is used, otherwise the rest of the function body is used. /// /// Use this if the intrinsic is likely to be more performant on the platform(s) specified /// in `intrinsic_available`.