Allow namespace override.

This change allows a

 #[namespace (namespace = A::B)]

attribute for each item in a cxx::bridge.

We now have a fair number of different types of name floating
around:
* C++ identifiers
* C++ fully-qualified names
* Rust identifiers
* Rust fully-qualified names (future, when we support sub-modules)
* Items with both a Rust and C++ name (a 'Pair')
* Types with only a known Rust name, which can be resolved to a
  C++ name.

This change attempts to put some sensible names for all these
things in syntax/mod.rs, and so that would be a good place to start
review.

At the moment, the Namespace (included in each CppName)
is ruthlessly cloned all over the place. As a given namespace is
likely to be applicable to many types and functions, it may
save significant memory in future to use Rc<> here. But let's not
optimise too early.
diff --git a/syntax/impls.rs b/syntax/impls.rs
index 6a177d5..a83ce74 100644
--- a/syntax/impls.rs
+++ b/syntax/impls.rs
@@ -1,8 +1,13 @@
-use crate::syntax::{ExternFn, Impl, Receiver, Ref, Signature, Slice, Ty1, Type};
+use crate::syntax::{
+    Api, CppName, ExternFn, Impl, Namespace, Pair, Receiver, Ref, ResolvableName, Signature, Slice,
+    Symbol, Ty1, Type, Types,
+};
+use proc_macro2::{Ident, Span};
 use std::borrow::Borrow;
 use std::hash::{Hash, Hasher};
 use std::mem;
 use std::ops::{Deref, DerefMut};
+use syn::Token;
 
 impl Deref for ExternFn {
     type Target = Signature;
@@ -274,3 +279,84 @@
         &self.ty
     }
 }
+
+impl Pair {
+    /// Use this constructor when the item can't have a different
+    /// name in Rust and C++. For cases where #[rust_name] and similar
+    /// attributes can be used, construct the object by hand.
+    pub fn new(ns: Namespace, ident: Ident) -> Self {
+        Self {
+            rust: ident.clone(),
+            cxx: CppName::new(ns, ident),
+        }
+    }
+}
+
+impl ResolvableName {
+    pub fn new(ident: Ident) -> Self {
+        Self { rust: ident }
+    }
+
+    pub fn from_pair(pair: Pair) -> Self {
+        Self { rust: pair.rust }
+    }
+
+    pub fn make_self(span: Span) -> Self {
+        Self {
+            rust: Token![Self](span).into(),
+        }
+    }
+
+    pub fn is_self(&self) -> bool {
+        self.rust == "Self"
+    }
+
+    pub fn span(&self) -> Span {
+        self.rust.span()
+    }
+
+    pub fn to_symbol(&self, types: &Types) -> Symbol {
+        types.resolve(self).to_symbol()
+    }
+}
+
+impl Api {
+    pub fn get_namespace(&self) -> Option<&Namespace> {
+        match self {
+            Api::CxxFunction(cfn) => Some(&cfn.ident.cxx.ns),
+            Api::CxxType(cty) => Some(&cty.ident.cxx.ns),
+            Api::Enum(enm) => Some(&enm.ident.cxx.ns),
+            Api::Struct(strct) => Some(&strct.ident.cxx.ns),
+            Api::RustType(rty) => Some(&rty.ident.cxx.ns),
+            Api::RustFunction(rfn) => Some(&rfn.ident.cxx.ns),
+            Api::Impl(_) | Api::Include(_) | Api::TypeAlias(_) => None,
+        }
+    }
+}
+
+impl CppName {
+    pub fn new(ns: Namespace, ident: Ident) -> Self {
+        Self { ns, ident }
+    }
+
+    fn iter_all_segments(
+        &self,
+    ) -> std::iter::Chain<std::slice::Iter<Ident>, std::iter::Once<&Ident>> {
+        self.ns.iter().chain(std::iter::once(&self.ident))
+    }
+
+    fn join(&self, sep: &str) -> String {
+        self.iter_all_segments()
+            .map(|s| s.to_string())
+            .collect::<Vec<_>>()
+            .join(sep)
+    }
+
+    pub fn to_symbol(&self) -> Symbol {
+        Symbol::from_idents(self.iter_all_segments())
+    }
+
+    pub fn to_fully_qualified(&self) -> String {
+        format!("::{}", self.join("::"))
+    }
+}