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()) {