[rs_bindings_from_cc] Use `FunctionLifetimes` when converting function types.
Previously, the code here would essentially work on the raw lifetimes array,
which only happens to work and isn't type-safe.
To make sure we treat lifetimes in a type-safe way, add an assertion to
`Importer::ConvertType()`.
PiperOrigin-RevId: 546942043
Change-Id: I1a9d7920ded69b0258740cd0b6a76dc974484e55
diff --git a/lifetime_annotations/type_lifetimes.cc b/lifetime_annotations/type_lifetimes.cc
index d886a39..275f967 100644
--- a/lifetime_annotations/type_lifetimes.cc
+++ b/lifetime_annotations/type_lifetimes.cc
@@ -548,6 +548,7 @@
const FunctionLifetimes& ValueLifetimes::GetFuncLifetimes() const {
assert(clang::isa<clang::FunctionProtoType>(type_));
+ assert(function_lifetimes_);
return *function_lifetimes_;
}
diff --git a/rs_bindings_from_cc/importer.cc b/rs_bindings_from_cc/importer.cc
index df5004a..259c6a0 100644
--- a/rs_bindings_from_cc/importer.cc
+++ b/rs_bindings_from_cc/importer.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <algorithm>
+#include <cassert>
#include <cstddef>
#include <iterator>
#include <map>
@@ -756,6 +757,21 @@
return MappedType::WithDeclId(decl_id);
}
+static bool IsSameCanonicalUnqualifiedType(clang::QualType type1,
+ clang::QualType type2) {
+ type1 = type1.getCanonicalType().getUnqualifiedType();
+ type2 = type2.getCanonicalType().getUnqualifiedType();
+
+ // `DeducedType::getDeducedType()` can return null, in which case we don't
+ // have a more canonical representation. If this happens, optimistically
+ // assume the types are equal.
+ if (clang::isa<clang::DeducedType>(type1) ||
+ clang::isa<clang::DeducedType>(type2))
+ return true;
+
+ return type1 == type2;
+}
+
absl::StatusOr<MappedType> Importer::ConvertType(
const clang::Type* type,
std::optional<clang::tidy::lifetimes::ValueLifetimes>& lifetimes,
@@ -763,6 +779,10 @@
// Qualifiers are handled separately in ConvertQualType().
std::string type_string = clang::QualType(type, 0).getAsString();
+ assert(!lifetimes.has_value() ||
+ IsSameCanonicalUnqualifiedType(lifetimes->Type(),
+ clang::QualType(type, 0)));
+
if (auto override_type = GetTypeMapOverride(*type);
override_type.has_value()) {
return *std::move(override_type);
@@ -788,15 +808,23 @@
CRUBIT_ASSIGN_OR_RETURN(
absl::string_view rs_abi,
ConvertCcCallConvIntoRsAbi(func_type->getCallConv()));
- CRUBIT_ASSIGN_OR_RETURN(MappedType mapped_return_type,
- ConvertQualType(func_type->getReturnType(),
- lifetimes, ref_qualifier_kind));
+ std::optional<clang::tidy::lifetimes::ValueLifetimes> return_lifetimes;
+ if (lifetimes.has_value())
+ return_lifetimes = lifetimes->GetFuncLifetimes().GetReturnLifetimes();
+ CRUBIT_ASSIGN_OR_RETURN(
+ MappedType mapped_return_type,
+ ConvertQualType(func_type->getReturnType(), return_lifetimes,
+ ref_qualifier_kind));
std::vector<MappedType> mapped_param_types;
- for (const clang::QualType& param_type : func_type->getParamTypes()) {
+ for (unsigned i = 0; i < func_type->getNumParams(); ++i) {
+ std::optional<clang::tidy::lifetimes::ValueLifetimes> param_lifetimes;
+ if (lifetimes.has_value())
+ param_lifetimes = lifetimes->GetFuncLifetimes().GetParamLifetimes(i);
CRUBIT_ASSIGN_OR_RETURN(
MappedType mapped_param_type,
- ConvertQualType(param_type, lifetimes, ref_qualifier_kind));
+ ConvertQualType(func_type->getParamType(i), param_lifetimes,
+ ref_qualifier_kind));
mapped_param_types.push_back(std::move(mapped_param_type));
}