Don't import private structs, even indirectly as part of template instantiation!
PiperOrigin-RevId: 478948147
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index 2a319e4..54f2fea 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -564,7 +564,34 @@
return result;
}
+/// Returns true if a decl is inside a private section, or is inside a
+/// RecordDecl which is IsTransitivelyInPrivate.
+bool IsTransitivelyInPrivate(clang::Decl* decl_to_check) {
+ while (true) {
+ auto* parent =
+ llvm::dyn_cast<clang::CXXRecordDecl>(decl_to_check->getDeclContext());
+ if (parent == nullptr) {
+ return false;
+ }
+ switch (decl_to_check->getAccess()) {
+ case clang::AccessSpecifier::AS_public:
+ break;
+ case clang::AccessSpecifier::AS_none:
+ if (!parent->isClass()) {
+ break;
+ }
+ [[fallthrough]];
+ case clang::AccessSpecifier::AS_private:
+ case clang::AccessSpecifier::AS_protected:
+ return true;
+ }
+
+ decl_to_check = parent;
+ }
+}
+
std::optional<IR::Item> Importer::ImportDecl(clang::Decl* decl) {
+ if (IsTransitivelyInPrivate(decl)) return std::nullopt;
std::optional<IR::Item> result;
for (auto& importer : decl_importers_) {
if (importer->CanImport(decl)) {
diff --git a/rs_bindings_from_cc/src_code_gen.rs b/rs_bindings_from_cc/src_code_gen.rs
index ac8f005..2745e15 100644
--- a/rs_bindings_from_cc/src_code_gen.rs
+++ b/rs_bindings_from_cc/src_code_gen.rs
@@ -7431,6 +7431,30 @@
}
#[test]
+ fn test_private_struct_not_present() -> Result<()> {
+ let ir = ir_from_cc(&with_lifetime_macros(
+ r#"#pragma clang lifetime_elision
+ template <typename T> class MyTemplate {};
+ class HasPrivateType {
+ private:
+ struct PrivateType {
+ using Foo = MyTemplate<PrivateType>;
+ Foo* get();
+ };
+ protected:
+ HasPrivateType(MyTemplate<PrivateType> x) {}
+ };"#,
+ ))?;
+ let rs_api = generate_bindings_tokens(ir)?.rs_api;
+
+ assert_rs_not_matches!(
+ rs_api,
+ quote! { __CcTemplateInst10MyTemplateIN14HasPrivateType11PrivateTypeEE }
+ );
+ Ok(())
+ }
+
+ #[test]
fn test_implicit_template_specializations_are_sorted_by_mangled_name() -> Result<()> {
let bindings = generate_bindings_tokens(ir_from_cc(
r#"
diff --git a/rs_bindings_from_cc/test/golden/private_method_rs_api.rs b/rs_bindings_from_cc/test/golden/private_method_rs_api.rs
index d311c0e..7ea7b98 100644
--- a/rs_bindings_from_cc/test/golden/private_method_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/private_method_rs_api.rs
@@ -46,10 +46,6 @@
// Error while generating bindings for item 'Outer::operator=':
// Parameter #0 is not supported: Unsupported type 'class Outer &&': Unsupported type: && without lifetime
-// rs_bindings_from_cc/test/golden/private_method.h;l=19
-// Error while generating bindings for item 'Outer::Inner':
-// Nested classes are not supported yet
-
// THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_PRIVATE_METHOD_H_
const _: () = assert!(::std::mem::size_of::<Option<&i32>>() == ::std::mem::size_of::<&i32>());
diff --git a/rs_bindings_from_cc/test/golden/templates.h b/rs_bindings_from_cc/test/golden/templates.h
index 615e09d..9976140 100644
--- a/rs_bindings_from_cc/test/golden/templates.h
+++ b/rs_bindings_from_cc/test/golden/templates.h
@@ -126,4 +126,18 @@
} // namespace forward_declared_template
+namespace private_classes {
+
+class HasPrivateType {
+ private:
+ struct PrivateType {
+ using Foo = test_namespace_bindings::MyTemplate<PrivateType>;
+ Foo* get();
+ };
+
+ protected:
+ HasPrivateType(test_namespace_bindings::MyTemplate<PrivateType> x) {}
+};
+} // namespace private_classes
+
#endif // THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_H_
diff --git a/rs_bindings_from_cc/test/golden/templates_rs_api.rs b/rs_bindings_from_cc/test/golden/templates_rs_api.rs
index 16f2d25..5b8e06e 100644
--- a/rs_bindings_from_cc/test/golden/templates_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/templates_rs_api.rs
@@ -193,6 +193,116 @@
// namespace forward_declared_template
+pub mod private_classes {
+ #[::ctor::recursively_pinned]
+ #[repr(C)]
+ pub struct HasPrivateType {
+ __non_field_data: [::std::mem::MaybeUninit<u8>; 1],
+ }
+ forward_declare::unsafe_define!(
+ forward_declare::symbol!("HasPrivateType"),
+ crate::private_classes::HasPrivateType
+ );
+
+ impl<'b> ::ctor::CtorNew<&'b crate::private_classes::HasPrivateType> for HasPrivateType {
+ type CtorType = impl ::ctor::Ctor<Output = Self> + ::ctor::Captures<'b>;
+ #[inline(always)]
+ fn ctor_new(args: &'b crate::private_classes::HasPrivateType) -> Self::CtorType {
+ let __param_0 = args;
+ unsafe {
+ ::ctor::FnCtor::new(
+ move |dest: ::std::pin::Pin<
+ &mut ::std::mem::MaybeUninit<crate::private_classes::HasPrivateType>,
+ >| {
+ crate::detail::__rust_thunk___ZN15private_classes14HasPrivateTypeC1ERKS0_(
+ ::std::pin::Pin::into_inner_unchecked(dest),
+ __param_0,
+ );
+ },
+ )
+ }
+ }
+ }
+ impl<'b> ::ctor::CtorNew<(&'b crate::private_classes::HasPrivateType,)> for HasPrivateType {
+ type CtorType = impl ::ctor::Ctor<Output = Self> + ::ctor::Captures<'b>;
+ #[inline(always)]
+ fn ctor_new(args: (&'b crate::private_classes::HasPrivateType,)) -> Self::CtorType {
+ let (arg,) = args;
+ <Self as ::ctor::CtorNew<&'b crate::private_classes::HasPrivateType>>::ctor_new(arg)
+ }
+ }
+
+ impl<'b> ::ctor::CtorNew<::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>>
+ for HasPrivateType
+ {
+ type CtorType = impl ::ctor::Ctor<Output = Self> + ::ctor::Captures<'b>;
+ #[inline(always)]
+ fn ctor_new(
+ args: ::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,
+ ) -> Self::CtorType {
+ let __param_0 = args;
+ unsafe {
+ ::ctor::FnCtor::new(
+ move |dest: ::std::pin::Pin<
+ &mut ::std::mem::MaybeUninit<crate::private_classes::HasPrivateType>,
+ >| {
+ crate::detail::__rust_thunk___ZN15private_classes14HasPrivateTypeC1EOS0_(
+ ::std::pin::Pin::into_inner_unchecked(dest),
+ __param_0,
+ );
+ },
+ )
+ }
+ }
+ }
+ impl<'b> ::ctor::CtorNew<(::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,)>
+ for HasPrivateType
+ {
+ type CtorType = impl ::ctor::Ctor<Output = Self> + ::ctor::Captures<'b>;
+ #[inline(always)]
+ fn ctor_new(
+ args: (::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,),
+ ) -> Self::CtorType {
+ let (arg,) = args;
+ <Self as ::ctor::CtorNew<
+ ::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,
+ >>::ctor_new(arg)
+ }
+ }
+
+ impl<'b> ::ctor::Assign<&'b crate::private_classes::HasPrivateType> for HasPrivateType {
+ #[inline(always)]
+ fn assign<'a>(
+ self: ::std::pin::Pin<&'a mut Self>,
+ __param_0: &'b crate::private_classes::HasPrivateType,
+ ) {
+ unsafe {
+ crate::detail::__rust_thunk___ZN15private_classes14HasPrivateTypeaSERKS0_(
+ self, __param_0,
+ );
+ }
+ }
+ }
+
+ impl<'b> ::ctor::Assign<::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>>
+ for HasPrivateType
+ {
+ #[inline(always)]
+ fn assign<'a>(
+ self: ::std::pin::Pin<&'a mut Self>,
+ __param_0: ::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,
+ ) {
+ unsafe {
+ crate::detail::__rust_thunk___ZN15private_classes14HasPrivateTypeaSEOS0_(
+ self, __param_0,
+ );
+ }
+ }
+ }
+}
+
+// namespace private_classes
+
// THIRD_PARTY_CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_TEMPLATES_H_
#[derive(Clone, Copy)]
@@ -966,6 +1076,22 @@
>(
i: Option<::std::pin::Pin<&'a mut crate::__CcTemplateInst18MyTopLevelTemplateIiE>>,
);
+ pub(crate) fn __rust_thunk___ZN15private_classes14HasPrivateTypeC1ERKS0_<'a, 'b>(
+ __this: &'a mut ::std::mem::MaybeUninit<crate::private_classes::HasPrivateType>,
+ __param_0: &'b crate::private_classes::HasPrivateType,
+ );
+ pub(crate) fn __rust_thunk___ZN15private_classes14HasPrivateTypeC1EOS0_<'a, 'b>(
+ __this: &'a mut ::std::mem::MaybeUninit<crate::private_classes::HasPrivateType>,
+ __param_0: ::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,
+ );
+ pub(crate) fn __rust_thunk___ZN15private_classes14HasPrivateTypeaSERKS0_<'a, 'b>(
+ __this: ::std::pin::Pin<&'a mut crate::private_classes::HasPrivateType>,
+ __param_0: &'b crate::private_classes::HasPrivateType,
+ ) -> ::std::pin::Pin<&'a mut crate::private_classes::HasPrivateType>;
+ pub(crate) fn __rust_thunk___ZN15private_classes14HasPrivateTypeaSEOS0_<'a, 'b>(
+ __this: ::std::pin::Pin<&'a mut crate::private_classes::HasPrivateType>,
+ __param_0: ::ctor::RvalueReference<'b, crate::private_classes::HasPrivateType>,
+ ) -> ::std::pin::Pin<&'a mut crate::private_classes::HasPrivateType>;
pub(crate) fn __rust_thunk___ZN23test_namespace_bindings10MyTemplateI14DifferentScopeEC1Ev__2f_2fthird_5fparty_2fcrubit_2frs_5fbindings_5ffrom_5fcc_2ftest_2fgolden_3atemplates_5fcc<
'a,
>(
@@ -1238,6 +1364,15 @@
static_assertions::assert_not_impl_any!(crate::test_namespace_bindings::TemplateParam: Drop);
};
+const _: () = assert!(::std::mem::size_of::<crate::private_classes::HasPrivateType>() == 1);
+const _: () = assert!(::std::mem::align_of::<crate::private_classes::HasPrivateType>() == 1);
+const _: () = {
+ static_assertions::assert_not_impl_any!(crate::private_classes::HasPrivateType: Copy);
+};
+const _: () = {
+ static_assertions::assert_not_impl_any!(crate::private_classes::HasPrivateType: Drop);
+};
+
const _: () = assert!(
::std::mem::size_of::<
crate::__CcTemplateInstN23test_namespace_bindings10MyTemplateI14DifferentScopeEE,
diff --git a/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc b/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
index 47db5d8..9d871bb 100644
--- a/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
+++ b/rs_bindings_from_cc/test/golden/templates_rs_api_impl.cc
@@ -217,6 +217,28 @@
return template_template_params::MyTemplate<
template_template_params::Policy>::GetPolicy();
}
+extern "C" void __rust_thunk___ZN15private_classes14HasPrivateTypeC1ERKS0_(
+ class private_classes::HasPrivateType* __this,
+ const class private_classes::HasPrivateType* __param_0) {
+ crubit::construct_at(__this, *__param_0);
+}
+extern "C" void __rust_thunk___ZN15private_classes14HasPrivateTypeC1EOS0_(
+ class private_classes::HasPrivateType* __this,
+ class private_classes::HasPrivateType* __param_0) {
+ crubit::construct_at(__this, std::move(*__param_0));
+}
+extern "C" class private_classes::HasPrivateType*
+__rust_thunk___ZN15private_classes14HasPrivateTypeaSERKS0_(
+ class private_classes::HasPrivateType* __this,
+ const class private_classes::HasPrivateType* __param_0) {
+ return &__this->operator=(*__param_0);
+}
+extern "C" class private_classes::HasPrivateType*
+__rust_thunk___ZN15private_classes14HasPrivateTypeaSEOS0_(
+ class private_classes::HasPrivateType* __this,
+ class private_classes::HasPrivateType* __param_0) {
+ return &__this->operator=(std::move(*__param_0));
+}
static_assert(sizeof(struct DifferentScope) == 1);
static_assert(alignof(struct DifferentScope) == 1);
@@ -312,4 +334,7 @@
static_assert(alignof(class template_template_params::MyTemplate<
template_template_params::Policy>) == 1);
+static_assert(sizeof(class private_classes::HasPrivateType) == 1);
+static_assert(alignof(class private_classes::HasPrivateType) == 1);
+
#pragma clang diagnostic pop