1 // Mangled symbol arrangements:
2 //
3 //   (a) One-off internal symbol.
4 //          pattern:  {CXXBRIDGE} $ {NAME}
5 //          examples:
6 //             - cxxbridge1$exception
7 //          defining characteristics:
8 //             - 2 segments
9 //             - starts with cxxbridge
10 //
11 //   (b) Behavior on a builtin binding without generic parameter.
12 //          pattern:  {CXXBRIDGE} $ {TYPE} $ {NAME}
13 //          examples:
14 //             - cxxbridge1$string$len
15 //          defining characteristics:
16 //             - 3 segments
17 //             - starts with cxxbridge
18 //
19 //   (c) Behavior on a builtin binding with generic parameter.
20 //          pattern:  {CXXBRIDGE} $ {TYPE} $ {PARAM...} $ {NAME}
21 //          examples:
22 //             - cxxbridge1$box$org$rust$Struct$alloc
23 //             - cxxbridge1$unique_ptr$std$vector$u8$drop
24 //          defining characteristics:
25 //             - 4+ segments
26 //             - starts with cxxbridge
27 //
28 //   (d) User-defined extern function.
29 //          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {NAME}
30 //          examples:
31 //             - cxxbridge1$new_client
32 //             - org$rust$cxxbridge1$new_client
33 //          defining characteristics:
34 //             - cxxbridge is second from end
35 //          FIXME: conflict with (a) if they collide with one of our one-off symbol names in the global namespace
36 //
37 //   (e) User-defined extern member function.
38 //          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE} $ {NAME}
39 //          examples:
40 //             - org$cxxbridge1$Struct$get
41 //          defining characteristics:
42 //             - cxxbridge is third from end
43 //          FIXME: conflict with (b) if e.g. user binds a type in global namespace that collides with our builtin type names
44 //
45 //   (f) Operator overload.
46 //          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE} $ operator $ {NAME}
47 //          examples:
48 //             - org$rust$cxxbridge1$Struct$operator$eq
49 //          defining characteristics:
50 //             - second segment from end is `operator` (not possible in type or namespace names)
51 //
52 //   (g) Closure trampoline.
53 //          pattern:  {NAMESPACE...} $ {CXXBRIDGE} $ {TYPE?} $ {NAME} $ {ARGUMENT} $ {DIRECTION}
54 //          examples:
55 //             - org$rust$cxxbridge1$Struct$invoke$f$0
56 //          defining characteristics:
57 //             - last symbol is `0` (C half) or `1` (Rust half) which are not legal identifiers on their own
58 //
59 //
60 // Mangled preprocessor variable arrangements:
61 //
62 //   (A) One-off internal variable.
63 //          pattern:  {CXXBRIDGE} _ {NAME}
64 //          examples:
65 //             - CXXBRIDGE1_PANIC
66 //             - CXXBRIDGE1_RUST_STRING
67 //          defining characteristics:
68 //             - NAME does not begin with STRUCT or ENUM
69 //
70 //   (B) Guard around user-defined type.
71 //          pattern:  {CXXBRIDGE} _ {STRUCT or ENUM} _ {NAMESPACE...} $ {TYPE}
72 //          examples:
73 //             - CXXBRIDGE1_STRUCT_org$rust$Struct
74 //             - CXXBRIDGE1_ENUM_Enabled
75 
76 use crate::syntax::symbol::{self, Symbol};
77 use crate::syntax::{ExternFn, Pair, Types};
78 
79 const CXXBRIDGE: &str = "cxxbridge1";
80 
81 macro_rules! join {
82     ($($segment:expr),+ $(,)?) => {
83         symbol::join(&[$(&$segment),+])
84     };
85 }
86 
extern_fn(efn: &ExternFn, types: &Types) -> Symbol87 pub fn extern_fn(efn: &ExternFn, types: &Types) -> Symbol {
88     match &efn.receiver {
89         Some(receiver) => {
90             let receiver_ident = types.resolve(&receiver.ty);
91             join!(
92                 efn.name.namespace,
93                 CXXBRIDGE,
94                 receiver_ident.name.cxx,
95                 efn.name.rust,
96             )
97         }
98         None => join!(efn.name.namespace, CXXBRIDGE, efn.name.rust),
99     }
100 }
101 
operator(receiver: &Pair, operator: &'static str) -> Symbol102 pub fn operator(receiver: &Pair, operator: &'static str) -> Symbol {
103     join!(
104         receiver.namespace,
105         CXXBRIDGE,
106         receiver.cxx,
107         "operator",
108         operator,
109     )
110 }
111 
112 // The C half of a function pointer trampoline.
c_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol113 pub fn c_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol {
114     join!(extern_fn(efn, types), var.rust, 0)
115 }
116 
117 // The Rust half of a function pointer trampoline.
r_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol118 pub fn r_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol {
119     join!(extern_fn(efn, types), var.rust, 1)
120 }
121