// Mangled symbol arrangements: // // (a) One-off internal symbol. // pattern: {CXXBRIDGE} $ {NAME} // examples: // - cxxbridge1$exception // defining characteristics: // - 2 segments // - starts with cxxbridge // // (b) Behavior on a builtin binding without generic parameter. // pattern: {CXXBRIDGE} $ {TYPE} $ {NAME} // examples: // - cxxbridge1$string$len // defining characteristics: // - 3 segments // - starts with cxxbridge // // (c) Behavior on a builtin binding with generic parameter. // pattern: {CXXBRIDGE} $ {TYPE} $ {PARAM...} $ {NAME} // examples: // - cxxbridge1$box$org$rust$Struct$alloc // - cxxbridge1$unique_ptr$std$vector$u8$drop // defining characteristics: // - 4+ segments // - starts with cxxbridge // // (d) User-defined extern function. // pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {NAME} // examples: // - cxxbridge1$new_client // - org$rust$cxxbridge1$new_client // defining characteristics: // - cxxbridge is second from end // FIXME: conflict with (a) if they collide with one of our one-off symbol names in the global namespace // // (e) User-defined extern member function. // pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE} $ {NAME} // examples: // - org$cxxbridge1$Struct$get // defining characteristics: // - cxxbridge is third from end // FIXME: conflict with (b) if e.g. user binds a type in global namespace that collides with our builtin type names // // (f) Operator overload. // pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE} $ operator $ {NAME} // examples: // - org$rust$cxxbridge1$Struct$operator$eq // defining characteristics: // - second segment from end is `operator` (not possible in type or namespace names) // // (g) Closure trampoline. // pattern: {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE?} $ {NAME} $ {ARGUMENT} $ {DIRECTION} // examples: // - org$rust$cxxbridge1$Struct$invoke$f$0 // defining characteristics: // - last symbol is `0` (C half) or `1` (Rust half) which are not legal identifiers on their own // // // Mangled preprocessor variable arrangements: // // (A) One-off internal variable. // pattern: {CXXBRIDGE} _ {NAME} // examples: // - CXXBRIDGE1_PANIC // - CXXBRIDGE1_RUST_STRING // defining characteristics: // - NAME does not begin with STRUCT or ENUM // // (B) Guard around user-defined type. // pattern: {CXXBRIDGE} _ {STRUCT or ENUM} _ {NAMESPACE...} $ {TYPE} // examples: // - CXXBRIDGE1_STRUCT_org$rust$Struct // - CXXBRIDGE1_ENUM_Enabled use crate::syntax::symbol::{self, Symbol}; use crate::syntax::{ExternFn, Pair, Types}; const CXXBRIDGE: &str = "cxxbridge1"; macro_rules! join { ($($segment:expr),+ $(,)?) => { symbol::join(&[$(&$segment),+]) }; } pub fn extern_fn(efn: &ExternFn, types: &Types) -> Symbol { match &efn.receiver { Some(receiver) => { let receiver_ident = types.resolve(&receiver.ty); join!( efn.name.namespace, CXXBRIDGE, receiver_ident.name.cxx, efn.name.rust, ) } None => join!(efn.name.namespace, CXXBRIDGE, efn.name.rust), } } pub fn operator(receiver: &Pair, operator: &'static str) -> Symbol { join!( receiver.namespace, CXXBRIDGE, receiver.cxx, "operator", operator, ) } // The C half of a function pointer trampoline. pub fn c_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol { join!(extern_fn(efn, types), var.rust, 0) } // The Rust half of a function pointer trampoline. pub fn r_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol { join!(extern_fn(efn, types), var.rust, 1) }