Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [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/ir_from_cc.h" |
| 6 | |
Marcel Hlopko | 20f4ce4 | 2021-11-02 08:20:00 +0000 | [diff] [blame] | 7 | #include <memory> |
| 8 | #include <string> |
| 9 | #include <utility> |
| 10 | #include <vector> |
| 11 | |
Lukasz Anforowicz | cec7a8a | 2022-04-27 10:24:51 -0700 | [diff] [blame] | 12 | #include "absl/container/flat_hash_map.h" |
| 13 | #include "absl/status/status.h" |
| 14 | #include "absl/status/statusor.h" |
| 15 | #include "absl/strings/string_view.h" |
| 16 | #include "absl/strings/substitute.h" |
| 17 | #include "absl/types/span.h" |
Marco Poletti | c61bcc4 | 2022-04-08 12:54:30 -0700 | [diff] [blame] | 18 | #include "common/check.h" |
Marcel Hlopko | 3b254b3 | 2022-03-09 14:10:49 +0000 | [diff] [blame] | 19 | #include "rs_bindings_from_cc/bazel_types.h" |
| 20 | #include "rs_bindings_from_cc/frontend_action.h" |
Marcel Hlopko | 3b254b3 | 2022-03-09 14:10:49 +0000 | [diff] [blame] | 21 | #include "rs_bindings_from_cc/ir.h" |
Lukasz Anforowicz | cec7a8a | 2022-04-27 10:24:51 -0700 | [diff] [blame] | 22 | #include "clang/Frontend/FrontendAction.h" |
| 23 | #include "clang/Tooling/Tooling.h" |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 24 | |
Marcel Hlopko | f15e8ce | 2022-04-08 08:46:09 -0700 | [diff] [blame] | 25 | namespace crubit { |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 26 | |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 27 | static constexpr absl::string_view kVirtualHeaderPath = |
| 28 | "ir_from_cc_virtual_header.h"; |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 29 | static constexpr absl::string_view kVirtualInputPath = |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 30 | "ir_from_cc_virtual_input.cc"; |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 31 | |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 32 | absl::StatusOr<IR> IrFromCc( |
Googler | 6c3de12 | 2022-03-28 11:40:41 +0000 | [diff] [blame] | 33 | const absl::string_view extra_source_code, const BazelLabel current_target, |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 34 | absl::Span<const HeaderName> public_headers, |
| 35 | absl::flat_hash_map<const HeaderName, const std::string> |
| 36 | virtual_headers_contents, |
Googler | 6c3de12 | 2022-03-28 11:40:41 +0000 | [diff] [blame] | 37 | absl::flat_hash_map<const HeaderName, const BazelLabel> headers_to_targets, |
Marcel Hlopko | 2ee2391 | 2022-05-09 06:13:55 -0700 | [diff] [blame] | 38 | absl::Span<const absl::string_view> args, |
| 39 | absl::Span<const std::string> extra_instantiations) { |
Lukasz Anforowicz | 34ad7f7 | 2022-03-17 16:05:28 +0000 | [diff] [blame] | 40 | // Caller should verify that the inputs are not empty. |
Marcel Hlopko | 2ee2391 | 2022-05-09 06:13:55 -0700 | [diff] [blame] | 41 | // TODO(b/440066049): Generate a source file for requested instantiations once |
| 42 | // cl/430823388 is submitted. |
| 43 | CRUBIT_CHECK(!extra_source_code.empty() || !public_headers.empty() || |
| 44 | !extra_instantiations.empty()); |
| 45 | CRUBIT_CHECK(!extra_source_code.empty() || !headers_to_targets.empty() || |
| 46 | !extra_instantiations.empty()); |
Lukasz Anforowicz | 34ad7f7 | 2022-03-17 16:05:28 +0000 | [diff] [blame] | 47 | |
Googler | 7ea9fbb | 2022-03-11 02:56:03 +0000 | [diff] [blame] | 48 | std::vector<HeaderName> entrypoint_headers(public_headers.begin(), |
| 49 | public_headers.end()); |
Rosica Dejanovska | 5fc4caf | 2022-01-31 13:54:32 +0000 | [diff] [blame] | 50 | clang::tooling::FileContentMappings file_contents; |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 51 | |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 52 | for (auto const& name_and_content : virtual_headers_contents) { |
Rosica Dejanovska | 5fc4caf | 2022-01-31 13:54:32 +0000 | [diff] [blame] | 53 | file_contents.push_back({std::string(name_and_content.first.IncludePath()), |
| 54 | name_and_content.second}); |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 55 | } |
| 56 | if (!extra_source_code.empty()) { |
Rosica Dejanovska | 5fc4caf | 2022-01-31 13:54:32 +0000 | [diff] [blame] | 57 | file_contents.push_back( |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 58 | {std::string(kVirtualHeaderPath), std::string(extra_source_code)}); |
| 59 | HeaderName header_name = HeaderName(std::string(kVirtualHeaderPath)); |
| 60 | entrypoint_headers.push_back(header_name); |
| 61 | headers_to_targets.insert({header_name, current_target}); |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 62 | } |
| 63 | |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 64 | std::string virtual_input_file_content; |
| 65 | for (const HeaderName& header_name : entrypoint_headers) { |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 66 | absl::SubstituteAndAppend(&virtual_input_file_content, "#include \"$0\"\n", |
Marcel Hlopko | 7aa38a7 | 2021-11-11 07:39:51 +0000 | [diff] [blame] | 67 | header_name.IncludePath()); |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 68 | } |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 69 | |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 70 | std::vector<std::string> args_as_strings{ |
Rosica Dejanovska | 5fc4caf | 2022-01-31 13:54:32 +0000 | [diff] [blame] | 71 | // Parse non-doc comments that are used as documention |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 72 | "-fparse-all-comments"}; |
| 73 | args_as_strings.insert(args_as_strings.end(), args.begin(), args.end()); |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 74 | |
Michael Forster | 64217b4 | 2022-04-22 05:48:54 -0700 | [diff] [blame] | 75 | if (Invocation invocation(current_target, entrypoint_headers, |
| 76 | headers_to_targets); |
Rosica Dejanovska | 5fc4caf | 2022-01-31 13:54:32 +0000 | [diff] [blame] | 77 | clang::tooling::runToolOnCodeWithArgs( |
| 78 | std::make_unique<FrontendAction>(invocation), |
| 79 | virtual_input_file_content, args_as_strings, kVirtualInputPath, |
| 80 | "rs_bindings_from_cc", |
| 81 | std::make_shared<clang::PCHContainerOperations>(), file_contents)) { |
Michael Forster | a49d2e6 | 2022-01-28 07:26:40 +0000 | [diff] [blame] | 82 | return invocation.ir_; |
Michael Forster | 3f323be | 2021-10-11 07:13:28 +0000 | [diff] [blame] | 83 | } else { |
| 84 | return absl::Status(absl::StatusCode::kInvalidArgument, |
| 85 | "Could not compile header contents"); |
| 86 | } |
Googler | 741ed9c | 2021-10-01 08:00:49 +0000 | [diff] [blame] | 87 | } |
| 88 | |
Marcel Hlopko | f15e8ce | 2022-04-08 08:46:09 -0700 | [diff] [blame] | 89 | } // namespace crubit |