mirror of
https://gitee.com/openharmony/third_party_rust_cxx
synced 2024-11-28 01:41:05 +00:00
Store independent rust name and c++ name for extern functions
This commit is contained in:
parent
f3a9afae50
commit
a4641c738a
@ -370,7 +370,7 @@ fn write_struct_with_methods(out: &mut OutFile, ety: &ExternType, methods: &[&Ex
|
||||
for method in methods {
|
||||
write!(out, " ");
|
||||
let sig = &method.sig;
|
||||
let local_name = method.ident.to_string();
|
||||
let local_name = method.ident.cxx.to_string();
|
||||
write_rust_function_shim_decl(out, &local_name, sig, false);
|
||||
writeln!(out, ";");
|
||||
}
|
||||
@ -517,8 +517,8 @@ fn write_cxx_function_shim(
|
||||
write!(out, " ");
|
||||
write_return_type(out, &efn.ret);
|
||||
match &efn.receiver {
|
||||
None => write!(out, "(*{}$)(", efn.ident),
|
||||
Some(receiver) => write!(out, "({}::*{}$)(", receiver.ty, efn.ident),
|
||||
None => write!(out, "(*{}$)(", efn.ident.rust),
|
||||
Some(receiver) => write!(out, "({}::*{}$)(", receiver.ty, efn.ident.rust),
|
||||
}
|
||||
for (i, arg) in efn.args.iter().enumerate() {
|
||||
if i > 0 {
|
||||
@ -534,8 +534,8 @@ fn write_cxx_function_shim(
|
||||
}
|
||||
write!(out, " = ");
|
||||
match &efn.receiver {
|
||||
None => write!(out, "{}", efn.ident),
|
||||
Some(receiver) => write!(out, "&{}::{}", receiver.ty, efn.ident),
|
||||
None => write!(out, "{}", efn.ident.cxx),
|
||||
Some(receiver) => write!(out, "&{}::{}", receiver.ty, efn.ident.cxx),
|
||||
}
|
||||
writeln!(out, ";");
|
||||
write!(out, " ");
|
||||
@ -562,8 +562,8 @@ fn write_cxx_function_shim(
|
||||
_ => {}
|
||||
}
|
||||
match &efn.receiver {
|
||||
None => write!(out, "{}$(", efn.ident),
|
||||
Some(_) => write!(out, "(self.*{}$)(", efn.ident),
|
||||
None => write!(out, "{}$(", efn.ident.rust),
|
||||
Some(_) => write!(out, "(self.*{}$)(", efn.ident.rust),
|
||||
}
|
||||
for (i, arg) in efn.args.iter().enumerate() {
|
||||
if i > 0 {
|
||||
@ -697,8 +697,8 @@ fn write_rust_function_shim(out: &mut OutFile, efn: &ExternFn, types: &Types) {
|
||||
writeln!(out, "//{}", line);
|
||||
}
|
||||
let local_name = match &efn.sig.receiver {
|
||||
None => efn.ident.to_string(),
|
||||
Some(receiver) => format!("{}::{}", receiver.ty, efn.ident),
|
||||
None => efn.ident.cxx.to_string(),
|
||||
Some(receiver) => format!("{}::{}", receiver.ty, efn.ident.cxx),
|
||||
};
|
||||
let invoke = mangle::extern_fn(&out.namespace, efn);
|
||||
let indirect_call = false;
|
||||
|
@ -206,7 +206,6 @@ fn expand_cxx_type(namespace: &Namespace, ety: &ExternType) -> TokenStream {
|
||||
}
|
||||
|
||||
fn expand_cxx_function_decl(namespace: &Namespace, efn: &ExternFn, types: &Types) -> TokenStream {
|
||||
let ident = &efn.ident;
|
||||
let receiver = efn.receiver.iter().map(|receiver| {
|
||||
let receiver_type = receiver.ty();
|
||||
quote!(_: #receiver_type)
|
||||
@ -238,7 +237,7 @@ fn expand_cxx_function_decl(namespace: &Namespace, efn: &ExternFn, types: &Types
|
||||
outparam = Some(quote!(__return: *mut #ret));
|
||||
}
|
||||
let link_name = mangle::extern_fn(namespace, efn);
|
||||
let local_name = format_ident!("__{}", ident);
|
||||
let local_name = format_ident!("__{}", efn.ident.rust);
|
||||
quote! {
|
||||
#[link_name = #link_name]
|
||||
fn #local_name(#(#all_args,)* #outparam) #ret;
|
||||
@ -246,7 +245,6 @@ fn expand_cxx_function_decl(namespace: &Namespace, efn: &ExternFn, types: &Types
|
||||
}
|
||||
|
||||
fn expand_cxx_function_shim(namespace: &Namespace, efn: &ExternFn, types: &Types) -> TokenStream {
|
||||
let ident = &efn.ident;
|
||||
let doc = &efn.doc;
|
||||
let decl = expand_cxx_function_decl(namespace, efn, types);
|
||||
let receiver = efn.receiver.iter().map(|receiver| {
|
||||
@ -329,7 +327,7 @@ fn expand_cxx_function_shim(namespace: &Namespace, efn: &ExternFn, types: &Types
|
||||
}
|
||||
})
|
||||
.collect::<TokenStream>();
|
||||
let local_name = format_ident!("__{}", ident);
|
||||
let local_name = format_ident!("__{}", efn.ident.rust);
|
||||
let call = if indirect_return {
|
||||
let ret = expand_extern_type(efn.ret.as_ref().unwrap());
|
||||
setup.extend(quote! {
|
||||
@ -426,6 +424,7 @@ fn expand_cxx_function_shim(namespace: &Namespace, efn: &ExternFn, types: &Types
|
||||
if unsafety.is_none() {
|
||||
dispatch = quote!(unsafe { #dispatch });
|
||||
}
|
||||
let ident = &efn.ident.rust;
|
||||
let function_shim = quote! {
|
||||
#doc
|
||||
pub #unsafety fn #ident(#(#all_args,)*) #ret {
|
||||
@ -455,7 +454,7 @@ fn expand_function_pointer_trampoline(
|
||||
let c_trampoline = mangle::c_trampoline(namespace, efn, var);
|
||||
let r_trampoline = mangle::r_trampoline(namespace, efn, var);
|
||||
let local_name = parse_quote!(__);
|
||||
let catch_unwind_label = format!("::{}::{}", efn.ident, var);
|
||||
let catch_unwind_label = format!("::{}::{}", efn.ident.rust, var);
|
||||
let shim = expand_rust_function_shim_impl(
|
||||
sig,
|
||||
types,
|
||||
@ -510,11 +509,10 @@ fn expand_rust_type_assert_sized(ety: &ExternType) -> TokenStream {
|
||||
}
|
||||
|
||||
fn expand_rust_function_shim(namespace: &Namespace, efn: &ExternFn, types: &Types) -> TokenStream {
|
||||
let ident = &efn.ident;
|
||||
let link_name = mangle::extern_fn(namespace, efn);
|
||||
let local_name = format_ident!("__{}", ident);
|
||||
let catch_unwind_label = format!("::{}", ident);
|
||||
let invoke = Some(ident);
|
||||
let local_name = format_ident!("__{}", efn.ident.rust);
|
||||
let catch_unwind_label = format!("::{}", efn.ident.rust);
|
||||
let invoke = Some(&efn.ident.rust);
|
||||
expand_rust_function_shim_impl(
|
||||
efn,
|
||||
types,
|
||||
|
@ -214,8 +214,8 @@ fn check_api_type(cx: &mut Check, ety: &ExternType) {
|
||||
if let Some(reason) = cx.types.required_trivial.get(&ety.ident) {
|
||||
let what = match reason {
|
||||
TrivialReason::StructField(strct) => format!("a field of `{}`", strct.ident),
|
||||
TrivialReason::FunctionArgument(efn) => format!("an argument of `{}`", efn.ident),
|
||||
TrivialReason::FunctionReturn(efn) => format!("a return value of `{}`", efn.ident),
|
||||
TrivialReason::FunctionArgument(efn) => format!("an argument of `{}`", efn.ident.rust),
|
||||
TrivialReason::FunctionReturn(efn) => format!("a return value of `{}`", efn.ident.rust),
|
||||
};
|
||||
let msg = format!(
|
||||
"needs a cxx::ExternType impl in order to be used as {}",
|
||||
|
@ -37,7 +37,7 @@ pub(crate) fn check_all(cx: &mut Check, namespace: &Namespace, apis: &[Api]) {
|
||||
check(cx, &ety.ident);
|
||||
}
|
||||
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
|
||||
check(cx, &efn.ident);
|
||||
check(cx, &efn.ident.rust);
|
||||
for arg in &efn.args {
|
||||
check(cx, &arg.ident);
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ macro_rules! join {
|
||||
|
||||
pub fn extern_fn(namespace: &Namespace, efn: &ExternFn) -> Symbol {
|
||||
match &efn.receiver {
|
||||
Some(receiver) => join!(namespace, CXXBRIDGE, receiver.ty, efn.ident),
|
||||
None => join!(namespace, CXXBRIDGE, efn.ident),
|
||||
Some(receiver) => join!(namespace, CXXBRIDGE, receiver.ty, efn.ident.rust),
|
||||
None => join!(namespace, CXXBRIDGE, efn.ident.rust),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,15 @@ pub struct Enum {
|
||||
pub repr: Atom,
|
||||
}
|
||||
|
||||
pub struct Pair {
|
||||
pub cxx: Ident,
|
||||
pub rust: Ident,
|
||||
}
|
||||
|
||||
pub struct ExternFn {
|
||||
pub lang: Lang,
|
||||
pub doc: Doc,
|
||||
pub ident: Ident,
|
||||
pub ident: Pair,
|
||||
pub sig: Signature,
|
||||
pub semi_token: Token![;],
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::syntax::file::{Item, ItemForeignMod};
|
||||
use crate::syntax::report::Errors;
|
||||
use crate::syntax::Atom::*;
|
||||
use crate::syntax::{
|
||||
attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Lang, Receiver, Ref, Signature,
|
||||
attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Lang, Pair, Receiver, Ref, Signature,
|
||||
Slice, Struct, Ty1, Type, TypeAlias, Var, Variant,
|
||||
};
|
||||
use proc_macro2::{Delimiter, Group, TokenStream, TokenTree};
|
||||
@ -370,7 +370,10 @@ fn parse_extern_fn(cx: &mut Errors, foreign_fn: &ForeignItemFn, lang: Lang) -> R
|
||||
Ok(api_function(ExternFn {
|
||||
lang,
|
||||
doc,
|
||||
ident,
|
||||
ident: Pair {
|
||||
cxx: ident.clone(),
|
||||
rust: ident,
|
||||
},
|
||||
sig: Signature {
|
||||
unsafety,
|
||||
fn_token,
|
||||
|
@ -51,7 +51,8 @@ impl<'a> Types<'a> {
|
||||
}
|
||||
|
||||
let mut type_names = UnorderedSet::new();
|
||||
let mut function_names = UnorderedSet::new();
|
||||
let mut cxx_function_names = UnorderedSet::new();
|
||||
let mut rust_function_names = UnorderedSet::new();
|
||||
for api in apis {
|
||||
// The same identifier is permitted to be declared as both a shared
|
||||
// enum and extern C++ type, or shared struct and extern C++ type.
|
||||
@ -116,9 +117,15 @@ impl<'a> Types<'a> {
|
||||
rust.insert(ident);
|
||||
}
|
||||
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
|
||||
let ident = &efn.ident;
|
||||
if !function_names.insert((&efn.receiver, ident)) {
|
||||
duplicate_name(cx, efn, ident);
|
||||
let cxx_fn = (&efn.receiver, &efn.ident.cxx);
|
||||
let rust_fn = (&efn.receiver, &efn.ident.rust);
|
||||
let cxx_duplicate = !cxx_function_names.insert(cxx_fn);
|
||||
if !rust_function_names.insert(rust_fn) {
|
||||
duplicate_name(cx, efn, &efn.ident.rust);
|
||||
} else if cxx_duplicate {
|
||||
// Insert into cxx_function_names either way, but hide
|
||||
// error if we're already erroring on the rust name.
|
||||
duplicate_name(cx, efn, &efn.ident.cxx);
|
||||
}
|
||||
for arg in &efn.args {
|
||||
visit(&mut all, &arg.ty);
|
||||
|
Loading…
Reference in New Issue
Block a user