forked from carbon-language/carbon-lang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bindings.h
92 lines (70 loc) · 2.89 KB
/
bindings.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// 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_