Support enum repr types from std::os::raw
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 9d673c6..c6d59d8 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -9,8 +9,8 @@
 use crate::syntax::symbol::Symbol;
 use crate::syntax::trivial::{self, TrivialReason};
 use crate::syntax::{
-    derive, mangle, Api, Doc, Enum, ExternFn, ExternType, Pair, Signature, Struct, Trait, Type,
-    TypeAlias, Types, Var,
+    derive, mangle, Api, Doc, Enum, EnumRepr, ExternFn, ExternType, Pair, Signature, Struct, Trait,
+    Type, TypeAlias, Types, Var,
 };
 use proc_macro2::Ident;
 
@@ -317,8 +317,12 @@
 }
 
 fn write_enum_decl(out: &mut OutFile, enm: &Enum) {
+    let repr = match &enm.repr {
+        EnumRepr::Foreign { .. } => return,
+        EnumRepr::Native { atom, .. } => *atom,
+    };
     write!(out, "enum class {} : ", enm.name.cxx);
-    write_atom(out, enm.repr);
+    write_atom(out, repr);
     writeln!(out, ";");
 }
 
@@ -376,6 +380,10 @@
 }
 
 fn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
+    let repr = match &enm.repr {
+        EnumRepr::Foreign { .. } => return,
+        EnumRepr::Native { atom, .. } => *atom,
+    };
     out.set_namespace(&enm.name.namespace);
     let guard = format!("CXXBRIDGE1_ENUM_{}", enm.name.to_symbol());
     writeln!(out, "#ifndef {}", guard);
@@ -384,7 +392,7 @@
         writeln!(out, "//{}", line);
     }
     write!(out, "enum class {} : ", enm.name.cxx);
