Merge `TypeMapper` back into `Importer` - part 4/N: `ConvertQualType`.
This CL is one of steps toward merging `TypeMapper` back into
`Importer`. The merge is:
- possible (after https://github.com/google/crubit/commit/16a5610d96eda5720bb57b5f927b00f00635ddf0 which means that there is only 1 instance
of `TypeMapper`, because `ImportFields` doesn't anymore need to
temporarily assume that the containing record can be imported),
- desirable (to support b/228868369 we need to let `ConvertType` call
into `Importer::ConvertTemplateSpecializationType`).
This CL moves the `TypeMapper::ConvertQualType` method into a method of
`Importer`. This requires also moving `ConvertType` and
`ConvertTypeDecl` methods.
PiperOrigin-RevId: 451510529
diff --git a/rs_bindings_from_cc/decl_importer.h b/rs_bindings_from_cc/decl_importer.h
index 253415b..4022fcf 100644
--- a/rs_bindings_from_cc/decl_importer.h
+++ b/rs_bindings_from_cc/decl_importer.h
@@ -70,24 +70,8 @@
TypeMapper(const TypeMapper& other) = default;
TypeMapper& operator=(const TypeMapper& other) = default;
- // Converts the Clang type `qual_type` into an equivalent `MappedType`.
- // Lifetimes for the type can optionally be specified using `lifetimes`.
- // If `qual_type` is a pointer type, `nullable` specifies whether the
- // pointer can be null.
- // TODO(b/209390498): Currently, we're able to specify nullability only for
- // top-level pointers. Extend this so that we can specify nullability for
- // all pointers contained in `qual_type`, in the same way that `lifetimes`
- // specifies lifetimes for all these pointers. Once this is done, make sure
- // that all callers pass in the appropriate information, derived from
- // nullability annotations.
- absl::StatusOr<MappedType> ConvertQualType(
- clang::QualType qual_type,
- std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
- bool nullable = true) const;
- absl::StatusOr<MappedType> ConvertType(
- const clang::Type* type,
- std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
- bool nullable) const;
+ // TODO(b/209390498): This method doesn't use any member variables or member
+ // functions - it should be a static method or a free function instead.
std::optional<absl::string_view> MapKnownCcTypeToRsType(
absl::string_view cc_type) const;
@@ -96,7 +80,6 @@
// disappear when TypeMapper class is removed / once TypeMapper is merged back
// into Importer.
friend class Importer;
- absl::StatusOr<MappedType> ConvertTypeDecl(const clang::TypeDecl* decl) const;
bool Contains(const clang::TypeDecl* decl) const {
return known_type_decls_.contains(
@@ -108,7 +91,10 @@
clang::cast<clang::TypeDecl>(decl->getCanonicalDecl()));
}
+ // TODO(b/209390498): The `ctx_` field is unused - it will disappear when
+ // TypeMapper class is removed / once TypeMapper is merged back into Importer.
const clang::ASTContext* ctx_;
+
absl::flat_hash_set<const clang::TypeDecl*> known_type_decls_;
};
@@ -171,6 +157,21 @@
// Converts a Clang source location to IR.
virtual SourceLoc ConvertSourceLocation(clang::SourceLocation loc) const = 0;
+ // Converts the Clang type `qual_type` into an equivalent `MappedType`.
+ // Lifetimes for the type can optionally be specified using `lifetimes`.
+ // If `qual_type` is a pointer type, `nullable` specifies whether the
+ // pointer can be null.
+ // TODO(b/209390498): Currently, we're able to specify nullability only for
+ // top-level pointers. Extend this so that we can specify nullability for
+ // all pointers contained in `qual_type`, in the same way that `lifetimes`
+ // specifies lifetimes for all these pointers. Once this is done, make sure
+ // that all callers pass in the appropriate information, derived from
+ // nullability annotations.
+ virtual absl::StatusOr<MappedType> ConvertQualType(
+ clang::QualType qual_type,
+ std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+ bool nullable = true) const = 0;
+
// Converts `type` into a MappedType, after first importing the Record behind
// the template instantiation.
virtual absl::StatusOr<MappedType> ConvertTemplateSpecializationType(
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index 3d193fd..d132772 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -609,12 +609,12 @@
type_string, import_status.message()));
}
- return type_mapper_.ConvertTypeDecl(specialization_decl);
+ return ConvertTypeDecl(specialization_decl);
}
-absl::StatusOr<MappedType> TypeMapper::ConvertTypeDecl(
+absl::StatusOr<MappedType> Importer::ConvertTypeDecl(
const clang::TypeDecl* decl) const {
- if (!known_type_decls_.contains(decl)) {
+ if (!HasBeenAlreadySuccessfullyImported(decl)) {
return absl::NotFoundError(absl::Substitute(
"No generated bindings found for '$0'", decl->getNameAsString()));
}
@@ -623,14 +623,14 @@
return MappedType::WithDeclId(decl_id);
}
-absl::StatusOr<MappedType> TypeMapper::ConvertType(
+absl::StatusOr<MappedType> Importer::ConvertType(
const clang::Type* type,
std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
bool nullable) const {
// Qualifiers are handled separately in ConvertQualType().
std::string type_string = clang::QualType(type, 0).getAsString();
- if (auto maybe_mapped_type = MapKnownCcTypeToRsType(type_string);
+ if (auto maybe_mapped_type = type_mapper_.MapKnownCcTypeToRsType(type_string);
maybe_mapped_type.has_value()) {
return MappedType::Simple(std::string(*maybe_mapped_type), type_string);
} else if (type->isPointerType() || type->isLValueReferenceType() ||
@@ -717,7 +717,7 @@
break;
default:
if (builtin_type->isIntegerType()) {
- auto size = ctx_->getTypeSize(builtin_type);
+ auto size = ctx_.getTypeSize(builtin_type);
if (size == 8 || size == 16 || size == 32 || size == 64) {
return MappedType::Simple(
absl::Substitute(
@@ -745,7 +745,7 @@
"Unsupported clang::Type class '", type->getTypeClassName(), "'"));
}
-absl::StatusOr<MappedType> TypeMapper::ConvertQualType(
+absl::StatusOr<MappedType> Importer::ConvertQualType(
clang::QualType qual_type,
std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
bool nullable) const {
diff --git a/rs_bindings_from_cc/importer.h b/rs_bindings_from_cc/importer.h
index 0cb2365..d4a182a 100644
--- a/rs_bindings_from_cc/importer.h
+++ b/rs_bindings_from_cc/importer.h
@@ -73,6 +73,10 @@
llvm::Optional<std::string> GetComment(
const clang::Decl* decl) const override;
SourceLoc ConvertSourceLocation(clang::SourceLocation loc) const override;
+ absl::StatusOr<MappedType> ConvertQualType(
+ clang::QualType qual_type,
+ std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+ bool nullable = true) const override;
absl::StatusOr<MappedType> ConvertTemplateSpecializationType(
const clang::TemplateSpecializationType* type) override;
void MarkAsSuccessfullyImported(const clang::TypeDecl* decl) override;
@@ -95,6 +99,12 @@
// Stores the comments of this target in source order.
void ImportFreeComments();
+ absl::StatusOr<MappedType> ConvertType(
+ const clang::Type* type,
+ std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
+ bool nullable) const;
+ absl::StatusOr<MappedType> ConvertTypeDecl(const clang::TypeDecl* decl) const;
+
std::vector<std::unique_ptr<DeclImporter>> decl_importers_;
std::unique_ptr<clang::MangleContext> mangler_;
absl::flat_hash_map<const clang::Decl*, std::optional<IR::Item>>
diff --git a/rs_bindings_from_cc/importers/cxx_record.cc b/rs_bindings_from_cc/importers/cxx_record.cc
index d2e0908..7225883 100644
--- a/rs_bindings_from_cc/importers/cxx_record.cc
+++ b/rs_bindings_from_cc/importers/cxx_record.cc
@@ -152,7 +152,7 @@
for (const clang::FieldDecl* field_decl : record_decl->fields()) {
std::optional<clang::tidy::lifetimes::ValueLifetimes> no_lifetimes;
absl::StatusOr<MappedType> type =
- ictx_.type_mapper_.ConvertQualType(field_decl->getType(), no_lifetimes);
+ ictx_.ConvertQualType(field_decl->getType(), no_lifetimes);
clang::AccessSpecifier access = field_decl->getAccess();
if (access == clang::AS_none) {
diff --git a/rs_bindings_from_cc/importers/enum.cc b/rs_bindings_from_cc/importers/enum.cc
index 1589391..e08d0a9 100644
--- a/rs_bindings_from_cc/importers/enum.cc
+++ b/rs_bindings_from_cc/importers/enum.cc
@@ -31,7 +31,7 @@
}
std::optional<clang::tidy::lifetimes::ValueLifetimes> no_lifetimes;
absl::StatusOr<MappedType> type =
- ictx_.type_mapper_.ConvertQualType(cc_type, no_lifetimes);
+ ictx_.ConvertQualType(cc_type, no_lifetimes);
if (!type.ok()) {
return ictx_.ImportUnsupportedItem(enum_decl, type.status().ToString());
}
diff --git a/rs_bindings_from_cc/importers/function.cc b/rs_bindings_from_cc/importers/function.cc
index 237facb..a90dc46 100644
--- a/rs_bindings_from_cc/importers/function.cc
+++ b/rs_bindings_from_cc/importers/function.cc
@@ -40,9 +40,9 @@
if (lifetimes) {
this_lifetimes = lifetimes->GetThisLifetimes();
}
- auto param_type = ictx_.type_mapper_.ConvertQualType(
- method_decl->getThisType(), this_lifetimes,
- /*nullable=*/false);
+ auto param_type =
+ ictx_.ConvertQualType(method_decl->getThisType(), this_lifetimes,
+ /*nullable=*/false);
if (!param_type.ok()) {
add_error(absl::StrCat("`this` parameter is not supported: ",
param_type.status().message()));
@@ -62,8 +62,7 @@
if (lifetimes) {
param_lifetimes = lifetimes->GetParamLifetimes(i);
}
- auto param_type =
- ictx_.type_mapper_.ConvertQualType(param->getType(), param_lifetimes);
+ auto param_type = ictx_.ConvertQualType(param->getType(), param_lifetimes);
if (!param_type.ok()) {
add_error(absl::Substitute("Parameter #$0 is not supported: $1", i,
param_type.status().message()));
@@ -120,8 +119,8 @@
return_lifetimes = lifetimes->GetReturnLifetimes();
}
- auto return_type = ictx_.type_mapper_.ConvertQualType(
- function_decl->getReturnType(), return_lifetimes);
+ auto return_type =
+ ictx_.ConvertQualType(function_decl->getReturnType(), return_lifetimes);
if (!return_type.ok()) {
add_error(absl::StrCat("Return type is not supported: ",
return_type.status().message()));
diff --git a/rs_bindings_from_cc/importers/typedef_name.cc b/rs_bindings_from_cc/importers/typedef_name.cc
index 4d366c1..dfc31f8 100644
--- a/rs_bindings_from_cc/importers/typedef_name.cc
+++ b/rs_bindings_from_cc/importers/typedef_name.cc
@@ -41,7 +41,7 @@
underlying_type = ictx_.ConvertTemplateSpecializationType(tst_type);
} else {
std::optional<clang::tidy::lifetimes::ValueLifetimes> no_lifetimes;
- underlying_type = ictx_.type_mapper_.ConvertQualType(
+ underlying_type = ictx_.ConvertQualType(
typedef_name_decl->getUnderlyingType(), no_lifetimes);
}
if (underlying_type.ok()) {