Parse unsafe
attributes
This commit is contained in:
parent
3ed9434f09
commit
0ac02118b1
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -405,9 +405,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.72"
|
||||
version = "2.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#![allow(clippy::redundant_closure_call)]
|
||||
|
||||
use syn::ext::IdentExt;
|
||||
use syn::{ext::IdentExt, parse::Parser};
|
||||
|
||||
pub trait IterHelpers: Iterator {
|
||||
fn try_skip_map<F, T, E>(&mut self, f: F) -> Result<Vec<T>, E>
|
||||
@ -38,12 +38,10 @@ impl SynItemHelpers for syn::ItemFn {
|
||||
fn exported_name(&self) -> Option<String> {
|
||||
self.attrs
|
||||
.attr_name_value_lookup("export_name")
|
||||
.or_else(|| self.unsafe_attr_name_value_lookup("export_name"))
|
||||
.or_else(|| {
|
||||
if self.is_no_mangle() {
|
||||
Some(self.sig.ident.unraw().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
self.is_no_mangle()
|
||||
.then(|| self.sig.ident.unraw().to_string())
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -150,6 +148,29 @@ pub trait SynAttributeHelpers {
|
||||
})
|
||||
}
|
||||
|
||||
/// Searches for attributes like `#[unsafe(test)]`.
|
||||
/// Example:
|
||||
/// - `item.has_unsafe_attr_word("test")` => `#[unsafe(test)]`
|
||||
fn has_unsafe_attr_word(&self, name: &str) -> bool {
|
||||
self.attrs().iter().filter_map(|attr| {
|
||||
match &attr.meta {
|
||||
syn::Meta::List(list) if list.path.is_ident("unsafe") => Some(list.tokens.clone()),
|
||||
_ => None,
|
||||
}
|
||||
}).any(|tokens| {
|
||||
let parser = syn::punctuated::Punctuated::<proc_macro2::TokenStream, syn::Token![,]>::parse_terminated;
|
||||
let Ok(args) = parser.parse2(tokens) else {
|
||||
return false;
|
||||
};
|
||||
args.into_iter().any(|arg| {
|
||||
match syn::parse2::<syn::Path>(arg) {
|
||||
Ok(path) => path.is_ident(name),
|
||||
Err(_) => false,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn find_deprecated_note(&self) -> Option<String> {
|
||||
let attrs = self.attrs();
|
||||
// #[deprecated = ""]
|
||||
@ -194,7 +215,7 @@ pub trait SynAttributeHelpers {
|
||||
}
|
||||
|
||||
fn is_no_mangle(&self) -> bool {
|
||||
self.has_attr_word("no_mangle")
|
||||
self.has_attr_word("no_mangle") || self.has_unsafe_attr_word("no_mangle")
|
||||
}
|
||||
|
||||
/// Sees whether we should skip parsing a given item.
|
||||
@ -231,6 +252,43 @@ pub trait SynAttributeHelpers {
|
||||
.next()
|
||||
}
|
||||
|
||||
fn unsafe_attr_name_value_lookup(&self, name: &str) -> Option<String> {
|
||||
self.attrs()
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
let syn::Meta::List(syn::MetaList { path, tokens, .. }) = &attr.meta else {
|
||||
return None;
|
||||
};
|
||||
if path.is_ident("unsafe") {
|
||||
let parser = syn::punctuated::Punctuated::<
|
||||
proc_macro2::TokenStream,
|
||||
syn::Token![,],
|
||||
>::parse_terminated;
|
||||
let Ok(args) = parser.parse2(tokens.clone()) else {
|
||||
return None;
|
||||
};
|
||||
for arg in args {
|
||||
match syn::parse2::<syn::MetaNameValue>(arg) {
|
||||
Ok(syn::MetaNameValue {
|
||||
path,
|
||||
value:
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(lit),
|
||||
..
|
||||
}),
|
||||
..
|
||||
}) if path.is_ident(name) => {
|
||||
return Some(lit.value());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
fn get_comment_lines(&self) -> Vec<String> {
|
||||
let mut comment = Vec::new();
|
||||
|
||||
|
@ -4,3 +4,5 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
void do_the_thing_with_export_name(void);
|
||||
|
||||
void do_the_thing_with_unsafe_export_name(void);
|
||||
|
@ -9,6 +9,8 @@ extern "C" {
|
||||
|
||||
void do_the_thing_with_export_name(void);
|
||||
|
||||
void do_the_thing_with_unsafe_export_name(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -8,4 +8,6 @@ extern "C" {
|
||||
|
||||
void do_the_thing_with_export_name();
|
||||
|
||||
void do_the_thing_with_unsafe_export_name();
|
||||
|
||||
} // extern "C"
|
||||
|
@ -7,3 +7,5 @@ cdef extern from *:
|
||||
cdef extern from *:
|
||||
|
||||
void do_the_thing_with_export_name();
|
||||
|
||||
void do_the_thing_with_unsafe_export_name();
|
||||
|
@ -15,3 +15,5 @@ typedef struct {
|
||||
typedef FooU8 Boo;
|
||||
|
||||
void root(Boo x, Bar y);
|
||||
|
||||
void unsafe_root(Boo x, Bar y);
|
||||
|
@ -20,6 +20,8 @@ extern "C" {
|
||||
|
||||
void root(Boo x, Bar y);
|
||||
|
||||
void unsafe_root(Boo x, Bar y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -20,4 +20,6 @@ extern "C" {
|
||||
|
||||
void root(Boo x, Bar y);
|
||||
|
||||
void unsafe_root(Boo x, Bar y);
|
||||
|
||||
} // extern "C"
|
||||
|
@ -16,3 +16,5 @@ cdef extern from *:
|
||||
ctypedef FooU8 Boo;
|
||||
|
||||
void root(Boo x, Bar y);
|
||||
|
||||
void unsafe_root(Boo x, Bar y);
|
||||
|
@ -15,3 +15,5 @@ typedef struct FooU8 {
|
||||
typedef struct FooU8 Boo;
|
||||
|
||||
void root(Boo x, enum Bar y);
|
||||
|
||||
void unsafe_root(Boo x, enum Bar y);
|
||||
|
@ -20,6 +20,8 @@ extern "C" {
|
||||
|
||||
void root(Boo x, enum Bar y);
|
||||
|
||||
void unsafe_root(Boo x, enum Bar y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -15,3 +15,5 @@ struct FooU8 {
|
||||
typedef struct FooU8 Boo;
|
||||
|
||||
void root(Boo x, enum Bar y);
|
||||
|
||||
void unsafe_root(Boo x, enum Bar y);
|
||||
|
@ -20,6 +20,8 @@ extern "C" {
|
||||
|
||||
void root(Boo x, enum Bar y);
|
||||
|
||||
void unsafe_root(Boo x, enum Bar y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
@ -16,3 +16,5 @@ cdef extern from *:
|
||||
ctypedef FooU8 Boo;
|
||||
|
||||
void root(Boo x, Bar y);
|
||||
|
||||
void unsafe_root(Boo x, Bar y);
|
||||
|
@ -1,4 +1,9 @@
|
||||
#[export_name = "do_the_thing_with_export_name"]
|
||||
pub extern "C" fn do_the_thing() {
|
||||
println!("doing the thing!");
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(export_name = "do_the_thing_with_unsafe_export_name")]
|
||||
pub extern "C" fn unsafe_do_the_thing() {
|
||||
println!("doing the thing!");
|
||||
}
|
||||
|
@ -17,3 +17,9 @@ pub extern "C" fn root(
|
||||
x: Boo,
|
||||
y: Bar,
|
||||
) { }
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn unsafe_root(
|
||||
x: Boo,
|
||||
y: Bar,
|
||||
) { }
|
||||
|
Loading…
x
Reference in New Issue
Block a user