blob: 628cd949fd628d541ea4dae038a12a6f136fd801 [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 <utility>
#include <vector>
#include "base/logging.h"
#include "third_party/absl/strings/cord.h"
#include "third_party/json/src/json.hpp"
namespace rs_bindings_from_cc {
// A name of a public header of the C++ library.
class HeaderName {
public:
explicit HeaderName(absl::Cord name) : name_(std::move(name)) {}
const absl::Cord &IncludePath() const { return name_; }
nlohmann::json ToJson() const;
private:
// Header pathname in the format suitable for a google3-relative quote
// include.
absl::Cord name_;
};
// A type involved in the bindings. It has the knowledge about how the type is
// spelled in Rust and in C++ code.
//
// Examples:
// Type of C++'s `int32_t` will be `Type("i32")`.
// Type of C++'s `struct foo` will be `Type("Foo")`.
//
// Conventions:
// `rs_name` cannot be empty.
// TODO(hlopko): Add knowledge about the spelling of the C++ type.
class Type {
public:
explicit Type(absl::Cord rs_name) : rs_name_(std::move(rs_name)) {}
static Type Void() { return Type(absl::Cord("()")); }
bool IsVoid() const { return rs_name_ == "()"; }
const absl::Cord &RsName() const { return rs_name_; }
nlohmann::json ToJson() const;
private:
absl::Cord rs_name_;
};
// 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(absl::Cord identifier)
: identifier_(std::move(identifier)) {
CHECK(!identifier_.empty()) << "Identifier name cannot be empty.";
}
const absl::Cord &Ident() const { return identifier_; }
nlohmann::json ToJson() const;
private:
absl::Cord identifier_;
};
// A function parameter.
//
// Examples:
// FuncParam of a C++ function `void Foo(int32_t a);` will be
// `FuncParam(Type("i32"), Identifier("foo"))`.
class FuncParam {
public:
explicit FuncParam(Type type, Identifier identifier)
: type_(std::move(type)), identifier_(std::move(identifier)) {}
const Type &ParamType() const { return type_; }
const Identifier &Ident() const { return identifier_; }
nlohmann::json ToJson() const;
private:
Type type_;
Identifier identifier_;
};
// A function involved in the bindings.
class Func {
public:
explicit Func(Identifier identifier, absl::Cord mangled_name,
Type return_type, std::vector<FuncParam> params)
: identifier_(std::move(identifier)),
mangled_name_(std::move(mangled_name)),
return_type_(std::move(return_type)),
params_(std::move(params)) {}
const absl::Cord &MangledName() const { return mangled_name_; }
const Type &ReturnType() const { return return_type_; }
const Identifier &Ident() const { return identifier_; }
const std::vector<FuncParam> &Params() const { return params_; }
nlohmann::json ToJson() const;
private:
Identifier identifier_;
absl::Cord mangled_name_;
Type return_type_;
std::vector<FuncParam> params_;
};
// A complete intermediate representation of bindings for publicly accessible
// declarations of a single C++ library.
class IR {
public:
explicit IR() {}
explicit IR(std::vector<HeaderName> used_headers, std::vector<Func> functions)
: used_headers_(std::move(used_headers)),
functions_(std::move(functions)) {}
nlohmann::json ToJson() const;
const std::vector<HeaderName> &UsedHeaders() const { return used_headers_; }
std::vector<HeaderName> &UsedHeaders() { return used_headers_; }
const std::vector<Func> &Functions() const { return functions_; }
std::vector<Func> &Functions() { return functions_; }
private:
// 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_;
};
} // namespace rs_bindings_from_cc
#endif // CRUBIT_RS_BINDINGS_FROM_CC_IR_H_