blob: f023f5fc8a9b4475ade654278369746fc5b63b0b [file] [log] [blame]
Marcel Hlopko3f771a92022-05-09 06:09:59 -07001// 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 Hlopko20de6de2022-09-13 05:28:08 -07007#include <optional>
Marcel Hlopkoab7a2282022-09-05 08:17:41 -07008#include <string>
Marcel Hlopko20de6de2022-09-13 05:28:08 -07009#include <utility>
Dmitri Gribenko785831e2023-07-14 06:47:36 -070010#include <vector>
Marcel Hlopkoab7a2282022-09-05 08:17:41 -070011
Marcel Hlopko20de6de2022-09-13 05:28:08 -070012#include "absl/container/flat_hash_map.h"
13#include "absl/container/flat_hash_set.h"
Dmitri Gribenko785831e2023-07-14 06:47:36 -070014#include "absl/log/check.h"
Marcel Hlopkoab7a2282022-09-05 08:17:41 -070015#include "absl/strings/string_view.h"
Marcel Hlopko3f771a92022-05-09 06:09:59 -070016#include "common/status_macros.h"
Dmitri Gribenko785831e2023-07-14 06:47:36 -070017#include "rs_bindings_from_cc/cmdline.h"
Marcel Hlopko2ee23912022-05-09 06:13:55 -070018#include "rs_bindings_from_cc/collect_instantiations.h"
Rosica Dejanovskaabe406f2022-09-02 07:06:50 -070019#include "rs_bindings_from_cc/collect_namespaces.h"
Marcel Hlopkoab7a2282022-09-05 08:17:41 -070020#include "rs_bindings_from_cc/ir.h"
Marcel Hlopko3f771a92022-05-09 06:09:59 -070021#include "rs_bindings_from_cc/ir_from_cc.h"
22#include "rs_bindings_from_cc/src_code_gen.h"
23
24namespace crubit {
25
Marcel Hlopko20de6de2022-09-13 05:28:08 -070026std::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
36std::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 Hlopko3f771a92022-05-09 06:09:59 -070060absl::StatusOr<BindingsAndMetadata> GenerateBindingsAndMetadata(
Rosica Dejanovskaaf348cc2022-08-30 05:54:16 -070061 Cmdline& cmdline, std::vector<std::string> clang_args,
62 absl::flat_hash_map<const HeaderName, const std::string>
Lukasz Anforowicz121338a2022-11-01 14:28:32 -070063 virtual_headers_contents_for_testing) {
Marcel Hlopko3f771a92022-05-09 06:09:59 -070064 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 Jeanpierre96bf0bd2022-10-04 20:32:15 -070068 CRUBIT_ASSIGN_OR_RETURN(
69 std::vector<std::string> requested_instantiations,
70 CollectInstantiations(cmdline.srcs_to_scan_for_instantiations()));
Marcel Hlopko2ee23912022-05-09 06:13:55 -070071
72 CRUBIT_ASSIGN_OR_RETURN(
Devin Jeanpierreb0af4dc2023-04-27 06:59:25 -070073 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 Hlopko3f771a92022-05-09 06:09:59 -070082
Marcel Hlopkob4d5d8e2022-11-16 03:15:00 -080083 if (!cmdline.instantiations_out().empty()) {
Devin Jeanpierre97047892023-01-11 01:54:53 -080084 ir.crate_root_path = "__cc_template_instantiations_rs_api";
Marcel Hlopkob4d5d8e2022-11-16 03:15:00 -080085 }
86
Michael VanBemmelf5cbdf42022-10-14 17:00:11 -070087 bool generate_error_report = !cmdline.error_report_out().empty();
88 CRUBIT_ASSIGN_OR_RETURN(
89 Bindings bindings,
Jing Lu7ac3e672023-09-27 11:48:35 -070090 GenerateBindings(ir, cmdline.crubit_support_path_format(),
Lukasz Anforowicz5bf49432022-12-12 12:17:24 -080091 cmdline.clang_format_exe_path(),
Michael VanBemmelf5cbdf42022-10-14 17:00:11 -070092 cmdline.rustfmt_exe_path(),
Googler69e09632023-03-03 12:18:35 -080093 cmdline.rustfmt_config_path(), generate_error_report,
94 cmdline.generate_source_location_in_doc_comment()));
Marcel Hlopko3f771a92022-05-09 06:09:59 -070095
Marcel Hlopkoc31d95a2022-09-09 05:17:32 -070096 absl::flat_hash_map<std::string, std::string> instantiations;
Marcel Hlopko20de6de2022-09-13 05:28:08 -070097 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 Hlopkoc31d95a2022-09-09 05:17:32 -0700103 instantiations.insert({record->cc_name, record->rs_name});
104 }
105 }
106
Rosica Dejanovskaabe406f2022-09-02 07:06:50 -0700107 auto top_level_namespaces = crubit::CollectNamespaces(ir);
108
Marcel Hlopko3f771a92022-05-09 06:09:59 -0700109 return BindingsAndMetadata{
110 .ir = ir,
111 .rs_api = bindings.rs_api,
112 .rs_api_impl = bindings.rs_api_impl,
Marcel Hlopkoc31d95a2022-09-09 05:17:32 -0700113 .namespaces = std::move(top_level_namespaces),
114 .instantiations = std::move(instantiations),
Michael VanBemmelf5cbdf42022-10-14 17:00:11 -0700115 .error_report = bindings.error_report,
Marcel Hlopko3f771a92022-05-09 06:09:59 -0700116 };
117}
118
119} // namespace crubit