Really bad support for struct types as types (in member variables, parameters, etc.) :)
This is necessary in order to support member functions (including special member functions), so that their `this` parameter can be represented.
PiperOrigin-RevId: 402912882
diff --git a/rs_bindings_from_cc/ast_visitor.cc b/rs_bindings_from_cc/ast_visitor.cc
index f88f28c..03618a8 100644
--- a/rs_bindings_from_cc/ast_visitor.cc
+++ b/rs_bindings_from_cc/ast_visitor.cc
@@ -72,6 +72,26 @@
success = false;
continue;
}
+
+ if (const clang::RecordType* record_type =
+ llvm::dyn_cast<clang::RecordType>(param->getType())) {
+ if (clang::RecordDecl* record_decl =
+ llvm::dyn_cast<clang::RecordDecl>(record_type->getDecl())) {
+ // TODO(b/200067242): non-trivial_abi structs, when passed by value,
+ // have a different representation which needs special support. We
+ // currently do not support it.
+ if (!record_decl->canPassInRegisters()) {
+ ir_.items.push_back(UnsupportedItem{
+ .name = function_decl->getQualifiedNameAsString(),
+ .message = absl::Substitute("Non-trivial_abi type '$0' is not "
+ "supported by value as a parameter",
+ param->getType().getAsString()),
+ .source_loc = ConvertSourceLoc(param->getBeginLoc())});
+ success = false;
+ }
+ }
+ }
+
std::optional<Identifier> param_name = GetTranslatedIdentifier(param);
if (!param_name.has_value()) {
ir_.items.push_back(UnsupportedItem{
@@ -84,6 +104,27 @@
params.push_back({*param_type, *std::move(param_name)});
}
+ if (const clang::RecordType* record_return_type =
+ llvm::dyn_cast<clang::RecordType>(function_decl->getReturnType())) {
+ if (clang::RecordDecl* record_decl =
+ llvm::dyn_cast<clang::RecordDecl>(record_return_type->getDecl())) {
+ // TODO(b/200067242): non-trivial_abi structs, when passed by value,
+ // have a different representation which needs special support. We
+ // currently do not support it.
+ if (!record_decl->canPassInRegisters()) {
+ ir_.items.push_back(UnsupportedItem{
+ .name = function_decl->getQualifiedNameAsString(),
+ .message =
+ absl::Substitute("Non-trivial_abi type '$0' is not supported "
+ "by value as a return type",
+ function_decl->getReturnType().getAsString()),
+ .source_loc =
+ ConvertSourceLoc(function_decl->getReturnTypeSourceRange())});
+ success = false;
+ }
+ }
+ }
+
auto return_type = ConvertType(function_decl->getReturnType());
if (!return_type.ok()) {
ir_.items.push_back(UnsupportedItem{
@@ -267,6 +308,10 @@
.column = sm.getSpellingColumnNumber(loc)};
}
+SourceLoc AstVisitor::ConvertSourceLoc(clang::SourceRange range) const {
+ return ConvertSourceLoc(range.getBegin());
+}
+
absl::StatusOr<MappedType> AstVisitor::ConvertType(
clang::QualType qual_type) const {
std::optional<MappedType> type = std::nullopt;
@@ -310,6 +355,15 @@
}
}
}
+ } else if (const clang::TagType* tag_type =
+ qual_type->getAs<clang::TagType>()) {
+ // TODO(b/202692734): If tag_type is un-importable, fail here.
+ clang::TagDecl* tag_decl = tag_type->getDecl();
+
+ if (std::optional<Identifier> id = GetTranslatedIdentifier(tag_decl)) {
+ std::string ident(id->Ident());
+ return MappedType::Simple(ident, ident);
+ }
}
if (!type.has_value()) {