mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-27 22:02:33 +01:00
This is intended to be used for template instantiation, but for now takes no stance as to what it's cloning. This is tested by parsing and cloning all of our test files, and checking that the result of converting each AST to proto is the same as the result of cloning and then converting each AST to proto.
60 lines
2.0 KiB
C++
60 lines
2.0 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
|
|
|
|
#include "explorer/ast/bindings.h"
|
|
|
|
#include "common/error.h"
|
|
#include "explorer/ast/impl_binding.h"
|
|
#include "explorer/ast/pattern.h"
|
|
#include "explorer/ast/value.h"
|
|
|
|
namespace Carbon {
|
|
|
|
Bindings::Bindings(CloneContext& context, const Bindings& other) {
|
|
for (auto [binding, value] : other.args_) {
|
|
args_.insert({context.Remap(binding), context.Clone(value)});
|
|
}
|
|
for (auto [binding, value] : other.witnesses_) {
|
|
witnesses_.insert({context.Remap(binding), context.Clone(value)});
|
|
}
|
|
}
|
|
|
|
void Bindings::Add(Nonnull<const GenericBinding*> binding,
|
|
Nonnull<const Value*> value,
|
|
std::optional<Nonnull<const Value*>> witness) {
|
|
bool added_value = args_.insert({binding, value}).second;
|
|
CARBON_CHECK(added_value) << "Add of already-existing binding";
|
|
|
|
if (witness) {
|
|
// TODO: Eventually we should check that we have a witness if and only if
|
|
// the binding has an impl binding.
|
|
auto impl_binding = binding->impl_binding();
|
|
CARBON_CHECK(impl_binding) << "Given witness but have no impl binding";
|
|
bool added_witness = witnesses_.insert({*impl_binding, *witness}).second;
|
|
CARBON_CHECK(added_witness) << "Add of already-existing binding";
|
|
}
|
|
}
|
|
|
|
auto Bindings::None() -> Nonnull<const Bindings*> {
|
|
static Nonnull<const Bindings*> bindings = new Bindings;
|
|
return bindings;
|
|
}
|
|
|
|
auto Bindings::SymbolicIdentity(
|
|
Nonnull<Arena*> arena,
|
|
llvm::ArrayRef<Nonnull<const GenericBinding*>> bindings)
|
|
-> Nonnull<const Bindings*> {
|
|
auto* result = arena->New<Bindings>();
|
|
for (const auto* binding : bindings) {
|
|
std::optional<Nonnull<const Value*>> witness;
|
|
if (binding->impl_binding()) {
|
|
witness = *binding->impl_binding().value()->symbolic_identity();
|
|
}
|
|
result->Add(binding, *binding->symbolic_identity(), witness);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace Carbon
|