Skip to content

Commit d3841f8

Browse files
committed
WIP: use the libm MPFR testing infra to test compiler-builtins
1 parent 13c5374 commit d3841f8

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
@@ -6,13 +6,14 @@ use parse::{Invocation, StructuredInput};
66
use proc_macro as pm;
77
use proc_macro2::{self as pm2, Span};
88
use quote::{ToTokens, quote};
9+
use shared::OpScope;
910
pub(crate) use shared::{ALL_OPERATIONS, FloatTy, MathOpInfo, Ty};
1011
use syn::spanned::Spanned;
1112
use syn::visit_mut::VisitMut;
12-
use syn::{Ident, ItemEnum};
13+
use syn::{Ident, ItemEnum, PathArguments, PathSegment};
1314

1415
const KNOWN_TYPES: &[&str] = &[
15-
"FTy", "CFn", "CArgs", "CRet", "RustFn", "RustArgs", "RustRet", "public",
16+
"FTy", "CFn", "CArgs", "CRet", "RustFn", "RustArgs", "RustRet", "path",
1617
];
1718

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

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

241+
if input.skip_builtins && func.scope == OpScope::BuiltinsPublic {
242+
continue;
243+
}
244+
228245
// Run everything else
229246
fn_list.push(func);
230247
}
@@ -361,7 +378,17 @@ fn expand(input: StructuredInput, fn_list: &[&MathOpInfo]) -> syn::Result<pm2::T
361378
let c_ret = &func.c_sig.returns;
362379
let rust_args = &func.rust_sig.args;
363380
let rust_ret = &func.rust_sig.returns;
364-
let public = func.public;
381+
let path = syn::Path {
382+
leading_colon: None,
383+
segments: func
384+
.path
385+
.split("::")
386+
.map(|pseg| PathSegment {
387+
ident: Ident::new(pseg, Span::call_site()),
388+
arguments: PathArguments::None,
389+
})
390+
.collect(),
391+
};
365392

366393
let mut ty_fields = Vec::new();
367394
for ty in &input.emit_types {
@@ -373,8 +400,8 @@ fn expand(input: StructuredInput, fn_list: &[&MathOpInfo]) -> syn::Result<pm2::T
373400
"RustFn" => quote! { RustFn: fn( #(#rust_args),* ,) -> ( #(#rust_ret),* ), },
374401
"RustArgs" => quote! { RustArgs: ( #(#rust_args),* ,), },
375402
"RustRet" => quote! { RustRet: ( #(#rust_ret),* ), },
376-
"public" => quote! { public: #public, },
377-
_ => unreachable!("checked in validation"),
403+
"path" => quote! { path: #path, },
404+
_ => unreachable!("fields should be checked in validation"),
378405
};
379406
ty_fields.push(field);
380407
}
@@ -463,6 +490,8 @@ fn base_name(name: &str) -> &str {
463490
None => name
464491
.strip_suffix("f")
465492
.or_else(|| name.strip_suffix("f16"))
493+
.or_else(|| name.strip_suffix("f32"))
494+
.or_else(|| name.strip_suffix("f64"))
466495
.or_else(|| name.strip_suffix("f128"))
467496
.unwrap_or(name),
468497
}

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)