Use Symbol for mangled names throughout code generators
diff --git a/syntax/mangle.rs b/syntax/mangle.rs
index f2616d2..6f4e0d8 100644
--- a/syntax/mangle.rs
+++ b/syntax/mangle.rs
@@ -1,5 +1,7 @@
 use crate::syntax::namespace::Namespace;
-use crate::syntax::{symbol, ExternFn};
+use crate::syntax::symbol::{self, Symbol};
+use crate::syntax::ExternFn;
+use proc_macro2::Ident;
 
 const CXXBRIDGE: &str = "cxxbridge02";
 
@@ -9,10 +11,19 @@
     };
 }
 
-pub fn extern_fn(namespace: &Namespace, efn: &ExternFn) -> String {
+pub fn extern_fn(namespace: &Namespace, efn: &ExternFn) -> Symbol {
     match &efn.receiver {
         Some(receiver) => join!(namespace, CXXBRIDGE, receiver.ident, efn.ident),
         None => join!(namespace, CXXBRIDGE, efn.ident),
     }
-    .to_string()
+}
+
+// The C half of a function pointer trampoline.
+pub fn c_trampoline(namespace: &Namespace, efn: &ExternFn, var: &Ident) -> Symbol {
+    join!(extern_fn(namespace, efn), var, 0)
+}
+
+// The Rust half of a function pointer trampoline.
+pub fn r_trampoline(namespace: &Namespace, efn: &ExternFn, var: &Ident) -> Symbol {
+    join!(extern_fn(namespace, efn), var, 1)
 }
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 81b1a2f..49bb299 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -11,7 +11,7 @@
 pub mod namespace;
 mod parse;
 pub mod set;
-mod symbol;
+pub mod symbol;
 mod tokens;
 pub mod types;
 
diff --git a/syntax/symbol.rs b/syntax/symbol.rs
index a40baaf..fa8e587 100644
--- a/syntax/symbol.rs
+++ b/syntax/symbol.rs
@@ -19,6 +19,12 @@
     }
 }
 
+impl From<&Ident> for Symbol {
+    fn from(ident: &Ident) -> Self {
+        Symbol(ident.to_string())
+    }
+}
+
 impl Symbol {
     fn push(&mut self, segment: &dyn Display) {
         let len_before = self.0.len();
@@ -37,7 +43,9 @@
 }
 
 impl Segment for str {}
+impl Segment for usize {}
 impl Segment for Ident {}
+impl Segment for Symbol {}
 
 impl Segment for Namespace {
     fn write(&self, symbol: &mut Symbol) {