Allow aliases and C++ opaque types to be trivial.

This change allows aliases:
  type Foo = bindgen::Bar;
and C++ opaque types:
  type Foo;
to declare that they're 'trivial' in the sense that:

* They have trivial move constructors
* They have no destructors

and therefore may be passed and owned by value in Rust.

A subsequent commit will add C++ static assertions.

This commit is a BREAKING CHANGE as it requires existing
ExternTypes to gain a new associated type
diff --git a/syntax/check.rs b/syntax/check.rs
index 147984e..cfac236 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -338,6 +338,7 @@
         || cx.types.cxx.contains(ident)
             && !cx.types.structs.contains_key(ident)
             && !cx.types.enums.contains_key(ident)
+            && !cx.types.required_trivial_aliases.contains(ident)
         || cx.types.rust.contains(ident)
 }
 
@@ -376,7 +377,11 @@
             } else if cx.types.enums.contains_key(ident) {
                 "enum".to_owned()
             } else if cx.types.cxx.contains(ident) {
-                "C++ type".to_owned()
+                if cx.types.required_trivial_aliases.contains(ident) {
+                    "trivial C++ type".to_owned()
+                } else {
+                    "non-trivial C++ type".to_owned()
+                }
             } else if cx.types.rust.contains(ident) {
                 "opaque Rust type".to_owned()
             } else if Atom::from(ident) == Some(CxxString) {
diff --git a/syntax/types.rs b/syntax/types.rs
index 8a86a46..ff78268 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -14,6 +14,7 @@
     pub rust: Set<&'a Ident>,
     pub aliases: Map<&'a Ident, &'a TypeAlias>,
     pub untrusted: Map<&'a Ident, &'a ExternType>,
+    pub required_trivial_aliases: Set<&'a Ident>,
 }
 
 impl<'a> Types<'a> {
@@ -135,6 +136,55 @@
             }
         }
 
+        // All these APIs may contain types passed by value. We need to ensure
+        // we check that this is permissible. We do this _after_ scanning all
+        // the APIs above, in case some function or struct references a type
+        // which is declared subsequently.
+        let mut required_trivial_aliases = Set::new();
+
+        fn insist_alias_types_are_trivial<'c>(
+            required_trivial_aliases: &mut Set<&'c Ident>,
+            aliases: &Map<&'c Ident, &'c TypeAlias>,
+            ty: &'c Type,
+        ) {
+            if let Type::Ident(ident) = ty {
+                if aliases.contains_key(ident) {
+                    required_trivial_aliases.insert(ident);
+                }
+            }
+        }
+
+        for api in apis {
+            match api {
+                Api::Struct(strct) => {
+                    for field in &strct.fields {
+                        insist_alias_types_are_trivial(
+                            &mut required_trivial_aliases,
+                            &aliases,
+                            &field.ty,
+                        );
+                    }
+                }
+                Api::CxxFunction(efn) | Api::RustFunction(efn) => {
+                    for arg in &efn.args {
+                        insist_alias_types_are_trivial(
+                            &mut required_trivial_aliases,
+                            &aliases,
+                            &arg.ty,
+                        );
+                    }
+                    if let Some(ret) = &efn.ret {
+                        insist_alias_types_are_trivial(
+                            &mut required_trivial_aliases,
+                            &aliases,
+                            &ret,
+                        );
+                    }
+                }
+                _ => {}
+            }
+        }
+
         Types {
             all,
             structs,
@@ -143,6 +193,7 @@
             rust,
             aliases,
             untrusted,
+            required_trivial_aliases,
         }
     }