mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-03 06:35:48 +01:00
Handle "gaps" in C++ vtables. (#7206)
Not every entry in a C++ vtable corresponds to a function that we want to import. For the holes, leave a `SemIR::InstId::None` in the vtable. Also mark vtables that extend a C++ vtable as being non-Carbon-native so we don't try to lower them (and crash on the `None` entries). In particular, we leave holes for destructors, since we don't have destructor declarations on the Carbon side that need to override them.
This commit is contained in:
@@ -939,25 +939,26 @@ static auto BuildClassDefinition(Context& context,
|
||||
|
||||
if (class_info.is_dynamic) {
|
||||
llvm::SmallVector<SemIR::InstId> vtable;
|
||||
const auto& vtable_layout = dyn_cast<clang::ItaniumVTableContext>(
|
||||
context.ast_context().getVTableContext())
|
||||
->getVTableLayout(clang_def);
|
||||
auto& vtable_context = *cast<clang::ItaniumVTableContext>(
|
||||
context.ast_context().getVTableContext());
|
||||
const auto& vtable_layout = vtable_context.getVTableLayout(clang_def);
|
||||
auto vtable_components = vtable_layout.vtable_components();
|
||||
vtable.reserve(vtable_components.size());
|
||||
auto num_components = 0;
|
||||
for (const auto& vtable_component : vtable_components) {
|
||||
if (vtable_component.getKind() !=
|
||||
clang::VTableComponent::CK_FunctionPointer) {
|
||||
continue;
|
||||
}
|
||||
++num_components;
|
||||
const auto* method_decl = vtable_component.getFunctionDecl();
|
||||
vtable.push_back(ImportCppFunctionDecl(
|
||||
auto virtual_index = vtable_context.getMethodVTableIndex(method_decl);
|
||||
if (virtual_index >= vtable.size()) {
|
||||
vtable.resize(virtual_index + 1, SemIR::InstId::None);
|
||||
}
|
||||
vtable[virtual_index] = ImportCppFunctionDecl(
|
||||
context, SemIR::LocId(import_ir_inst_id),
|
||||
const_cast<clang::CXXMethodDecl*>(method_decl),
|
||||
MakeVirtualFunctionSignature(context, method_decl)));
|
||||
MakeVirtualFunctionSignature(context, method_decl));
|
||||
}
|
||||
vtable.truncate(num_components);
|
||||
auto vtable_id = context.vtables().Add(
|
||||
{{.class_id = class_id,
|
||||
.virtual_functions_id = context.inst_blocks().Add(vtable),
|
||||
|
||||
Reference in New Issue
Block a user