blob: f09ec43a63db7434a824160f2f9cafb6477738b7 [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
5#include "rs_bindings_from_cc/ir.h"
6
Marcel Hlopko20f4ce42021-11-02 08:20:00 +00007#include <stdint.h>
8
Devin Jeanpierref2ec8712021-10-13 20:47:16 +00009#include <optional>
Marcel Hlopko20f4ce42021-11-02 08:20:00 +000010#include <ostream>
Marcel Hlopko42abfc82021-08-09 07:03:17 +000011#include <string>
Marcel Hlopko20f4ce42021-11-02 08:20:00 +000012#include <utility>
Devin Jeanpierref2ec8712021-10-13 20:47:16 +000013#include <variant>
Marcel Hlopko42abfc82021-08-09 07:03:17 +000014#include <vector>
15
Lukasz Anforowiczcec7a8a2022-04-27 10:24:51 -070016#include "absl/strings/string_view.h"
Marco Polettic61bcc42022-04-08 12:54:30 -070017#include "common/check.h"
18#include "common/strong_int.h"
Marcel Hlopko3b254b32022-03-09 14:10:49 +000019#include "rs_bindings_from_cc/bazel_types.h"
Lukasz Anforowiczcec7a8a2022-04-27 10:24:51 -070020#include "llvm/Support/JSON.h"
Marcel Hlopko42abfc82021-08-09 07:03:17 +000021
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -070022namespace crubit {
Marcel Hlopko42abfc82021-08-09 07:03:17 +000023
Googler7ce38c92021-12-02 07:50:52 +000024template <class T>
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000025llvm::json::Value toJSON(const T& t) {
26 return t.ToJson();
Googler7ce38c92021-12-02 07:50:52 +000027}
28
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000029template <typename TTag, typename TInt>
Marco Polettic61bcc42022-04-08 12:54:30 -070030llvm::json::Value toJSON(const crubit::StrongInt<TTag, TInt> strong_int) {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000031 return llvm::json::Value(strong_int.value());
Marcel Hlopkof1123c82021-08-19 11:38:52 +000032}
33
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000034template <typename TTag>
Marco Polettic61bcc42022-04-08 12:54:30 -070035llvm::json::Value toJSON(const crubit::StringType<TTag> string_type) {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000036 return llvm::json::Value(string_type.value());
Googler64e4edb2021-12-03 12:17:38 +000037}
38
Lukasz Anforowiczfea0db92022-05-17 17:28:04 -070039template <class T>
40llvm::json::Value toJSON(const absl::StatusOr<T>& t) {
41 if (t.ok()) {
42 return llvm::json::Object{{"Ok", *t}};
43 }
44 return llvm::json::Object{{"Err", std::string(t.status().message())}};
45}
46
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000047llvm::json::Value HeaderName::ToJson() const {
48 return llvm::json::Object{
49 {"name", name_},
50 };
Marcel Hlopko42abfc82021-08-09 07:03:17 +000051}
52
Marcel Hlopkoaf682a02022-04-08 07:27:14 -070053llvm::json::Value LifetimeName::ToJson() const {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000054 return llvm::json::Object{
55 {"name", name},
56 {"id", id},
57 };
58}
Devin Jeanpierre09c6f452021-09-29 07:34:24 +000059
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000060llvm::json::Value RsType::ToJson() const {
61 return llvm::json::Object{
62 {"name", decl_id.hasValue() ? llvm::json::Value(nullptr)
63 : llvm::json::Value(name)},
64 {"lifetime_args", lifetime_args},
65 {"type_args", type_args},
66 {"decl_id", decl_id},
67 };
68}
Devin Jeanpierre09c6f452021-09-29 07:34:24 +000069
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +000070llvm::json::Value CcType::ToJson() const {
71 return llvm::json::Object{
72 {"name", decl_id.hasValue() ? llvm::json::Value(nullptr)
73 : llvm::json::Value(name)},
74 {"is_const", is_const},
75 {"type_args", type_args},
76 {"decl_id", decl_id},
77 };
Devin Jeanpierre09c6f452021-09-29 07:34:24 +000078}
79
Devin Jeanpierredeea7892022-03-29 02:13:31 -070080namespace {
81enum class ValueCategory { kLvalue, kRvalue };
82
83MappedType PointerOrReferenceTo(MappedType pointee_type,
84 absl::string_view cc_ptr_name,
85 ValueCategory value_category,
86 std::optional<LifetimeId> lifetime,
87 bool nullable) {
Googler454f2652021-12-06 12:53:12 +000088 bool has_lifetime = lifetime.has_value();
Devin Jeanpierre70393902022-03-15 13:22:59 +000089 absl::string_view rs_name;
Devin Jeanpierredeea7892022-03-29 02:13:31 -070090 if (value_category == ValueCategory::kLvalue) {
91 if (has_lifetime) {
92 rs_name = pointee_type.cc_type.is_const ? internal::kRustRefConst
93 : internal::kRustRefMut;
94 } else {
95 rs_name = pointee_type.cc_type.is_const ? internal::kRustPtrConst
96 : internal::kRustPtrMut;
97 }
Googler02da3fb2021-12-06 11:59:19 +000098 } else {
Devin Jeanpierredeea7892022-03-29 02:13:31 -070099 CRUBIT_CHECK(has_lifetime);
100 rs_name = pointee_type.cc_type.is_const ? internal::kRustRvalueRefConst
101 : internal::kRustRvalueRefMut;
Googler02da3fb2021-12-06 11:59:19 +0000102 }
103 auto pointer_type =
Devin Jeanpierre70393902022-03-15 13:22:59 +0000104 MappedType::Simple(std::string(rs_name), std::string(cc_ptr_name));
Googler454f2652021-12-06 12:53:12 +0000105 if (has_lifetime) {
Googler02da3fb2021-12-06 11:59:19 +0000106 pointer_type.rs_type.lifetime_args.push_back(*std::move(lifetime));
107 }
108 pointer_type.rs_type.type_args.push_back(std::move(pointee_type.rs_type));
Googler454f2652021-12-06 12:53:12 +0000109 if (has_lifetime && nullable) {
110 pointer_type.rs_type =
111 RsType{.name = "Option", .type_args = {pointer_type.rs_type}};
112 }
Googler02da3fb2021-12-06 11:59:19 +0000113 pointer_type.cc_type.type_args.push_back(std::move(pointee_type.cc_type));
114 return pointer_type;
115}
Devin Jeanpierredeea7892022-03-29 02:13:31 -0700116} // namespace
Googler02da3fb2021-12-06 11:59:19 +0000117
Devin Jeanpierre70393902022-03-15 13:22:59 +0000118MappedType MappedType::PointerTo(MappedType pointee_type,
119 std::optional<LifetimeId> lifetime,
120 bool nullable) {
121 return PointerOrReferenceTo(std::move(pointee_type), internal::kCcPtr,
Devin Jeanpierredeea7892022-03-29 02:13:31 -0700122 ValueCategory::kLvalue, lifetime, nullable);
Devin Jeanpierre70393902022-03-15 13:22:59 +0000123}
124
Googler02da3fb2021-12-06 11:59:19 +0000125MappedType MappedType::LValueReferenceTo(MappedType pointee_type,
126 std::optional<LifetimeId> lifetime) {
Devin Jeanpierre70393902022-03-15 13:22:59 +0000127 return PointerOrReferenceTo(std::move(pointee_type), internal::kCcLValueRef,
Devin Jeanpierredeea7892022-03-29 02:13:31 -0700128 ValueCategory::kLvalue, lifetime,
129 /*nullable=*/false);
130}
131
132MappedType MappedType::RValueReferenceTo(MappedType pointee_type,
133 LifetimeId lifetime) {
134 return PointerOrReferenceTo(std::move(pointee_type), internal::kCcRValueRef,
135 ValueCategory::kRvalue, lifetime,
136 /*nullable=*/false);
Googler02da3fb2021-12-06 11:59:19 +0000137}
138
Lukasz Anforowiczcf230fd2022-02-18 19:20:39 +0000139MappedType MappedType::FuncPtr(absl::string_view cc_call_conv,
140 absl::string_view rs_abi,
141 std::optional<LifetimeId> lifetime,
142 MappedType return_type,
143 std::vector<MappedType> param_types) {
Lukasz Anforowicz92c81c32022-03-04 19:03:56 +0000144 MappedType result = FuncRef(cc_call_conv, rs_abi, lifetime,
145 std::move(return_type), std::move(param_types));
146
Lukasz Anforowicz34ad7f72022-03-17 16:05:28 +0000147 CRUBIT_CHECK(result.cc_type.name == internal::kCcLValueRef);
Lukasz Anforowicz92c81c32022-03-04 19:03:56 +0000148 result.cc_type.name = std::string(internal::kCcPtr);
149
150 RsType rs_func_ptr_type = std::move(result.rs_type);
Lukasz Anforowicz34ad7f72022-03-17 16:05:28 +0000151 CRUBIT_CHECK(
152 rs_func_ptr_type.name.substr(0, internal::kRustFuncPtr.length()) ==
153 internal::kRustFuncPtr);
Lukasz Anforowicz92c81c32022-03-04 19:03:56 +0000154 result.rs_type =
155 RsType{.name = "Option", .type_args = {std::move(rs_func_ptr_type)}};
156
157 return result;
158}
159
160MappedType MappedType::FuncRef(absl::string_view cc_call_conv,
161 absl::string_view rs_abi,
162 std::optional<LifetimeId> lifetime,
163 MappedType return_type,
164 std::vector<MappedType> param_types) {
Lukasz Anforowiczcf230fd2022-02-18 19:20:39 +0000165 std::vector<MappedType> type_args = std::move(param_types);
166 type_args.push_back(std::move(return_type));
167
168 std::vector<CcType> cc_type_args;
169 std::vector<RsType> rs_type_args;
170 cc_type_args.reserve(type_args.size());
171 rs_type_args.reserve(type_args.size());
172 for (MappedType& type_arg : type_args) {
173 cc_type_args.push_back(std::move(type_arg.cc_type));
174 rs_type_args.push_back(std::move(type_arg.rs_type));
175 }
176
177 CcType cc_func_value_type = CcType{
178 .name = absl::StrCat(internal::kCcFuncValue, " ", cc_call_conv),
179 .type_args = std::move(cc_type_args),
180 };
Lukasz Anforowicz92c81c32022-03-04 19:03:56 +0000181 CcType cc_func_ref_type = CcType{.name = std::string(internal::kCcLValueRef),
Lukasz Anforowiczcf230fd2022-02-18 19:20:39 +0000182 .type_args = {cc_func_value_type}};
183
184 // Rust cannot express a function *value* type, only function pointer types.
185 RsType rs_func_ptr_type = RsType{
186 .name = absl::StrCat(internal::kRustFuncPtr, " ", rs_abi),
187 .type_args = std::move(rs_type_args),
188 };
189 if (lifetime.has_value())
190 rs_func_ptr_type.lifetime_args.push_back(*std::move(lifetime));
191
Lukasz Anforowiczcf230fd2022-02-18 19:20:39 +0000192 return MappedType{
Lukasz Anforowicz92c81c32022-03-04 19:03:56 +0000193 .rs_type = std::move(rs_func_ptr_type),
194 .cc_type = std::move(cc_func_ref_type),
Lukasz Anforowiczcf230fd2022-02-18 19:20:39 +0000195 };
196}
197
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000198llvm::json::Value MappedType::ToJson() const {
199 return llvm::json::Object{
200 {"rs_type", rs_type},
201 {"cc_type", cc_type},
202 };
Devin Jeanpierre09c6f452021-09-29 07:34:24 +0000203}
204
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000205llvm::json::Value Identifier::ToJson() const {
206 return llvm::json::Object{
207 {"identifier", identifier_},
208 };
Marcel Hlopko42abfc82021-08-09 07:03:17 +0000209}
210
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000211llvm::json::Value IntegerConstant::ToJson() const {
212 return llvm::json::Object{
213 {"is_negative", is_negative_},
214 {"wrapped_value", wrapped_value_},
215 };
Teddy Katz76fa42b2022-02-23 01:22:56 +0000216}
217
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000218llvm::json::Value Operator::ToJson() const {
219 return llvm::json::Object{
220 {"name", name_},
221 };
Marcel Hlopko42abfc82021-08-09 07:03:17 +0000222}
223
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000224static std::string SpecialNameToString(SpecialName special_name) {
225 switch (special_name) {
226 case SpecialName::kDestructor:
227 return "Destructor";
228 case SpecialName::kConstructor:
229 return "Constructor";
230 }
231}
232
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000233llvm::json::Value toJSON(const UnqualifiedIdentifier& unqualified_identifier) {
Lukasz Anforowicz9c663ca2022-02-09 01:33:31 +0000234 if (auto* id = std::get_if<Identifier>(&unqualified_identifier)) {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000235 return llvm::json::Object{
236 {"Identifier", *id},
237 };
Lukasz Anforowicz9c663ca2022-02-09 01:33:31 +0000238 } else if (auto* op = std::get_if<Operator>(&unqualified_identifier)) {
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000239 return llvm::json::Object{
240 {"Operator", *op},
241 };
Lukasz Anforowicz9c663ca2022-02-09 01:33:31 +0000242 } else {
243 SpecialName special_name = std::get<SpecialName>(unqualified_identifier);
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000244 return llvm::json::Object{
245 {SpecialNameToString(special_name), nullptr},
246 };
Lukasz Anforowicz9c663ca2022-02-09 01:33:31 +0000247 }
Lukasz Anforowicz9c663ca2022-02-09 01:33:31 +0000248}
249
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000250llvm::json::Value FuncParam::ToJson() const {
251 return llvm::json::Object{
252 {"type", type},
253 {"identifier", identifier},
254 };
Lukasz Anforowicz9c663ca2022-02-09 01:33:31 +0000255}
256
Devin Jeanpierref2ec8712021-10-13 20:47:16 +0000257std::ostream& operator<<(std::ostream& o, const SpecialName& special_name) {
258 return o << SpecialNameToString(special_name);
259}
260
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000261llvm::json::Value MemberFuncMetadata::InstanceMethodMetadata::ToJson() const {
262 const char* reference_str = nullptr;
263 switch (reference) {
264 case MemberFuncMetadata::kLValue:
265 reference_str = "LValue";
266 break;
267 case MemberFuncMetadata::kRValue:
268 reference_str = "RValue";
269 break;
270 case MemberFuncMetadata::kUnqualified:
271 reference_str = "Unqualified";
272 break;
Devin Jeanpierrec6877bb2021-10-13 20:47:54 +0000273 }
274
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000275 return llvm::json::Object{
276 {"reference", reference_str},
277 {"is_const", is_const},
278 {"is_virtual", is_virtual},
279 {"is_explicit_ctor", is_explicit_ctor},
280 };
Devin Jeanpierrec6877bb2021-10-13 20:47:54 +0000281}
282
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000283llvm::json::Value MemberFuncMetadata::ToJson() const {
284 return llvm::json::Object{
285 {"record_id", record_id},
286 {"instance_method_metadata", instance_method_metadata},
287 };
288}
Michael Forster7ef80732021-10-01 18:12:19 +0000289
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000290llvm::json::Value Func::ToJson() const {
291 llvm::json::Object func{
292 {"name", name},
293 {"owning_target", owning_target},
294 {"doc_comment", doc_comment},
295 {"mangled_name", mangled_name},
296 {"return_type", return_type},
297 {"params", params},
298 {"lifetime_params", lifetime_params},
299 {"is_inline", is_inline},
300 {"member_func_metadata", member_func_metadata},
Lukasz Anforowicz0b6a6ac2022-03-22 22:32:23 +0000301 {"has_c_calling_convention", has_c_calling_convention},
Lukasz Anforowiczb1ff2e52022-05-16 10:54:23 -0700302 {"is_member_or_descendant_of_class_template",
303 is_member_or_descendant_of_class_template},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000304 {"source_loc", source_loc},
Rosica Dejanovskad638cf52022-03-23 15:45:01 +0000305 {"id", id},
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700306 {"enclosing_namespace_id", enclosing_namespace_id},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000307 };
308
309 return llvm::json::Object{
310 {"Func", std::move(func)},
311 };
Marcel Hlopko42abfc82021-08-09 07:03:17 +0000312}
313
Googler2294c702021-09-17 07:32:07 +0000314static std::string AccessToString(AccessSpecifier access) {
315 switch (access) {
316 case kPublic:
317 return "Public";
318 case kProtected:
319 return "Protected";
320 case kPrivate:
321 return "Private";
322 }
323}
324
Devin Jeanpierre2d5718a2021-10-05 11:39:34 +0000325std::ostream& operator<<(std::ostream& o, const AccessSpecifier& access) {
326 return o << AccessToString(access);
327}
328
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000329llvm::json::Value Field::ToJson() const {
330 return llvm::json::Object{
331 {"identifier", identifier},
332 {"doc_comment", doc_comment},
333 {"type", type},
334 {"access", AccessToString(access)},
335 {"offset", offset},
Lukasz Anforowicz5765bb82022-05-17 17:21:06 -0700336 {"size", size},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000337 {"is_no_unique_address", is_no_unique_address},
Michael Forster82c02d32022-05-20 21:47:33 -0700338 {"is_bitfield", is_bitfield},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000339 };
Marcel Hlopkob4b28742021-09-15 12:45:20 +0000340}
341
Lukasz Anforowiczff7df4a2022-06-02 14:27:45 -0700342llvm::json::Value toJSON(const SpecialMemberFunc& f) {
343 switch (f) {
344 case SpecialMemberFunc::kTrivial:
Devin Jeanpierre07931272021-10-05 11:40:13 +0000345 return "Trivial";
Lukasz Anforowiczff7df4a2022-06-02 14:27:45 -0700346 case SpecialMemberFunc::kNontrivialMembers:
Devin Jeanpierrebe2f33b2021-10-21 12:54:19 +0000347 return "NontrivialMembers";
Lukasz Anforowiczff7df4a2022-06-02 14:27:45 -0700348 case SpecialMemberFunc::kNontrivialUserDefined:
Devin Jeanpierre7b62e952021-12-08 21:43:30 +0000349 return "NontrivialUserDefined";
Lukasz Anforowiczff7df4a2022-06-02 14:27:45 -0700350 case SpecialMemberFunc::kUnavailable:
351 return "Unavailable";
Devin Jeanpierre07931272021-10-05 11:40:13 +0000352 }
353}
354
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000355llvm::json::Value BaseClass::ToJson() const {
356 return llvm::json::Object{
357 {"base_record_id", base_record_id},
358 {"offset", offset},
359 };
Marcel Hlopkob4b28742021-09-15 12:45:20 +0000360}
Googler098c4582022-01-10 12:29:34 +0000361
Lukasz Anforowiczd4742ff2022-07-11 17:05:02 -0700362static std::string RecordTypeToString(RecordType record_type) {
363 switch (record_type) {
364 case kStruct:
365 return "Struct";
366 case kUnion:
367 return "Union";
368 case kClass:
369 return "Class";
370 }
371}
372
373std::ostream& operator<<(std::ostream& o, const RecordType& record_type) {
374 return o << RecordTypeToString(record_type);
375}
376
Devin Jeanpierrec0543eb2022-04-20 16:00:34 -0700377llvm::json::Value IncompleteRecord::ToJson() const {
378 llvm::json::Object record{
379 {"cc_name", cc_name},
Rosica Dejanovskae12d7172022-06-22 12:20:17 -0700380 {"rs_name", rs_name},
Devin Jeanpierrec0543eb2022-04-20 16:00:34 -0700381 {"id", id},
382 {"owning_target", owning_target},
383 };
384
385 return llvm::json::Object{
386 {"IncompleteRecord", std::move(record)},
387 };
388}
389
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000390llvm::json::Value Record::ToJson() const {
Rosica Dejanovskab2bd59e2022-04-11 09:02:03 -0700391 std::vector<llvm::json::Value> json_item_ids;
392 json_item_ids.reserve(child_item_ids.size());
393 for (const auto& id : child_item_ids) {
394 json_item_ids.push_back(id.value());
395 }
396
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000397 llvm::json::Object record{
398 {"rs_name", rs_name},
399 {"cc_name", cc_name},
400 {"id", id},
401 {"owning_target", owning_target},
402 {"doc_comment", doc_comment},
403 {"unambiguous_public_bases", unambiguous_public_bases},
404 {"fields", fields},
405 {"lifetime_params", lifetime_params},
406 {"size", size},
407 {"alignment", alignment},
Devin Jeanpierre1221c2a2022-05-05 22:36:22 -0700408 {"is_derived_class", is_derived_class},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000409 {"override_alignment", override_alignment},
410 {"copy_constructor", copy_constructor},
411 {"move_constructor", move_constructor},
412 {"destructor", destructor},
413 {"is_trivial_abi", is_trivial_abi},
Teddy Katzd2cd1422022-04-04 09:41:33 -0700414 {"is_inheritable", is_inheritable},
Lukasz Anforowiczd4742ff2022-07-11 17:05:02 -0700415 {"record_type", RecordTypeToString(record_type)},
Devin Jeanpierrea2be2a22022-05-18 18:59:05 -0700416 {"is_aggregate", is_aggregate},
Rosica Dejanovskab2bd59e2022-04-11 09:02:03 -0700417 {"child_item_ids", std::move(json_item_ids)},
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700418 {"enclosing_namespace_id", enclosing_namespace_id},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000419 };
420
421 return llvm::json::Object{
422 {"Record", std::move(record)},
423 };
Teddy Katz76fa42b2022-02-23 01:22:56 +0000424}
425
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000426llvm::json::Value Enumerator::ToJson() const {
427 return llvm::json::Object{
428 {"identifier", identifier},
429 {"value", value},
430 };
Teddy Katz76fa42b2022-02-23 01:22:56 +0000431}
432
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000433llvm::json::Value Enum::ToJson() const {
434 llvm::json::Object enum_ir{
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700435 {"identifier", identifier},
436 {"id", id},
437 {"owning_target", owning_target},
438 {"underlying_type", underlying_type},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000439 {"enumerators", enumerators},
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700440 {"enclosing_namespace_id", enclosing_namespace_id},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000441 };
Googler098c4582022-01-10 12:29:34 +0000442
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000443 return llvm::json::Object{
444 {"Enum", std::move(enum_ir)},
445 };
Googler098c4582022-01-10 12:29:34 +0000446}
447
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000448llvm::json::Value TypeAlias::ToJson() const {
449 llvm::json::Object type_alias{
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700450 {"identifier", identifier},
451 {"id", id},
452 {"owning_target", owning_target},
453 {"doc_comment", doc_comment},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000454 {"underlying_type", underlying_type},
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700455 {"enclosing_namespace_id", enclosing_namespace_id},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000456 };
457
458 return llvm::json::Object{
459 {"TypeAlias", std::move(type_alias)},
460 };
Michael Forster6a184ad2021-10-12 13:04:05 +0000461}
Marcel Hlopkob4b28742021-09-15 12:45:20 +0000462
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000463llvm::json::Value SourceLoc::ToJson() const {
464 return llvm::json::Object{
465 {"filename", filename},
466 {"line", line},
467 {"column", column},
468 };
Michael Forster523dbd42021-10-12 11:05:44 +0000469}
470
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000471llvm::json::Value UnsupportedItem::ToJson() const {
472 llvm::json::Object unsupported{
473 {"name", name},
474 {"message", message},
475 {"source_loc", source_loc},
Rosica Dejanovskad638cf52022-03-23 15:45:01 +0000476 {"id", id},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000477 };
Michael Forsterf1dce422021-10-13 09:50:16 +0000478
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000479 return llvm::json::Object{
480 {"UnsupportedItem", std::move(unsupported)},
481 };
Michael Forsterf1dce422021-10-13 09:50:16 +0000482}
483
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000484llvm::json::Value Comment::ToJson() const {
485 llvm::json::Object comment{
486 {"text", text},
Rosica Dejanovskad638cf52022-03-23 15:45:01 +0000487 {"id", id},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000488 };
Rosica Dejanovskab2bd59e2022-04-11 09:02:03 -0700489 comment["id"] = id.value();
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000490 return llvm::json::Object{
491 {"Comment", std::move(comment)},
492 };
493}
494
Rosica Dejanovskadd9a9032022-04-12 07:34:41 -0700495llvm::json::Value Namespace::ToJson() const {
496 std::vector<llvm::json::Value> json_item_ids;
497 json_item_ids.reserve(child_item_ids.size());
498 for (const auto& id : child_item_ids) {
499 json_item_ids.push_back(id.value());
500 }
501
502 llvm::json::Object ns{
503 {"name", name},
504 {"id", id},
Rosica Dejanovska6efd17f2022-05-11 08:09:57 -0700505 {"canonical_namespace_id", canonical_namespace_id},
Rosica Dejanovskadd9a9032022-04-12 07:34:41 -0700506 {"owning_target", owning_target},
507 {"child_item_ids", std::move(json_item_ids)},
Rosica Dejanovskae91d2992022-05-05 05:31:39 -0700508 {"enclosing_namespace_id", enclosing_namespace_id},
Rosica Dejanovskadd9a9032022-04-12 07:34:41 -0700509 };
510
511 return llvm::json::Object{
512 {"Namespace", std::move(ns)},
513 };
514}
515
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000516llvm::json::Value IR::ToJson() const {
517 std::vector<llvm::json::Value> json_items;
Michael Forster7ef80732021-10-01 18:12:19 +0000518 json_items.reserve(items.size());
519 for (const auto& item : items) {
520 std::visit([&](auto&& item) { json_items.push_back(item.ToJson()); }, item);
Marcel Hlopkob4b28742021-09-15 12:45:20 +0000521 }
522
Rosica Dejanovskab2bd59e2022-04-11 09:02:03 -0700523 std::vector<llvm::json::Value> top_level_ids;
524 top_level_ids.reserve(top_level_item_ids.size());
525 for (const auto& id : top_level_item_ids) {
526 top_level_ids.push_back(id.value());
527 }
528
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000529 return llvm::json::Object{
530 {"used_headers", used_headers},
531 {"current_target", current_target},
532 {"items", std::move(json_items)},
Rosica Dejanovskab2bd59e2022-04-11 09:02:03 -0700533 {"top_level_item_ids", std::move(top_level_ids)},
Lukasz Anforowicz3b4be122022-03-16 00:09:35 +0000534 };
Marcel Hlopko42abfc82021-08-09 07:03:17 +0000535}
536
Marcel Hlopkof15e8ce2022-04-08 08:46:09 -0700537} // namespace crubit