mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-28 07:40:11 +01:00
With the toolchain splitting namespaces, ostream.h's `operator<<` templates aren't reliably found with name lookup, likely due to the loss of associated namespaces (zygoloid commented on this at https://github.com/carbon-language/carbon-lang/pull/3161#discussion_r1307941999). This is especially a barrier to moving the lex files into `Carbon::Lex`; versus other parts of the toolchain, they contain more printable types which are used cross-namespace, including `Carbon::Testing`. As a consequence, I'm looking at migrating ostream.h to a more reliable approach that doesn't rely as much on everything being in the `Carbon` namespace.
93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#ifndef CARBON_EXPLORER_AST_BINDINGS_H_
|
|
#define CARBON_EXPLORER_AST_BINDINGS_H_
|
|
|
|
#include <map>
|
|
#include <utility>
|
|
|
|
#include "common/ostream.h"
|
|
#include "explorer/ast/clone_context.h"
|
|
#include "explorer/base/nonnull.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
namespace Carbon {
|
|
|
|
class Arena;
|
|
class ImplBinding;
|
|
class GenericBinding;
|
|
class Value;
|
|
|
|
using BindingMap =
|
|
std::map<Nonnull<const GenericBinding*>, Nonnull<const Value*>>;
|
|
using ImplWitnessMap =
|
|
std::map<Nonnull<const ImplBinding*>, Nonnull<const Value*>>;
|
|
|
|
// A set of evaluated bindings in some context, such as a function or class.
|
|
//
|
|
// These are shared by a context and all unparameterized entities within that
|
|
// context. For example, a class and the name of a method within that class
|
|
// will have the same set of bindings.
|
|
class Bindings : public Printable<Bindings> {
|
|
public:
|
|
// Gets an empty set of bindings.
|
|
static auto None() -> Nonnull<const Bindings*>;
|
|
|
|
// Makes a set of symbolic identity bindings for the given collection of
|
|
// generic bindings and their impl bindings.
|
|
static auto SymbolicIdentity(
|
|
Nonnull<Arena*> arena,
|
|
llvm::ArrayRef<Nonnull<const GenericBinding*>> bindings)
|
|
-> Nonnull<const Bindings*>;
|
|
|
|
// Create an empty set of bindings.
|
|
Bindings() = default;
|
|
|
|
// Create an instantiated set of bindings for use during evaluation,
|
|
// containing both arguments and witnesses.
|
|
explicit Bindings(BindingMap args, ImplWitnessMap witnesses)
|
|
: args_(std::move(args)), witnesses_(std::move(witnesses)) {}
|
|
|
|
enum NoWitnessesTag { NoWitnesses };
|
|
|
|
// Create a set of bindings for use during type-checking, containing only the
|
|
// arguments but not the corresponding witnesses.
|
|
explicit Bindings(BindingMap args, NoWitnessesTag /*unused*/)
|
|
: args_(std::move(args)) {}
|
|
|
|
explicit Bindings(CloneContext& context, const Bindings& other);
|
|
|
|
template <typename F>
|
|
auto Decompose(F f) const {
|
|
return f(args_, witnesses_);
|
|
}
|
|
|
|
void Print(llvm::raw_ostream& out) const;
|
|
|
|
// Add a value, and perhaps a witness, for a generic binding.
|
|
void Add(Nonnull<const GenericBinding*> binding, Nonnull<const Value*> value,
|
|
std::optional<Nonnull<const Value*>> witness);
|
|
|
|
// Argument values corresponding to generic bindings.
|
|
auto args() const -> const BindingMap& { return args_; }
|
|
|
|
// Witnesses corresponding to impl bindings.
|
|
auto witnesses() const -> const ImplWitnessMap& { return witnesses_; }
|
|
|
|
// Determine whether this is an empty set of bindings.
|
|
[[nodiscard]] auto empty() const -> bool {
|
|
return args_.empty() && witnesses_.empty();
|
|
}
|
|
|
|
private:
|
|
BindingMap args_;
|
|
ImplWitnessMap witnesses_;
|
|
};
|
|
|
|
} // namespace Carbon
|
|
|
|
#endif // CARBON_EXPLORER_AST_BINDINGS_H_
|