blob: 8ff68dd330a20ca88a5de1f5dad4b0c10d9c5b51 [file] [log] [blame]
Googler741ed9c2021-10-01 08:00:49 +00001// 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
7#include "devtools/cymbal/common/clang_tool.h"
8#include "rs_bindings_from_cc/frontend_action.h"
9#include "third_party/absl/container/flat_hash_map.h"
10#include "third_party/absl/strings/substitute.h"
11
12namespace rs_bindings_from_cc {
13
14static constexpr absl::string_view kVirtualInputPath =
Michael Forster3f323be2021-10-11 07:13:28 +000015 "ir_from_cc_virtual_input.cc";
Googler741ed9c2021-10-01 08:00:49 +000016
Michael Forster3f323be2021-10-11 07:13:28 +000017absl::StatusOr<IR> IrFromCc(
18 absl::Span<const absl::string_view> header_files_contents,
19 absl::Span<const absl::string_view> header_names,
20 absl::Span<const absl::string_view> args) {
21 std::vector<std::string> headers{header_names.begin(), header_names.end()};
Googler741ed9c2021-10-01 08:00:49 +000022 absl::flat_hash_map<std::string, std::string> file_contents;
23 std::string virtual_input_file_content;
24
25 int counter = 0;
26 for (const absl::string_view header_content : header_files_contents) {
27 std::string filename(
28 absl::Substitute("test/testing_header_$0.h", counter++));
29 file_contents.insert({filename, std::string(header_content)});
Googler741ed9c2021-10-01 08:00:49 +000030 headers.push_back(std::move(filename));
31 }
32
Michael Forster3f323be2021-10-11 07:13:28 +000033 for (const std::string& filename : headers) {
34 absl::SubstituteAndAppend(&virtual_input_file_content, "#include \"$0\"\n",
35 filename);
36 }
Googler741ed9c2021-10-01 08:00:49 +000037 file_contents.insert(
38 {std::string(kVirtualInputPath), virtual_input_file_content});
39
Michael Forster3f323be2021-10-11 07:13:28 +000040 std::vector<std::string> args_as_strings{
41 // This includes the path of the binary that we're pretending to be.
42 // TODO(forster): Find out where to point this. Should we use the
43 // production crosstool for this? See
44 // http://google3/devtools/cymbal/common/clang_tool.cc;l=171;rcl=385188113
45 "clang",
46 // We only need the AST.
47 "-fsyntax-only",
48 // Parse non-doc comments that are used as documention.
49 "-fparse-all-comments"};
50 args_as_strings.insert(args_as_strings.end(), args.begin(), args.end());
Googler741ed9c2021-10-01 08:00:49 +000051 args_as_strings.push_back(std::string(kVirtualInputPath));
52
Michael Forster3f323be2021-10-11 07:13:28 +000053 if (IR ir; devtools::cymbal::RunToolWithClangFlagsOnCode(
54 args_as_strings, file_contents,
55 std::make_unique<FrontendAction>(
56 std::vector<absl::string_view>(headers.begin(), headers.end()),
57 ir))) {
58 return ir;
59 } else {
60 return absl::Status(absl::StatusCode::kInvalidArgument,
61 "Could not compile header contents");
62 }
Googler741ed9c2021-10-01 08:00:49 +000063}
64
65} // namespace rs_bindings_from_cc