Deduplicate handling of TagType and TypedefType in Importer::ConvertType
PiperOrigin-RevId: 433261074
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index 655507a..dbd0d0b 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -939,6 +939,24 @@
.column = sm.getSpellingColumnNumber(loc)};
}
+absl::StatusOr<MappedType> Importer::ConvertTypeDecl(
+ const clang::TypeDecl* decl) const {
+ if (!known_type_decls_.contains(decl)) {
+ return absl::NotFoundError(absl::Substitute(
+ "No generated bindings found for '$0'", decl->getNameAsString()));
+ }
+
+ std::optional<Identifier> id = GetTranslatedIdentifier(decl);
+ if (!id.has_value()) {
+ return absl::UnimplementedError(absl::Substitute(
+ "Cannot translate name of '$0'", decl->getNameAsString()));
+ }
+
+ std::string ident(id->Ident());
+ DeclId decl_id = GenerateDeclId(decl);
+ return MappedType::WithDeclIds(ident, decl_id, ident, decl_id);
+}
+
absl::StatusOr<MappedType> Importer::ConvertType(
const clang::Type* type,
std::optional<devtools_rust::TypeLifetimes>& lifetimes,
@@ -1032,38 +1050,10 @@
}
}
} else if (const auto* tag_type = type->getAsAdjusted<clang::TagType>()) {
- clang::TagDecl* tag_decl = tag_type->getDecl();
-
- // TODO(lukasza): Rather than falling back to `absl::UnimplementedError` at
- // the bottom of this method, we should explicitly emit an error when
- // `tag_decl` is missing from `known_type_decls` or can't be handled by
- // GetTranslatedIdentifier. See also a corresponding TODO in
- // `test_record_with_unsupported_field`.
- if (known_type_decls_.contains(tag_decl)) {
- if (std::optional<Identifier> id = GetTranslatedIdentifier(tag_decl)) {
- std::string ident(id->Ident());
- DeclId decl_id = GenerateDeclId(tag_decl);
- return MappedType::WithDeclIds(ident, decl_id, ident, decl_id);
- }
- }
+ return ConvertTypeDecl(tag_type->getDecl());
} else if (const auto* typedef_type =
type->getAsAdjusted<clang::TypedefType>()) {
- clang::TypedefNameDecl* typedef_name_decl = typedef_type->getDecl();
-
- // TODO(lukasza): Rather than falling back to `absl::UnimplementedError` at
- // the bottom of this method, we should explicitly emit an error when
- // `typedef_name_decl` is missing from `known_type_decls` or can't be
- // handled by GetTranslatedIdentifier. See also a corresponding TODO in
- // `test_record_with_unsupported_field`.
- // TODO(lukasza): Consider merging with `TagType` handling above.
- if (known_type_decls_.contains(typedef_name_decl)) {
- if (std::optional<Identifier> id =
- GetTranslatedIdentifier(typedef_name_decl)) {
- std::string ident(id->Ident());
- DeclId decl_id = GenerateDeclId(typedef_name_decl);
- return MappedType::WithDeclIds(ident, decl_id, ident, decl_id);
- }
- }
+ return ConvertTypeDecl(typedef_type->getDecl());
}
return absl::UnimplementedError(absl::StrCat(
diff --git a/rs_bindings_from_cc/importer.h b/rs_bindings_from_cc/importer.h
index 686d000..788ccf6 100644
--- a/rs_bindings_from_cc/importer.h
+++ b/rs_bindings_from_cc/importer.h
@@ -179,6 +179,7 @@
const clang::Type* type,
std::optional<devtools_rust::TypeLifetimes>& lifetimes,
bool nullable) const;
+ absl::StatusOr<MappedType> ConvertTypeDecl(const clang::TypeDecl* decl) const;
SourceLoc ConvertSourceLocation(clang::SourceLocation loc) const;
diff --git a/rs_bindings_from_cc/ir_from_cc_test.rs b/rs_bindings_from_cc/ir_from_cc_test.rs
index 80f0312..fa91dab 100644
--- a/rs_bindings_from_cc/ir_from_cc_test.rs
+++ b/rs_bindings_from_cc/ir_from_cc_test.rs
@@ -743,15 +743,12 @@
};
"#,
)?;
- // TODO(lukasza): Fix the error message below - saying that clang::Type
- // class 'Record' is unsupported is incorrect (see also a corresponding
- // TODO in Importer::ConvertType).
assert_ir_matches!(
ir,
quote! {
UnsupportedItem(UnsupportedItem {
name: "StructWithUnsupportedField",
- message: "UNIMPLEMENTED: Type of field 'my_field' is not supported: Unsupported type 'union MyUnion': Unsupported clang::Type class 'Record'",
+ message: "UNIMPLEMENTED: Type of field 'my_field' is not supported: Unsupported type 'union MyUnion': No generated bindings found for 'MyUnion'",
...
})
}
diff --git a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs
index 55d7f5d..a09f066 100644
--- a/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs
+++ b/rs_bindings_from_cc/test/golden/user_of_unsupported_rs_api.rs
@@ -17,7 +17,7 @@
// rs_bindings_from_cc/test/golden/user_of_unsupported.h;l=10
// Error while generating bindings for item 'UseUnsupportedType':
-// Parameter #0 is not supported: Unsupported type 'ns::StructInNamespace *': Unsupported type 'ns::StructInNamespace': Unsupported clang::Type class 'Elaborated'
+// Parameter #0 is not supported: Unsupported type 'ns::StructInNamespace *': Unsupported type 'ns::StructInNamespace': No generated bindings found for 'StructInNamespace'
// CRUBIT_RS_BINDINGS_FROM_CC_TEST_GOLDEN_USER_OF_UNSUPPORTED_H_