Allow wildcard argument names.

This adds support for wildcard variable names by internally giving
them unique names.
diff --git a/syntax/parse.rs b/syntax/parse.rs
index d14806d..a425c56 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -6,9 +6,9 @@
 use quote::{format_ident, quote};
 use syn::punctuated::Punctuated;
 use syn::{
-    Abi, Error, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType, GenericArgument, Item,
-    ItemForeignMod, ItemStruct, Pat, PathArguments, Result, ReturnType, Token, Type as RustType,
-    TypeBareFn, TypePath, TypeReference, TypeSlice,
+    Abi, Error, Fields, FnArg, ForeignItem, ForeignItemFn, ForeignItemType, GenericArgument, Ident,
+    Item, ItemForeignMod, ItemStruct, Pat, PathArguments, Result, ReturnType, Token,
+    Type as RustType, TypeBareFn, TypePath, TypeReference, TypeSlice,
 };
 
 pub mod kw {
@@ -193,6 +193,9 @@
             FnArg::Typed(arg) => {
                 let ident = match arg.pat.as_ref() {
                     Pat::Ident(pat) => pat.ident.clone(),
+                    Pat::Wild(pat) => {
+                        Ident::new(&format!("_{}", args.len()), pat.underscore_token.span)
+                    }
                     _ => return Err(Error::new_spanned(arg, "unsupported signature")),
                 };
                 let ty = parse_type(&arg.ty)?;
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index d2c860e..69ef2b0 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -34,6 +34,8 @@
         fn c_return_ref_vector(c: &C) -> &CxxVector<u8>;
         fn c_return_rust_vec() -> Vec<u8>;
         fn c_return_ref_rust_vec(c: &C) -> &Vec<u8>;
+        fn c_return_identity(_: usize) -> usize;
+        fn c_return_sum(_: usize, _: usize) -> usize;
 
         fn c_take_primitive(n: usize);
         fn c_take_shared(shared: Shared);
@@ -86,6 +88,8 @@
         fn r_return_unique_ptr_string() -> UniquePtr<CxxString>;
         fn r_return_rust_vec() -> Vec<u8>;
         fn r_return_ref_rust_vec(shared: &Shared) -> &Vec<u8>;
+        fn r_return_identity(_: usize) -> usize;
+        fn r_return_sum(_: usize, _: usize) -> usize;
 
         fn r_take_primitive(n: usize);
         fn r_take_shared(shared: Shared);
@@ -184,6 +188,14 @@
     unimplemented!()
 }
 
+fn r_return_identity(n: usize) -> usize {
+    n
+}
+
+fn r_return_sum(n1: usize, n2: usize) -> usize {
+    n1 + n2
+}
+
 fn r_take_primitive(n: usize) {
     assert_eq!(n, 2020);
 }
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index c0b5888..11096ba 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -102,6 +102,14 @@
   throw std::runtime_error("unimplemented");
 }
 
+size_t c_return_identity(size_t n) {
+  return n;
+}
+
+size_t c_return_sum(size_t n1, size_t n2) {
+  return n1 + n2;
+}
+
 void c_take_primitive(size_t n) {
   if (n == 2020) {
     cxx_test_suite_set_correct();
@@ -265,6 +273,8 @@
   ASSERT(std::string(r_return_str(Shared{2020})) == "2020");
   ASSERT(std::string(r_return_rust_string()) == "2020");
   ASSERT(*r_return_unique_ptr_string() == "2020");
+  ASSERT(r_return_identity(2020) == 2020);
+  ASSERT(r_return_sum(2020, 1) == 2021);
 
   r_take_primitive(2020);
   r_take_shared(Shared{2020});
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index 1d617ab..4600d64 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -38,6 +38,8 @@
 const std::vector<uint8_t> &c_return_ref_vector(const C &c);
 rust::Vec<uint8_t> c_return_rust_vec();
 const rust::Vec<uint8_t> &c_return_ref_rust_vec(const C &c);
+size_t c_return_identity(size_t n);
+size_t c_return_sum(size_t n1, size_t n2);
 
 void c_take_primitive(size_t n);
 void c_take_shared(Shared shared);
diff --git a/tests/test.rs b/tests/test.rs
index 07c23bd..4fd52d3 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -49,6 +49,8 @@
             .map(|o| o.z)
             .sum(),
     );
+    assert_eq!(2020, ffi::c_return_identity(2020));
+    assert_eq!(2021, ffi::c_return_sum(2020, 1));
 }
 
 #[test]