blob: 89d05c31ca462cbd555a69354eb16b4a8df2fbf2 [file] [log] [blame]
// 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
// This file defines an intermediate representation (IR) used between Clang AST
// and code generators that generate Rust bindings and C++ bindings
// implementation.
//
// All types in this file own their data. This IR is expected to outlive the
// Clang's AST context, therefore it cannot reference data owned by it.
#ifndef CRUBIT_RS_BINDINGS_FROM_CC_IR_H_
#define CRUBIT_RS_BINDINGS_FROM_CC_IR_H_
#include <string>
#include <utility>
#include <vector>
#include "base/logging.h"
#include "third_party/absl/strings/string_view.h"
#include "third_party/json/src/json.hpp"
namespace rs_bindings_from_cc {
namespace internal {
inline constexpr absl::string_view kRustPtrMut = "*mut";
inline constexpr absl::string_view kCcPtrMut = "*";
} // namespace internal
// A name of a public header of the C++ library.
class HeaderName {
public:
explicit HeaderName(std::string name) : name_(std::move(name)) {}
absl::string_view IncludePath() const { return name_; }
nlohmann::json ToJson() const;
private:
// Header pathname in the format suitable for a google3-relative quote
// include.
std::string name_;
};
// A type involved in the bindings. It has the knowledge about how the type is
// spelled in Rust and in C++ code.
//
// Examples:
// C++'s `int32_t` will be `Type{"i32", "int"}`.
// C++'s `struct Foo` will be `Type{"Foo", "Foo"}`.
// C++'s `int*` will be `Type{"*mut", "*", {Type{"i32", "int"}}}
struct Type {
static Type Void() { return Type{"()", "void"}; }
bool IsVoid() const { return rs_name == "()"; }
static Type PointerTo(Type pointee_type) {
// TODO(b/200016113): Decide how to handle const.
auto pointer_type = Type{std::string(internal::kRustPtrMut),
std::string(internal::kCcPtrMut)};
pointer_type.type_params.push_back(std::move(pointee_type));
return pointer_type;
}
nlohmann::json ToJson() const;
// The rust name of the type. For example, i32 or ().
std::string rs_name;
// The C++ name for the type. For example, int or void.
std::string cc_name;
// Type parameters for a generic type. Examples:
// int* has a single type parameter, int.
// tuple<int, float> has two type parameters, int and float.
std::vector<Type> type_params = {};
};
// An identifier involved in bindings.
//
// Examples:
// Identifier of C++'s `int32_t Add(int32_t a, int32_t b)` will be
// `Identifier("add")`.
//
// Invariants:
// `identifier` cannot be empty.
class Identifier {
public:
explicit Identifier(std::string identifier)
: identifier_(std::move(identifier)) {
CHECK(!identifier_.empty()) << "Identifier name cannot be empty.";
}
absl::string_view Ident() const { return identifier_; }
nlohmann::json ToJson() const;
private:
std::string identifier_;
};
// A function parameter.
//
// Examples:
// FuncParam of a C++ function `void Foo(int32_t a);` will be
// `FuncParam{.type=Type{"i32", "int32_t"}, .identifier=Identifier("foo"))`.
struct FuncParam {
nlohmann::json ToJson() const;
Type type;
Identifier identifier;
};
// A function involved in the bindings.
struct Func {
nlohmann::json ToJson() const;
Identifier identifier;
std::string mangled_name;
Type return_type;
std::vector<FuncParam> params;
bool is_inline;
};
// Access specifier for a member or base class.
enum AccessSpecifier {
kPublic,
kProtected,
kPrivate,
};
// A field (non-static member variable) of a record.
struct Field {
nlohmann::json ToJson() const;
Identifier identifier;
Type type;
AccessSpecifier access;
};
// A record (struct, class, union).
class Record {
public:
Record(Identifier identifier, std::vector<Field> fields)
: identifier_(std::move(identifier)), fields_(std::move(fields)) {}
const Identifier& Ident() const { return identifier_; }
const std::vector<Field>& Fields() const { return fields_; }
nlohmann::json ToJson() const;
private:
Identifier identifier_;
std::vector<Field> fields_;
};
// A complete intermediate representation of bindings for publicly accessible
// declarations of a single C++ library.
struct IR {
nlohmann::json ToJson() const;
// Collection of public headers that were used to construct the AST this `IR`
// is generated from.
std::vector<HeaderName> used_headers;
std::vector<Func> functions;
std::vector<Record> records;
};
} // namespace rs_bindings_from_cc
#endif // CRUBIT_RS_BINDINGS_FROM_CC_IR_H_