Return `StatusOr` with type payload for failed type conversions
PiperOrigin-RevId: 397268707
diff --git a/rs_bindings_from_cc/ast_visitor.cc b/rs_bindings_from_cc/ast_visitor.cc
index 521aa53..f4d5a26 100644
--- a/rs_bindings_from_cc/ast_visitor.cc
+++ b/rs_bindings_from_cc/ast_visitor.cc
@@ -23,6 +23,9 @@
namespace rs_bindings_from_cc {
+constexpr std::string_view kTypeStatusPayloadUrl =
+ "type.googleapis.com/devtools.rust.cc_interop.rs_binding_from_cc.type";
+
bool AstVisitor::TraverseDecl(clang::Decl* decl) {
if (seen_decls_.insert(decl->getCanonicalDecl()).second) {
return Base::TraverseDecl(decl);
@@ -46,7 +49,7 @@
for (const clang::ParmVarDecl* param : function_decl->parameters()) {
auto param_type =
ConvertType(param->getType(), function_decl->getASTContext());
- if (!param_type.has_value()) {
+ if (!param_type.ok()) {
// TODO(b/200239975): Add diagnostics for declarations we can't import
return true;
}
@@ -55,7 +58,7 @@
auto return_type = ConvertType(function_decl->getReturnType(),
function_decl->getASTContext());
- if (!return_type.has_value()) {
+ if (!return_type.ok()) {
return true;
}
ir_.functions.push_back(Func{
@@ -96,7 +99,7 @@
}
for (const clang::FieldDecl* field_decl : record_decl->fields()) {
auto type = ConvertType(field_decl->getType(), field_decl->getASTContext());
- if (!type.has_value()) {
+ if (!type.ok()) {
// TODO(b/200239975): Add diagnostics for declarations we can't import
return true;
}
@@ -112,12 +115,14 @@
return true;
}
-std::optional<Type> AstVisitor::ConvertType(
+absl::StatusOr<Type> AstVisitor::ConvertType(
clang::QualType qual_type, const clang::ASTContext& ctx) const {
+ std::string type_string = qual_type.getAsString();
+
if (const clang::PointerType* pointer_type =
qual_type->getAs<clang::PointerType>()) {
auto pointee_type = ConvertType(pointer_type->getPointeeType(), ctx);
- if (pointee_type.has_value()) {
+ if (pointee_type.ok()) {
return Type::PointerTo(*pointee_type);
}
} else if (const clang::BuiltinType* builtin_type =
@@ -128,14 +133,17 @@
return Type{
absl::Substitute("$0$1",
builtin_type->isSignedInteger() ? 'i' : 'u', size),
- qual_type.getAsString()};
+ type_string};
}
}
if (builtin_type->isVoidType()) {
return Type::Void();
}
}
- return std::nullopt;
+ absl::Status error = absl::UnimplementedError(
+ absl::Substitute("Unsupported type '$0'", type_string));
+ error.SetPayload(kTypeStatusPayloadUrl, absl::Cord(type_string));
+ return error;
}
std::string AstVisitor::GetMangledName(
diff --git a/rs_bindings_from_cc/ast_visitor.h b/rs_bindings_from_cc/ast_visitor.h
index 8880595..e08d504 100644
--- a/rs_bindings_from_cc/ast_visitor.h
+++ b/rs_bindings_from_cc/ast_visitor.h
@@ -10,6 +10,7 @@
#include "rs_bindings_from_cc/ir.h"
#include "third_party/absl/container/flat_hash_set.h"
+#include "third_party/absl/status/statusor.h"
#include "third_party/absl/strings/string_view.h"
#include "third_party/absl/types/span.h"
#include "third_party/llvm/llvm-project/clang/include/clang/AST/Decl.h"
@@ -43,8 +44,8 @@
private:
std::string GetMangledName(const clang::NamedDecl* named_decl) const;
Identifier GetTranslatedName(const clang::NamedDecl* named_decl) const;
- std::optional<Type> ConvertType(clang::QualType qual_type,
- const clang::ASTContext& ctx) const;
+ absl::StatusOr<Type> ConvertType(clang::QualType qual_type,
+ const clang::ASTContext& ctx) const;
absl::Span<const absl::string_view> public_header_names_;
IR& ir_;