Skip to content

Commit e6d9d2d

Browse files
committed
WIP: use the libm MPFR testing infra to test compiler-builtins
1 parent 0608b45 commit e6d9d2d

File tree

16 files changed

+436
-88
lines changed

16 files changed

+436
-88
lines changed

crates/libm-macros/src/lib.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ use parse::{Invocation, StructuredInput};
88
use proc_macro as pm;
99
use proc_macro2::{self as pm2, Span};
1010
use quote::{ToTokens, quote};
11+
use shared::OpScope;
1112
pub(crate) use shared::{ALL_OPERATIONS, FloatTy, MathOpInfo, Ty};
1213
use syn::spanned::Spanned;
1314
use syn::visit_mut::VisitMut;
14-
use syn::{Ident, ItemEnum};
15+
use syn::{Ident, ItemEnum, PathArguments, PathSegment};
1516

1617
const KNOWN_TYPES: &[&str] = &[
17-
"FTy", "CFn", "CArgs", "CRet", "RustFn", "RustArgs", "RustRet", "public",
18+
"FTy", "CFn", "CArgs", "CRet", "RustFn", "RustArgs", "RustRet", "path",
1819
];
1920

2021
/// Populate an enum with a variant representing function. Names are in upper camel case.
@@ -82,8 +83,8 @@ pub fn base_name_enum(attributes: pm::TokenStream, tokens: pm::TokenStream) -> p
8283
/// RustArgs: $RustArgs:ty,
8384
/// // The Rust version's return type (e.g. `(f32, f32)`)
8485
/// RustRet: $RustRet:ty,
85-
/// // True if this is part of `libm`'s public API
86-
/// public: $public:expr,
86+
/// // True if this is part of `libm`'s path API
87+
/// path: $path:path,
8788
/// // Attributes for the current function, if any
8889
/// attrs: [$($attr:meta),*],
8990
/// // Extra tokens passed directly (if any)
@@ -162,6 +163,18 @@ fn validate(input: &mut StructuredInput) -> syn::Result<Vec<&'static MathOpInfo>
162163
map.insert(Ident::new(op.name, key.span()), val.clone());
163164
}
164165
}
166+
167+
if let Some(k) = map.keys().find(|key| *key == "ALL_BUILTINS") {
168+
let key = k.clone();
169+
let val = map.remove(&key).unwrap();
170+
171+
for op in ALL_OPERATIONS
172+
.iter()
173+
.filter(|op| op.scope == OpScope::BuiltinsPublic)
174+
{
175+
map.insert(Ident::new(op.name, key.span()), val.clone());
176+
}
177+
}
165178
}
166179

167180
// Collect lists of all functions that are provied as macro inputs in various fields (only,
@@ -227,6 +240,10 @@ fn validate(input: &mut StructuredInput) -> syn::Result<Vec<&'static MathOpInfo>
227240
continue;
228241
}
229242

243+
if input.skip_builtins && func.scope == OpScope::BuiltinsPublic {
244+
continue;
245+
}
246+
230247
// Run everything else
231248
fn_list.push(func);
232249
}
@@ -363,7 +380,17 @@ fn expand(input: StructuredInput, fn_list: &[&MathOpInfo]) -> syn::Result<pm2::T
363380
let c_ret = &func.c_sig.returns;
364381
let rust_args = &func.rust_sig.args;
365382
let rust_ret = &func.rust_sig.returns;
366-
let public = func.public;
383+
let path = syn::Path {
384+
leading_colon: None,
385+
segments: func
386+
.path
387+
.split("::")
388+
.map(|pseg| PathSegment {
389+
ident: Ident::new(pseg, Span::call_site()),
390+
arguments: PathArguments::None,
391+
})
392+
.collect(),
393+
};
367394

368395
let mut ty_fields = Vec::new();
369396
for ty in &input.emit_types {
@@ -375,8 +402,8 @@ fn expand(input: StructuredInput, fn_list: &[&MathOpInfo]) -> syn::Result<pm2::T
375402
"RustFn" => quote! { RustFn: fn( #(#rust_args),* ,) -> ( #(#rust_ret),* ), },
376403
"RustArgs" => quote! { RustArgs: ( #(#rust_args),* ,), },
377404
"RustRet" => quote! { RustRet: ( #(#rust_ret),* ), },
378-
"public" => quote! { public: #public, },
379-
_ => unreachable!("checked in validation"),
405+
"path" => quote! { path: #path, },
406+
_ => unreachable!("fields should be checked in validation"),
380407
};
381408
ty_fields.push(field);
382409
}
@@ -465,6 +492,8 @@ fn base_name(name: &str) -> &str {
465492
None => name
466493
.strip_suffix("f")
467494
.or_else(|| name.strip_suffix("f16"))
495+
.or_else(|| name.strip_suffix("f32"))
496+
.or_else(|| name.strip_suffix("f64"))
468497
.or_else(|| name.strip_suffix("f128"))
469498
.unwrap_or(name),
470499
}

crates/libm-macros/src/parse.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub struct StructuredInput {
5252
pub skip: Vec<Ident>,
5353
/// If true, omit f16 and f128 functions that aren't present in other libraries.
5454
pub skip_f16_f128: bool,
55+
pub skip_builtins: bool,
5556
/// Invoke only for these functions
5657
pub only: Option<Vec<Ident>>,
5758
/// Attributes that get applied to specific functions
@@ -73,6 +74,7 @@ impl StructuredInput {
7374
let emit_types_expr = expect_field(&mut map, "emit_types").ok();
7475
let skip_expr = expect_field(&mut map, "skip").ok();
7576
let skip_f16_f128 = expect_field(&mut map, "skip_f16_f128").ok();
77+
let skip_builtins = expect_field(&mut map, "skip_builtins").ok();
7678
let only_expr = expect_field(&mut map, "only").ok();
7779
let attr_expr = expect_field(&mut map, "attributes").ok();
7880
let extra = expect_field(&mut map, "extra").ok();
@@ -101,6 +103,11 @@ impl StructuredInput {
101103
None => false,
102104
};
103105

106+
let skip_builtins = match skip_builtins {
107+
Some(expr) => expect_litbool(expr)?.value,
108+
None => false,
109+
};
110+
104111
let only_span = only_expr.as_ref().map(|expr| expr.span());
105112
let only = match only_expr {
106113
Some(expr) => Some(Parser::parse2(parse_ident_array, expr.into_token_stream())?),
@@ -131,6 +138,7 @@ impl StructuredInput {
131138
emit_types,
132139
skip,
133140
skip_f16_f128,
141+
skip_builtins,
134142
only,
135143
only_span,
136144
attributes,

0 commit comments

Comments
 (0)