blob: a01e16e501cb25438f814f1fa4d267429d12f269 [file] [log] [blame]
Marcel Hlopko42abfc82021-08-09 07:03:17 +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
Marcel Hlopko3962d182021-08-18 10:16:41 +00005#include "rs_bindings_from_cc/src_code_gen.h"
Marcel Hlopko42abfc82021-08-09 07:03:17 +00006
Marcel Hlopko42abfc82021-08-09 07:03:17 +00007#include <string>
8
Marcel Hlopko65978eb2022-04-08 07:40:18 -07009#include "common/ffi_types.h"
Marcel Hlopko42abfc82021-08-09 07:03:17 +000010#include "rs_bindings_from_cc/ir.h"
Lukasz Anforowiczcec7a8a2022-04-27 10:24:51 -070011#include "clang/Format/Format.h"
12#include "llvm/Support/FormatVariadic.h"
13#include "llvm/Support/JSON.h"
Marcel Hlopko42abfc82021-08-09 07:03:17 +000014
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -070015namespace crubit {
Marcel Hlopko42abfc82021-08-09 07:03:17 +000016
Marcel Hlopko45fba972021-08-23 19:52:20 +000017// FFI equivalent of `Bindings`.
18struct FfiBindings {
19 FfiU8SliceBox rs_api;
20 FfiU8SliceBox rs_api_impl;
21};
Marcel Hlopko42abfc82021-08-09 07:03:17 +000022
Marcel Hlopko45fba972021-08-23 19:52:20 +000023// This function is implemented in Rust.
24extern "C" FfiBindings GenerateBindingsImpl(FfiU8Slice json);
25
26// Creates `Bindings` instance from copied data from `ffi_bindings`.
Marcel Hlopkoe936aac2021-08-24 20:52:27 +000027static Bindings MakeBindingsFromFfiBindings(const FfiBindings& ffi_bindings) {
Marcel Hlopko45fba972021-08-23 19:52:20 +000028 Bindings bindings;
29
Marcel Hlopkoe936aac2021-08-24 20:52:27 +000030 const FfiU8SliceBox& rs_api = ffi_bindings.rs_api;
31 const FfiU8SliceBox& rs_api_impl = ffi_bindings.rs_api_impl;
Marcel Hlopko45fba972021-08-23 19:52:20 +000032
33 bindings.rs_api = std::string(rs_api.ptr, rs_api.size);
Michael Forsterf74c1492021-09-17 09:30:10 +000034
35 std::string impl{rs_api_impl.ptr, rs_api_impl.size};
36 bindings.rs_api_impl = *clang::tooling::applyAllReplacements(
37 impl,
38 clang::format::reformat(
39 clang::format::getGoogleStyle(clang::format::FormatStyle::LK_Cpp),
40 impl, clang::tooling::Range(0, impl.size()), "<stdin>"));
Marcel Hlopko45fba972021-08-23 19:52:20 +000041
42 return bindings;
43}
44
45// Deallocates given `ffi_bindings` instance that was created in Rust.
46static void FreeFfiBindings(FfiBindings ffi_bindings) {
47 FreeFfiU8SliceBox(ffi_bindings.rs_api);
48 FreeFfiU8SliceBox(ffi_bindings.rs_api_impl);
49}
50
Marcel Hlopkoe936aac2021-08-24 20:52:27 +000051Bindings GenerateBindings(const IR& ir) {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000052 std::string json = llvm::formatv("{0}", ir.ToJson());
Marcel Hlopko45fba972021-08-23 19:52:20 +000053 FfiBindings ffi_bindings = GenerateBindingsImpl(MakeFfiU8Slice(json));
54 Bindings bindings = MakeBindingsFromFfiBindings(ffi_bindings);
55 FreeFfiBindings(ffi_bindings);
56 return bindings;
Marcel Hlopko42abfc82021-08-09 07:03:17 +000057}
58
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -070059} // namespace crubit