| // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| // Exceptions. See /LICENSE for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| #include "rs_bindings_from_cc/ir.h" |
| |
| #include <stdint.h> |
| |
| #include <optional> |
| #include <ostream> |
| #include <string> |
| #include <utility> |
| #include <variant> |
| #include <vector> |
| |
| #include "base/integral_types.h" |
| #include "rs_bindings_from_cc/bazel_types.h" |
| #include "third_party/absl/strings/string_view.h" |
| #include "third_party/json/src/json.hpp" |
| #include "util/gtl/labs/string_type.h" |
| #include "util/intops/strong_int.h" |
| |
| namespace rs_bindings_from_cc { |
| |
| template <class T> |
| static std::vector<nlohmann::json> VectorToJson(const std::vector<T>& v) { |
| std::vector<nlohmann::json> result; |
| result.reserve(v.size()); |
| for (const T& t : v) { |
| result.push_back(t.ToJson()); |
| } |
| return result; |
| } |
| |
| nlohmann::json HeaderName::ToJson() const { |
| nlohmann::json result; |
| result["name"] = name_; |
| return result; |
| } |
| |
| nlohmann::json RsType::ToJson() const { |
| nlohmann::json result; |
| |
| if (decl_id.has_value()) { |
| result["decl_id"] = decl_id->value(); |
| } else { |
| result["name"] = name; |
| } |
| result["type_args"] = VectorToJson(type_args); |
| |
| return result; |
| } |
| |
| nlohmann::json CcType::ToJson() const { |
| nlohmann::json result; |
| |
| if (decl_id.has_value()) { |
| result["decl_id"] = decl_id->value(); |
| } else { |
| result["name"] = name; |
| } |
| result["is_const"] = is_const; |
| result["type_args"] = VectorToJson(type_args); |
| |
| return result; |
| } |
| |
| nlohmann::json MappedType::ToJson() const { |
| nlohmann::json result; |
| |
| result["rs_type"] = rs_type.ToJson(); |
| result["cc_type"] = cc_type.ToJson(); |
| |
| return result; |
| } |
| |
| nlohmann::json Identifier::ToJson() const { |
| nlohmann::json result; |
| result["identifier"] = identifier_; |
| return result; |
| } |
| |
| nlohmann::json FuncParam::ToJson() const { |
| nlohmann::json result; |
| result["type"] = type.ToJson(); |
| result["identifier"] = identifier.ToJson(); |
| return result; |
| } |
| |
| static std::string SpecialNameToString(SpecialName special_name) { |
| switch (special_name) { |
| case SpecialName::kDestructor: |
| return "Destructor"; |
| case SpecialName::kConstructor: |
| return "Constructor"; |
| } |
| } |
| |
| std::ostream& operator<<(std::ostream& o, const SpecialName& special_name) { |
| return o << SpecialNameToString(special_name); |
| } |
| |
| nlohmann::json MemberFuncMetadata::ToJson() const { |
| nlohmann::json meta; |
| |
| meta["for_type"] = for_type.ToJson(); |
| |
| if (instance_method_metadata.has_value()) { |
| nlohmann::json instance; |
| |
| absl::string_view reference; |
| switch (instance_method_metadata->reference) { |
| case MemberFuncMetadata::kLValue: |
| reference = "LValue"; |
| break; |
| case MemberFuncMetadata::kRValue: |
| reference = "RValue"; |
| break; |
| case MemberFuncMetadata::kUnqualified: |
| reference = "Unqualified"; |
| break; |
| } |
| instance["reference"] = reference; |
| instance["is_const"] = instance_method_metadata->is_const; |
| instance["is_virtual"] = instance_method_metadata->is_virtual; |
| |
| meta["instance_method_metadata"] = std::move(instance); |
| } |
| |
| return meta; |
| } |
| |
| nlohmann::json Func::ToJson() const { |
| nlohmann::json func; |
| if (auto* id = std::get_if<Identifier>(&name)) { |
| func["name"]["Identifier"] = id->ToJson(); |
| } else { |
| func["name"][SpecialNameToString(std::get<SpecialName>(name))] = nullptr; |
| } |
| func["decl_id"] = decl_id.value(); |
| func["owning_target"] = owning_target.value(); |
| if (doc_comment) { |
| func["doc_comment"] = *doc_comment; |
| } |
| func["mangled_name"] = mangled_name; |
| func["return_type"] = return_type.ToJson(); |
| func["params"] = VectorToJson(params); |
| func["is_inline"] = is_inline; |
| if (member_func_metadata.has_value()) { |
| func["member_func_metadata"] = member_func_metadata->ToJson(); |
| } |
| |
| nlohmann::json item; |
| item["Func"] = std::move(func); |
| return item; |
| } |
| |
| static std::string AccessToString(AccessSpecifier access) { |
| switch (access) { |
| case kPublic: |
| return "Public"; |
| case kProtected: |
| return "Protected"; |
| case kPrivate: |
| return "Private"; |
| } |
| } |
| |
| std::ostream& operator<<(std::ostream& o, const AccessSpecifier& access) { |
| return o << AccessToString(access); |
| } |
| |
| nlohmann::json Field::ToJson() const { |
| nlohmann::json result; |
| |
| result["identifier"] = identifier.ToJson(); |
| if (doc_comment) { |
| result["doc_comment"] = *doc_comment; |
| } |
| result["type"] = type.ToJson(); |
| result["access"] = AccessToString(access); |
| result["offset"] = offset; |
| return result; |
| } |
| |
| static std::string SpecialMemberDefinitionToString( |
| SpecialMemberFunc::Definition def) { |
| switch (def) { |
| case SpecialMemberFunc::Definition::kTrivial: |
| return "Trivial"; |
| case SpecialMemberFunc::Definition::kNontrivialMembers: |
| return "NontrivialMembers"; |
| case SpecialMemberFunc::Definition::kNontrivialSelf: |
| return "NontrivialSelf"; |
| case SpecialMemberFunc::Definition::kDeleted: |
| return "Deleted"; |
| } |
| } |
| |
| std::ostream& operator<<(std::ostream& o, |
| const SpecialMemberFunc::Definition& definition) { |
| return o << SpecialMemberDefinitionToString(definition); |
| } |
| |
| nlohmann::json SpecialMemberFunc::ToJson() const { |
| nlohmann::json result; |
| result["definition"] = SpecialMemberDefinitionToString(definition); |
| result["access"] = AccessToString(access); |
| return result; |
| } |
| |
| nlohmann::json Record::ToJson() const { |
| nlohmann::json record; |
| record["identifier"] = identifier.ToJson(); |
| record["decl_id"] = decl_id.value(); |
| record["owning_target"] = owning_target.value(); |
| if (doc_comment) { |
| record["doc_comment"] = *doc_comment; |
| } |
| record["fields"] = VectorToJson(fields); |
| record["size"] = size; |
| record["alignment"] = alignment; |
| record["copy_constructor"] = copy_constructor.ToJson(); |
| record["move_constructor"] = move_constructor.ToJson(); |
| record["destructor"] = destructor.ToJson(); |
| record["is_trivial_abi"] = is_trivial_abi; |
| |
| nlohmann::json item; |
| item["Record"] = std::move(record); |
| return item; |
| } |
| nlohmann::json SourceLoc::ToJson() const { |
| nlohmann::json source_loc; |
| source_loc["filename"] = filename; |
| source_loc["line"] = line; |
| source_loc["column"] = column; |
| return source_loc; |
| } |
| |
| nlohmann::json UnsupportedItem::ToJson() const { |
| nlohmann::json unsupported; |
| unsupported["name"] = name; |
| unsupported["message"] = message; |
| unsupported["source_loc"] = source_loc.ToJson(); |
| |
| nlohmann::json item; |
| item["UnsupportedItem"] = std::move(unsupported); |
| return item; |
| } |
| |
| nlohmann::json Comment::ToJson() const { |
| nlohmann::json comment; |
| comment["text"] = text; |
| |
| nlohmann::json item; |
| item["Comment"] = std::move(comment); |
| return item; |
| } |
| |
| nlohmann::json IR::ToJson() const { |
| std::vector<nlohmann::json> json_items; |
| json_items.reserve(items.size()); |
| for (const auto& item : items) { |
| std::visit([&](auto&& item) { json_items.push_back(item.ToJson()); }, item); |
| } |
| |
| nlohmann::json result; |
| result["used_headers"] = VectorToJson(used_headers); |
| result["current_target"] = current_target.value(); |
| result["items"] = std::move(json_items); |
| return result; |
| } |
| |
| } // namespace rs_bindings_from_cc |