Parse #![variants_from_header] inner attribute
diff --git a/syntax/attrs.rs b/syntax/attrs.rs
index 0ced368..a1ad03c 100644
--- a/syntax/attrs.rs
+++ b/syntax/attrs.rs
@@ -4,8 +4,8 @@
 use crate::syntax::{Derive, Doc, ForeignName};
 use proc_macro2::{Ident, TokenStream};
 use quote::ToTokens;
-use syn::parse::{ParseStream, Parser as _};
-use syn::{Attribute, Error, LitStr, Path, Result, Token};
+use syn::parse::{Nothing, Parse, ParseStream, Parser as _};
+use syn::{AttrStyle, Attribute, Error, LitStr, Path, Result, Token};
 
 // Intended usage:
 //
@@ -33,6 +33,7 @@
     pub namespace: Option<&'a mut Namespace>,
     pub cxx_name: Option<&'a mut Option<ForeignName>>,
     pub rust_name: Option<&'a mut Option<Ident>>,
+    pub variants_from_header: Option<&'a mut bool>,
 
     // Suppress clippy needless_update lint ("struct update has no effect, all
     // the fields in the struct have already been specified") when preemptively
@@ -121,6 +122,17 @@
                     break;
                 }
             }
+        } else if attr.path.is_ident("variants_from_header")
+            && matches!(attr.style, AttrStyle::Inner(_))
+            && cfg!(feature = "experimental")
+        {
+            if let Err(err) = Nothing::parse.parse2(attr.tokens.clone()) {
+                cx.push(err);
+            }
+            if let Some(variants_from_header) = &mut parser.variants_from_header {
+                **variants_from_header = true;
+                continue;
+            }
         } else if attr.path.is_ident("allow")
             || attr.path.is_ident("warn")
             || attr.path.is_ident("deny")
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 96aa4c9..1eae19e 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -111,6 +111,7 @@
     pub generics: Lifetimes,
     pub brace_token: Brace,
     pub variants: Vec<Variant>,
+    pub variants_from_header: bool,
     pub repr: Atom,
     pub repr_type: Type,
     pub explicit_repr: bool,
diff --git a/syntax/parse.rs b/syntax/parse.rs
index f99da89..c17cd6e 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -187,6 +187,7 @@
     let mut namespace = namespace.clone();
     let mut cxx_name = None;
     let mut rust_name = None;
+    let mut variants_from_header = false;
     let attrs = attrs::parse(
         cx,
         item.attrs,
@@ -197,6 +198,7 @@
             namespace: Some(&mut namespace),
             cxx_name: Some(&mut cxx_name),
             rust_name: Some(&mut rust_name),
+            variants_from_header: Some(&mut variants_from_header),
             ..Default::default()
         },
     );
@@ -255,6 +257,7 @@
         generics,
         brace_token,
         variants,
+        variants_from_header,
         repr,
         repr_type,
         explicit_repr,