Avoid `struct SomeClass` in `..._rs_api_impl.cc`.

After this CL, `..._rs_api_impl.cc` will reflect/preserve whether the
type was a `struct` or a `class`.  This helps avoid `-Wmismatched-tags`
warnings.

PiperOrigin-RevId: 460334053
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index 110a6fe..bc7ce9f 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -1100,13 +1100,7 @@
                     // Regular field
                     Ok(_rs_type) => Some(field.offset + field.size),
                     // Opaque field
-                    Err(_error) => {
-                        if record.is_union {
-                            Some(field.size)
-                        } else {
-                            None
-                        }
-                    }
+                    Err(_error) => if record.is_union() { Some(field.size) } else { None },
                 },
                 vec![format!(
                     "{} : {} bits",
@@ -1142,7 +1136,7 @@
 
             if let Some((Some(prev_field), _, Some(prev_end), _)) = prev {
                 assert!(
-                    record.is_union || prev_end <= offset,
+                    record.is_union() || prev_end <= offset,
                     "Unexpected offset+size for field {:?} in record {}",
                     prev_field,
                     record.cc_name
@@ -1163,7 +1157,7 @@
             // its original type).
             //
             // We also don't need padding if we're in a union.
-            let padding_size_in_bits = if record.is_union
+            let padding_size_in_bits = if record.is_union()
                 || (field.is_some() && get_field_rs_type_for_layout(field.unwrap()).is_ok())
             {
                 0
@@ -1223,7 +1217,7 @@
                         )
                     })?;
                     let mut formatted = quote! {#type_kind};
-                    if should_implement_drop(record) || record.is_union {
+                    if should_implement_drop(record) || record.is_union() {
                         if needs_manually_drop(db, rs_type.clone())? {
                             // TODO(b/212690698): Avoid (somewhat unergonomic) ManuallyDrop
                             // if we can ask Rust to preserve field destruction order if the
@@ -1248,7 +1242,7 @@
 
     let size = Literal::usize_unsuffixed(record.size);
     let alignment = Literal::usize_unsuffixed(record.alignment);
-    let field_offset_assertions = if record.is_union {
+    let field_offset_assertions = if record.is_union() {
         // TODO(https://github.com/Gilnaa/memoffset/issues/66): generate assertions for unions once
         // offsetof supports them.
         vec![]
@@ -1296,7 +1290,7 @@
     } else {
         quote! {#[derive( #(#derives),* )]}
     };
-    let record_kind = if record.is_union {
+    let record_kind = if record.is_union() {
         quote! { union }
     } else {
         quote! { struct }
@@ -1343,7 +1337,7 @@
     // type must be an *aggregate* type.
     //
     // TODO(b/232969667): Protect unions from direct initialization, too.
-    let allow_direct_init = record.is_aggregate || record.is_union;
+    let allow_direct_init = record.is_aggregate || record.is_union();
     let head_padding = if head_padding > 0 || !allow_direct_init {
         let n = proc_macro2::Literal::usize_unsuffixed(head_padding);
         quote! {
@@ -1459,7 +1453,7 @@
 }
 
 fn should_derive_clone(record: &Record) -> bool {
-    if record.is_union {
+    if record.is_union() {
         // `union`s (unlike `struct`s) should only derive `Clone` if they are `Copy`.
         should_derive_copy(record)
     } else {
@@ -2304,7 +2298,7 @@
         Item::Record(record) => {
             let ident = format_cc_ident(&record.cc_name);
             let namespace_qualifier = generate_namespace_qualifier(record.id, ir)?;
-            let tag_kind = tag_kind(record);
+            let tag_kind = cc_tag_kind(record);
             quote! { #tag_kind #(#namespace_qualifier::)*  #ident }
         }
         Item::TypeAlias(type_alias) => {
@@ -2316,11 +2310,11 @@
     })
 }
 
-fn tag_kind(record: &ir::Record) -> TokenStream {
-    if record.is_union {
-        quote! { union }
-    } else {
-        quote! { class }
+fn cc_tag_kind(record: &ir::Record) -> TokenStream {
+    match record.record_type {
+        RecordType::Struct => quote! { struct },
+        RecordType::Union => quote! { union },
+        RecordType::Class => quote! { class },
     }
 }
 
@@ -2415,7 +2409,7 @@
     let namespace_qualifier = quote! { #(#namespace_qualifier::)* };
     let size = Literal::usize_unsuffixed(record.size);
     let alignment = Literal::usize_unsuffixed(record.alignment);
-    let tag_kind = tag_kind(record);
+    let tag_kind = cc_tag_kind(record);
     let field_assertions = record
         .fields
         .iter()
@@ -2849,7 +2843,7 @@
         assert_cc_matches!(
             rs_api_impl,
             quote! {
-                extern "C" class ReturnStruct __rust_thunk___Z11DoSomething11ParamStruct(class ParamStruct param) {
+                extern "C" struct ReturnStruct __rust_thunk___Z11DoSomething11ParamStruct(struct ParamStruct param) {
                     return DoSomething(std::forward<decltype(param)>(param));
                 }
             }
@@ -2918,7 +2912,7 @@
             quote! {
                 extern "C"
                 int __rust_thunk___ZN10MyTemplateIiE8GetValueEv__2f_2ftest_3atesting_5ftarget(
-                        class MyTemplate<int>* __this) {
+                        struct MyTemplate<int>* __this) {
                     return __this->GetValue();
                 }
             }
@@ -3028,7 +3022,7 @@
         assert_cc_matches!(
             rs_api_impl,
             quote! {
-                extern "C" void __rust_thunk___ZN10SomeStructD1Ev(class SomeStruct * __this) {
+                extern "C" void __rust_thunk___ZN10SomeStructD1Ev(struct SomeStruct * __this) {
                     std :: destroy_at (std::forward<decltype(__this)>(__this)) ;
                 }
             }
@@ -3036,22 +3030,43 @@
         assert_cc_matches!(
             rs_api_impl,
             quote! {
-                static_assert(sizeof(class SomeStruct) == 12);
-                static_assert(alignof(class SomeStruct) == 4);
-                static_assert(CRUBIT_OFFSET_OF(public_int, class SomeStruct) == 0);
+                static_assert(sizeof(struct SomeStruct) == 12);
+                static_assert(alignof(struct SomeStruct) == 4);
+                static_assert(CRUBIT_OFFSET_OF(public_int, struct SomeStruct) == 0);
             }
         );
         Ok(())
     }
 
     #[test]
+    fn test_struct_vs_class() -> Result<()> {
+        let ir = ir_from_cc(&tokens_to_string(quote! {
+            struct SomeStruct final { int field; };
+            class SomeClass final { int field; };
+        })?)?;
+        let BindingsTokens { rs_api, rs_api_impl } = generate_bindings_tokens(ir)?;
+
+        // A Rust `struct` is generated for both `SomeStruct` and `SomeClass`.
+        assert_rs_matches!(rs_api, quote! { pub struct SomeStruct },);
+        assert_rs_matches!(rs_api, quote! { pub struct SomeClass },);
+
+        // But in C++ we still should refer to `struct SomeStruct` and `class
+        // SomeClass`. See also b/238212337.
+        assert_cc_matches!(rs_api_impl, quote! { struct SomeStruct * __this });
+        assert_cc_matches!(rs_api_impl, quote! { class SomeClass * __this });
+        assert_cc_matches!(rs_api_impl, quote! { static_assert(sizeof(struct SomeStruct) == 4); });
+        assert_cc_matches!(rs_api_impl, quote! { static_assert(sizeof(class SomeClass) == 4); });
+        Ok(())
+    }
+
+    #[test]
     fn test_ref_to_struct_in_thunk_impls() -> Result<()> {
-        let ir = ir_from_cc("struct S{}; inline void foo(class S& s) {} ")?;
+        let ir = ir_from_cc("struct S{}; inline void foo(S& s) {} ")?;
         let rs_api_impl = generate_bindings_tokens(ir)?.rs_api_impl;
         assert_cc_matches!(
             rs_api_impl,
             quote! {
-                extern "C" void __rust_thunk___Z3fooR1S(class S& s) {
+                extern "C" void __rust_thunk___Z3fooR1S(struct S& s) {
                     foo(std::forward<decltype(s)>(s));
                 }
             }
@@ -3061,12 +3076,12 @@
 
     #[test]
     fn test_const_ref_to_struct_in_thunk_impls() -> Result<()> {
-        let ir = ir_from_cc("struct S{}; inline void foo(const class S& s) {} ")?;
+        let ir = ir_from_cc("struct S{}; inline void foo(const S& s) {} ")?;
         let rs_api_impl = generate_bindings_tokens(ir)?.rs_api_impl;
         assert_cc_matches!(
             rs_api_impl,
             quote! {
-                extern "C" void __rust_thunk___Z3fooRK1S(const class S& s) {
+                extern "C" void __rust_thunk___Z3fooRK1S(const struct S& s) {
                     foo(std::forward<decltype(s)>(s));
                 }
             }
@@ -3120,7 +3135,7 @@
             generate_bindings_tokens(ir)?.rs_api_impl,
             quote! {
                 extern "C" int __rust_thunk___ZNK10SomeStruct9some_funcEi(
-                        const class SomeStruct* __this, int arg) {
+                        const struct SomeStruct* __this, int arg) {
                     return __this->some_func(std::forward<decltype(arg)>(arg));
                 }
             }
@@ -4638,7 +4653,7 @@
         assert_cc_matches!(
             generate_bindings_tokens(ir)?.rs_api_impl,
             quote! {
-                extern "C" void __rust_thunk___ZN11Polymorphic3FooEv(class Polymorphic * __this)
+                extern "C" void __rust_thunk___ZN11Polymorphic3FooEv(struct Polymorphic * __this)
             }
         );
         Ok(())
@@ -4857,7 +4872,7 @@
             rs_api_impl,
             quote! {
                 extern "C" void __rust_thunk___ZN20DefaultedConstructorC1Ev(
-                        class DefaultedConstructor* __this) {
+                        struct DefaultedConstructor* __this) {
                     crubit::construct_at (std::forward<decltype(__this)>(__this)) ;
                 }
             }
@@ -5048,7 +5063,7 @@
             rs_api_impl,
             quote! {
                 extern "C" bool __rust_thunk___ZNK10SomeStructeqERKS_(
-                        const class SomeStruct* __this, const class SomeStruct& other) {
+                        const struct SomeStruct* __this, const struct SomeStruct& other) {
                     return __this->operator==(std::forward<decltype(other)>(other));
                 }
             }
@@ -5603,7 +5618,7 @@
         let rs_api_impl = generate_bindings_tokens(ir)?.rs_api_impl;
         assert_cc_matches!(
             rs_api_impl,
-            quote! { static_assert(CRUBIT_OFFSET_OF(dyn, class type) ... ) }
+            quote! { static_assert(CRUBIT_OFFSET_OF(dyn, struct type) ... ) }
         );
         Ok(())
     }
@@ -5993,10 +6008,10 @@
                 }
                 ...
                 extern "C" void __rust_thunk___ZN23test_namespace_bindings1SC1Ev(
-                    class test_namespace_bindings::S* __this) {...}
+                    struct test_namespace_bindings::S* __this) {...}
                 ...
                 extern "C" void __rust_thunk___Z4useSN23test_namespace_bindings1SE(
-                    class test_namespace_bindings::S s) { useS(std::forward<decltype(s)>(s)); }
+                    struct test_namespace_bindings::S s) { useS(std::forward<decltype(s)>(s)); }
                 ...
             }
         );
@@ -6105,12 +6120,12 @@
             &bindings.rs_api_impl,
             quote! {
                 ...
-                extern "C" void #my_struct_bool_constructor(class MyStruct<bool>*__this) {...} ...
-                extern "C" void #my_struct_double_constructor(class MyStruct<double>*__this) {...} ...
-                extern "C" void #my_struct_int_constructor(class MyStruct<int>*__this) {...} ...
-                extern "C" bool #my_struct_bool_method(class MyStruct<bool>*__this) {...} ...
-                extern "C" double #my_struct_double_method(class MyStruct<double>*__this) {...} ...
-                extern "C" int #my_struct_int_method(class MyStruct<int>*__this) {...} ...
+                extern "C" void #my_struct_bool_constructor(struct MyStruct<bool>*__this) {...} ...
+                extern "C" void #my_struct_double_constructor(struct MyStruct<double>*__this) {...} ...
+                extern "C" void #my_struct_int_constructor(struct MyStruct<int>*__this) {...} ...
+                extern "C" bool #my_struct_bool_method(struct MyStruct<bool>*__this) {...} ...
+                extern "C" double #my_struct_double_method(struct MyStruct<double>*__this) {...} ...
+                extern "C" int #my_struct_int_method(struct MyStruct<int>*__this) {...} ...
             }
         );
         Ok(())