mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Create a Generic object to represent a generic. (#4081)
Build a `Generic` object for generic functions. This object tracks the generic parameters that are in scope for the generic entity. Eventually it will track other information about the generic too. Add basic SemIR formatting support for generic functions.
This commit is contained in:
@@ -56,6 +56,16 @@ auto ScopeStack::Pop() -> void {
|
||||
CARBON_CHECK(return_scope_stack_.back().returned_var.is_valid());
|
||||
return_scope_stack_.back().returned_var = SemIR::InstId::Invalid;
|
||||
}
|
||||
|
||||
CARBON_CHECK(scope.next_compile_time_bind_index.index ==
|
||||
static_cast<int32_t>(compile_time_binding_stack_.size()))
|
||||
<< "Wrong number of entries in compile-time binding stack, have "
|
||||
<< compile_time_binding_stack_.size() << ", expected "
|
||||
<< scope.next_compile_time_bind_index.index;
|
||||
compile_time_binding_stack_.truncate(
|
||||
scope_stack_.empty()
|
||||
? 0
|
||||
: scope_stack_.back().next_compile_time_bind_index.index);
|
||||
}
|
||||
|
||||
auto ScopeStack::PopTo(ScopeIndex index) -> void {
|
||||
@@ -147,13 +157,35 @@ auto ScopeStack::SetReturnedVarOrGetExisting(SemIR::InstId inst_id)
|
||||
auto ScopeStack::Suspend() -> SuspendedScope {
|
||||
CARBON_CHECK(!scope_stack_.empty()) << "No scope to suspend";
|
||||
SuspendedScope result = {.entry = scope_stack_.pop_back_val(),
|
||||
.suspended_lookups = {}};
|
||||
.suspended_items = {}};
|
||||
if (result.entry.scope_id.is_valid()) {
|
||||
non_lexical_scope_stack_.pop_back();
|
||||
}
|
||||
|
||||
auto remaining_compile_time_bindings =
|
||||
scope_stack_.empty()
|
||||
? 0
|
||||
: scope_stack_.back().next_compile_time_bind_index.index;
|
||||
|
||||
result.suspended_items.reserve(result.entry.names.size() +
|
||||
compile_time_binding_stack_.size() -
|
||||
remaining_compile_time_bindings);
|
||||
for (auto name_id : result.entry.names) {
|
||||
result.suspended_lookups.push_back(lexical_lookup_.Suspend(name_id));
|
||||
auto [index, inst_id] = lexical_lookup_.Suspend(name_id);
|
||||
CARBON_CHECK(index !=
|
||||
SuspendedScope::ScopeItem::IndexForCompileTimeBinding);
|
||||
result.suspended_items.push_back({.index = index, .inst_id = inst_id});
|
||||
}
|
||||
|
||||
// Move any compile-time bindings into the suspended scope.
|
||||
for (auto inst_id : llvm::ArrayRef(compile_time_binding_stack_)
|
||||
.drop_back(remaining_compile_time_bindings)) {
|
||||
result.suspended_items.push_back(
|
||||
{.index = SuspendedScope::ScopeItem::IndexForCompileTimeBinding,
|
||||
.inst_id = inst_id});
|
||||
}
|
||||
compile_time_binding_stack_.truncate(remaining_compile_time_bindings);
|
||||
|
||||
// This would be easy to support if we had a need, but currently we do not.
|
||||
CARBON_CHECK(!result.entry.has_returned_var)
|
||||
<< "Should not suspend a scope with a returned var.";
|
||||
@@ -161,13 +193,22 @@ auto ScopeStack::Suspend() -> SuspendedScope {
|
||||
}
|
||||
|
||||
auto ScopeStack::Restore(SuspendedScope scope) -> void {
|
||||
for (auto entry : scope.suspended_lookups) {
|
||||
// clang-tidy warns that the `std::move` below has no effect. While that's
|
||||
// true, this `move` defends against the suspended lookup growing more state
|
||||
// later.
|
||||
// NOLINTNEXTLINE(performance-move-const-arg)
|
||||
lexical_lookup_.Restore(std::move(entry), scope.entry.index);
|
||||
for (auto [index, inst_id] : scope.suspended_items) {
|
||||
if (index == SuspendedScope::ScopeItem::IndexForCompileTimeBinding) {
|
||||
compile_time_binding_stack_.push_back(inst_id);
|
||||
} else {
|
||||
lexical_lookup_.Restore({.index = index, .inst_id = inst_id},
|
||||
scope.entry.index);
|
||||
}
|
||||
}
|
||||
|
||||
CARBON_CHECK(scope.entry.next_compile_time_bind_index.index ==
|
||||
static_cast<int32_t>(compile_time_binding_stack_.size()))
|
||||
<< "Wrong number of entries in compile-time binding stack "
|
||||
"when restoring, have "
|
||||
<< compile_time_binding_stack_.size() << ", expected "
|
||||
<< scope.entry.next_compile_time_bind_index.index;
|
||||
|
||||
if (scope.entry.scope_id.is_valid()) {
|
||||
non_lexical_scope_stack_.push_back({.scope_index = scope.entry.index,
|
||||
.name_scope_id = scope.entry.scope_id});
|
||||
|
||||
Reference in New Issue
Block a user