mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Implement correctly overriding dependent virtual functions (#5804)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
9f67fa4b0f
commit
3bf98e9bc2
@@ -174,9 +174,11 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
|
||||
context.vtables().Get(base_vtable_id).virtual_functions_id);
|
||||
// TODO: Avoid quadratic search. Perhaps build a map from `NameId` to the
|
||||
// elements of the top of `vtable_stack`.
|
||||
for (auto fn_decl_id : base_vtable_inst_block) {
|
||||
auto fn_decl = GetCalleeFunction(context.sem_ir(), fn_decl_id);
|
||||
const auto& fn = context.functions().Get(fn_decl.function_id);
|
||||
for (auto base_vtable_entry_id : base_vtable_inst_block) {
|
||||
auto [derived_vtable_entry_id, fn_id, specific_id] =
|
||||
DecomposeVirtualFunction(context.sem_ir(), base_vtable_entry_id,
|
||||
base_class_specific_id);
|
||||
const auto& fn = context.sem_ir().functions().Get(fn_id);
|
||||
const auto* i = llvm::find_if(
|
||||
vtable_contents, [&](SemIR::InstId override_fn_decl_id) -> bool {
|
||||
const auto& override_fn = context.functions().Get(
|
||||
@@ -190,25 +192,14 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
|
||||
if (i != vtable_contents.end()) {
|
||||
auto& override_fn = context.functions().Get(
|
||||
context.insts().GetAs<SemIR::FunctionDecl>(*i).function_id);
|
||||
// TODO: Support generic base classes, rather than passing
|
||||
// `SpecificId::None`. This'll need to `GetConstantValueInSpecific` for
|
||||
// the base function, then extract the specific from that for use here.
|
||||
CheckFunctionTypeMatches(context, override_fn, fn,
|
||||
SemIR::SpecificId::None,
|
||||
CheckFunctionTypeMatches(context, override_fn, fn, specific_id,
|
||||
/*check_syntax=*/false,
|
||||
/*check_self=*/false);
|
||||
fn_decl_id = build_specific_function(*i);
|
||||
derived_vtable_entry_id = build_specific_function(*i);
|
||||
override_fn.virtual_index = vtable.size();
|
||||
CARBON_CHECK(override_fn.virtual_index == fn.virtual_index);
|
||||
} else {
|
||||
// Remap the base's vtable entry to the appropriate constant usable in
|
||||
// the context of the derived class (for the specific for the base
|
||||
// class, for instance)..
|
||||
fn_decl_id = context.sem_ir().constant_values().GetInstId(
|
||||
GetConstantValueInSpecific(context.sem_ir(), base_class_specific_id,
|
||||
fn_decl_id));
|
||||
}
|
||||
vtable.push_back(fn_decl_id);
|
||||
vtable.push_back(derived_vtable_entry_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user