Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 1 | // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| 2 | // Exceptions. See /LICENSE for license information. |
| 3 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 4 | |
| 5 | #include "rs_bindings_from_cc/generate_bindings_and_metadata.h" |
| 6 | |
Marcel Hlopko | 20de6de | 2022-09-13 05:28:08 -0700 | [diff] [blame] | 7 | #include <optional> |
Marcel Hlopko | ab7a228 | 2022-09-05 08:17:41 -0700 | [diff] [blame] | 8 | #include <string> |
Marcel Hlopko | 20de6de | 2022-09-13 05:28:08 -0700 | [diff] [blame] | 9 | #include <utility> |
Dmitri Gribenko | 785831e | 2023-07-14 06:47:36 -0700 | [diff] [blame] | 10 | #include <vector> |
Marcel Hlopko | ab7a228 | 2022-09-05 08:17:41 -0700 | [diff] [blame] | 11 | |
Marcel Hlopko | 20de6de | 2022-09-13 05:28:08 -0700 | [diff] [blame] | 12 | #include "absl/container/flat_hash_map.h" |
| 13 | #include "absl/container/flat_hash_set.h" |
Dmitri Gribenko | 785831e | 2023-07-14 06:47:36 -0700 | [diff] [blame] | 14 | #include "absl/log/check.h" |
Marcel Hlopko | ab7a228 | 2022-09-05 08:17:41 -0700 | [diff] [blame] | 15 | #include "absl/strings/string_view.h" |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 16 | #include "common/status_macros.h" |
Dmitri Gribenko | 785831e | 2023-07-14 06:47:36 -0700 | [diff] [blame] | 17 | #include "rs_bindings_from_cc/cmdline.h" |
Marcel Hlopko | 2ee2391 | 2022-05-09 06:13:55 -0700 | [diff] [blame] | 18 | #include "rs_bindings_from_cc/collect_instantiations.h" |
Rosica Dejanovska | abe406f | 2022-09-02 07:06:50 -0700 | [diff] [blame] | 19 | #include "rs_bindings_from_cc/collect_namespaces.h" |
Marcel Hlopko | ab7a228 | 2022-09-05 08:17:41 -0700 | [diff] [blame] | 20 | #include "rs_bindings_from_cc/ir.h" |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 21 | #include "rs_bindings_from_cc/ir_from_cc.h" |
| 22 | #include "rs_bindings_from_cc/src_code_gen.h" |
| 23 | |
| 24 | namespace crubit { |
| 25 | |
Marcel Hlopko | 20de6de | 2022-09-13 05:28:08 -0700 | [diff] [blame] | 26 | std::optional<const Namespace*> FindNamespace(const IR& ir, |
| 27 | absl::string_view name) { |
| 28 | for (const auto* ns : ir.get_items_if<Namespace>()) { |
| 29 | if (ns->name.Ident() == kInstantiationsNamespaceName) { |
| 30 | return ns; |
| 31 | } |
| 32 | } |
| 33 | return std::nullopt; |
| 34 | } |
| 35 | |
| 36 | std::vector<const Record*> FindInstantiationsInNamespace(const IR& ir, |
| 37 | ItemId namespace_id) { |
| 38 | absl::flat_hash_set<ItemId> record_ids; |
| 39 | for (const auto* type_alias : ir.get_items_if<TypeAlias>()) { |
| 40 | if (type_alias->enclosing_namespace_id.has_value() && |
| 41 | type_alias->enclosing_namespace_id == namespace_id) { |
| 42 | const MappedType* mapped_type = &type_alias->underlying_type; |
| 43 | CHECK(mapped_type->cc_type.decl_id.has_value()); |
| 44 | CHECK(mapped_type->rs_type.decl_id.has_value()); |
| 45 | CHECK(mapped_type->cc_type.decl_id.value() == |
| 46 | mapped_type->rs_type.decl_id.value()); |
| 47 | record_ids.insert(mapped_type->rs_type.decl_id.value()); |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | std::vector<const Record*> result; |
| 52 | for (const auto* record : ir.get_items_if<Record>()) { |
| 53 | if (record_ids.find(record->id) != record_ids.end()) { |
| 54 | result.push_back(record); |
| 55 | } |
| 56 | } |
| 57 | return result; |
| 58 | } |
| 59 | |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 60 | absl::StatusOr<BindingsAndMetadata> GenerateBindingsAndMetadata( |
Rosica Dejanovska | af348cc | 2022-08-30 05:54:16 -0700 | [diff] [blame] | 61 | Cmdline& cmdline, std::vector<std::string> clang_args, |
| 62 | absl::flat_hash_map<const HeaderName, const std::string> |
Lukasz Anforowicz | 121338a | 2022-11-01 14:28:32 -0700 | [diff] [blame] | 63 | virtual_headers_contents_for_testing) { |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 64 | std::vector<absl::string_view> clang_args_view; |
| 65 | clang_args_view.insert(clang_args_view.end(), clang_args.begin(), |
| 66 | clang_args.end()); |
| 67 | |
Devin Jeanpierre | 96bf0bd | 2022-10-04 20:32:15 -0700 | [diff] [blame] | 68 | CRUBIT_ASSIGN_OR_RETURN( |
| 69 | std::vector<std::string> requested_instantiations, |
| 70 | CollectInstantiations(cmdline.srcs_to_scan_for_instantiations())); |
Marcel Hlopko | 2ee2391 | 2022-05-09 06:13:55 -0700 | [diff] [blame] | 71 | |
| 72 | CRUBIT_ASSIGN_OR_RETURN( |
Devin Jeanpierre | b0af4dc | 2023-04-27 06:59:25 -0700 | [diff] [blame] | 73 | IR ir, IrFromCc({.current_target = cmdline.current_target(), |
| 74 | .public_headers = cmdline.public_headers(), |
| 75 | .virtual_headers_contents_for_testing = |
| 76 | std::move(virtual_headers_contents_for_testing), |
| 77 | .headers_to_targets = cmdline.headers_to_targets(), |
| 78 | .extra_rs_srcs = cmdline.extra_rs_srcs(), |
| 79 | .clang_args = clang_args_view, |
| 80 | .extra_instantiations = requested_instantiations, |
| 81 | .crubit_features = cmdline.target_to_features()})); |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 82 | |
Marcel Hlopko | b4d5d8e | 2022-11-16 03:15:00 -0800 | [diff] [blame] | 83 | if (!cmdline.instantiations_out().empty()) { |
Devin Jeanpierre | 9704789 | 2023-01-11 01:54:53 -0800 | [diff] [blame] | 84 | ir.crate_root_path = "__cc_template_instantiations_rs_api"; |
Marcel Hlopko | b4d5d8e | 2022-11-16 03:15:00 -0800 | [diff] [blame] | 85 | } |
| 86 | |
Michael VanBemmel | f5cbdf4 | 2022-10-14 17:00:11 -0700 | [diff] [blame] | 87 | bool generate_error_report = !cmdline.error_report_out().empty(); |
| 88 | CRUBIT_ASSIGN_OR_RETURN( |
| 89 | Bindings bindings, |
Jing Lu | 7ac3e67 | 2023-09-27 11:48:35 -0700 | [diff] [blame] | 90 | GenerateBindings(ir, cmdline.crubit_support_path_format(), |
Lukasz Anforowicz | 5bf4943 | 2022-12-12 12:17:24 -0800 | [diff] [blame] | 91 | cmdline.clang_format_exe_path(), |
Michael VanBemmel | f5cbdf4 | 2022-10-14 17:00:11 -0700 | [diff] [blame] | 92 | cmdline.rustfmt_exe_path(), |
Googler | 69e0963 | 2023-03-03 12:18:35 -0800 | [diff] [blame] | 93 | cmdline.rustfmt_config_path(), generate_error_report, |
| 94 | cmdline.generate_source_location_in_doc_comment())); |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 95 | |
Marcel Hlopko | c31d95a | 2022-09-09 05:17:32 -0700 | [diff] [blame] | 96 | absl::flat_hash_map<std::string, std::string> instantiations; |
Marcel Hlopko | 20de6de | 2022-09-13 05:28:08 -0700 | [diff] [blame] | 97 | std::optional<const Namespace*> ns = |
| 98 | FindNamespace(ir, kInstantiationsNamespaceName); |
| 99 | if (ns.has_value()) { |
| 100 | std::vector<const Record*> records = |
| 101 | FindInstantiationsInNamespace(ir, ns.value()->id); |
| 102 | for (const auto* record : records) { |
Marcel Hlopko | c31d95a | 2022-09-09 05:17:32 -0700 | [diff] [blame] | 103 | instantiations.insert({record->cc_name, record->rs_name}); |
| 104 | } |
| 105 | } |
| 106 | |
Rosica Dejanovska | abe406f | 2022-09-02 07:06:50 -0700 | [diff] [blame] | 107 | auto top_level_namespaces = crubit::CollectNamespaces(ir); |
| 108 | |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 109 | return BindingsAndMetadata{ |
| 110 | .ir = ir, |
| 111 | .rs_api = bindings.rs_api, |
| 112 | .rs_api_impl = bindings.rs_api_impl, |
Marcel Hlopko | c31d95a | 2022-09-09 05:17:32 -0700 | [diff] [blame] | 113 | .namespaces = std::move(top_level_namespaces), |
| 114 | .instantiations = std::move(instantiations), |
Michael VanBemmel | f5cbdf4 | 2022-10-14 17:00:11 -0700 | [diff] [blame] | 115 | .error_report = bindings.error_report, |
Marcel Hlopko | 3f771a9 | 2022-05-09 06:09:59 -0700 | [diff] [blame] | 116 | }; |
| 117 | } |
| 118 | |
| 119 | } // namespace crubit |