-    write_atom(out, enm.repr);
+    write_atom(out, repr);
     writeln!(out, " {{");
     for variant in &enm.variants {
         for line in variant.doc.to_string().lines() {
@@ -397,6 +405,10 @@
 }
 
 fn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
+    let repr = match &enm.repr {
+        EnumRepr::Foreign { .. } => return,
+        EnumRepr::Native { atom, .. } => *atom,
+    };
     out.set_namespace(&enm.name.namespace);
     out.include.type_traits = true;
     writeln!(
@@ -405,11 +417,11 @@
         enm.name.cxx,
     );
     write!(out, "static_assert(sizeof({}) == sizeof(", enm.name.cxx);
-    write_atom(out, enm.repr);
+    write_atom(out, repr);
     writeln!(out, "), \"incorrect size\");");
     for variant in &enm.variants {
         write!(out, "static_assert(static_cast<");
-        write_atom(out, enm.repr);
+        write_atom(out, repr);
         writeln!(
             out,
             ">({}::{}) == {}, \"disagrees with the value in #[cxx::bridge]\");",
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index e2fa646..3a8c87e 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -293,7 +293,7 @@
     let ident = &enm.name.rust;
     let doc = &enm.doc;
     let attrs = &enm.attrs;
-    let repr = enm.repr;
+    let repr = &enm.repr;
     let type_id = type_id(&enm.name);
     let variants = enm.variants.iter().map(|variant| {
         let doc = &variant.doc;
diff --git a/syntax/mod.rs b/syntax/mod.rs
index b22587f..1d98634 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -36,7 +36,7 @@
 use proc_macro2::{Ident, Span};
 use syn::punctuated::Punctuated;
 use syn::token::{Brace, Bracket, Paren};
-use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Token, Type as RustType};
+use syn::{Attribute, Expr, Generics, Lifetime, LitInt, Path, Token, Type as RustType};
 
 pub use self::atom::Atom;
 pub use self::derive::{Derive, Trait};
@@ -113,11 +113,15 @@
     pub variants: Vec<Variant>,
     pub variants_from_header: bool,
     pub variants_from_header_attr: Option<Attribute>,
-    pub repr: Atom,
-    pub repr_type: Type,
+    pub repr: EnumRepr,
     pub explicit_repr: bool,
 }
 
+pub enum EnumRepr {
+    Native { atom: Atom, repr_type: Type },
+    Foreign { rust_type: Path },
+}
+
 pub struct ExternFn {
     pub lang: Lang,
     pub doc: Doc,
diff --git a/syntax/parse.rs b/syntax/parse.rs
index bcf75ef..32d36eb 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -4,9 +4,9 @@
 use crate::syntax::report::Errors;
 use crate::syntax::Atom::*;
 use crate::syntax::{
-    attrs, error, Api, Array, Derive, Doc, Enum, ExternFn, ExternType, ForeignName, Impl, Include,
-    IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr, Receiver, Ref, Signature,
-    SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,
+    attrs, error, Api, Array, Derive, Doc, Enum, EnumRepr, ExternFn, ExternType, ForeignName, Impl,
+    Include, IncludeKind, Lang, Lifetimes, NamedType, Namespace, Pair, Ptr, Receiver, Ref,
+    Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var, Variant,
 };
 use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree};
 use quote::{format_ident, quote, quote_spanned};
@@ -241,6 +241,10 @@
     let name = pair(namespace, &item.ident, cxx_name, rust_name);
     let repr_ident = Ident::new(repr.as_ref(), Span::call_site());
     let repr_type = Type::Ident(NamedType::new(repr_ident));
+    let repr = EnumRepr::Native {
+        atom: repr,
+        repr_type,
+    };
     let generics = Lifetimes {
         lt_token: None,
         lifetimes: Punctuated::new(),
@@ -262,7 +266,6 @@
         variants_from_header,
         variants_from_header_attr,
         repr,
-        repr_type,
         explicit_repr,
     })
 }
diff --git a/syntax/tokens.rs b/syntax/tokens.rs
index b0c2f20..33f20fa 100644
--- a/syntax/tokens.rs
+++ b/syntax/tokens.rs
@@ -1,7 +1,7 @@
 use crate::syntax::atom::Atom::*;
 use crate::syntax::{
-    Array, Atom, Derive, Enum, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr, Receiver,
-    Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
+    Array, Atom, Derive, Enum, EnumRepr, ExternFn, ExternType, Impl, Lifetimes, NamedType, Ptr,
+    Receiver, Ref, Signature, SliceRef, Struct, Ty1, Type, TypeAlias, Var,
 };
 use proc_macro2::{Ident, Span, TokenStream};
 use quote::{quote_spanned, ToTokens};
@@ -280,6 +280,15 @@
     }
 }
 
+impl ToTokens for EnumRepr {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        match self {
+            EnumRepr::Native { atom, repr_type: _ } => atom.to_tokens(tokens),
+            EnumRepr::Foreign { rust_type } => rust_type.to_tokens(tokens),
+        }
+    }
+}
+
 impl ToTokens for NamedType {
     fn to_tokens(&self, tokens: &mut TokenStream) {
         let NamedType { rust, generics } = self;
diff --git a/syntax/types.rs b/syntax/types.rs
index c8d3398..c54682b 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -7,7 +7,7 @@
 use crate::syntax::trivial::{self, TrivialReason};
 use crate::syntax::visit::{self, Visit};
 use crate::syntax::{
-    toposort, Api, Atom, Enum, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
+    toposort, Api, Atom, Enum, EnumRepr, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
 };
 use proc_macro2::Ident;
 use quote::ToTokens;
@@ -88,7 +88,12 @@
                     add_resolution(&strct.name, &strct.generics);
                 }
                 Api::Enum(enm) => {
-                    all.insert(&enm.repr_type);
+                    match &enm.repr {
+                        EnumRepr::Native { atom: _, repr_type } => {
+                            all.insert(repr_type);
+                        }
+                        EnumRepr::Foreign { rust_type: _ } => {}
+                    }
                     let ident = &enm.name.rust;
                     if !type_names.insert(ident)
                         && (!cxx.contains(ident)