Import C++ vtables (#7174)

This correctly renders the vtable in SemIR, including allowing overrides
in
Carbon-derived-from-C++ classes.

It doesn't work in lowering because clang walks the methods of the
CXXRecordDecl - and we currently don't export anything into the
CXXRecordDecl's methods (we do export the fields) - so that's next.

This also doesn't teach Clang to affirmatively emit the vtable
regardless of the types use in C++ code - or to have Carbon use the
vtable in an object's initialization.
This commit is contained in:
David Blaikie
2026-05-11 17:33:08 +00:00
committed by GitHub
parent 0f5de499d6
commit df8b25522e
8 changed files with 508 additions and 46 deletions
+33
View File
@@ -861,6 +861,39 @@ static auto BuildClassDefinition(Context& context,
context, SemIR::WitnessType::TypeInstId),
.object_repr_type_inst_id = object_repr_id}));
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_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(
context, SemIR::LocId(import_ir_inst_id),
const_cast<clang::CXXMethodDecl*>(method_decl),
{.num_params = static_cast<int32_t>(method_decl->getNumParams())}));
}
vtable.truncate(num_components);
auto vtable_id = context.vtables().Add(
{{.class_id = class_id,
.virtual_functions_id = context.inst_blocks().Add(vtable),
.carbon_native_vtable = false}});
auto vptr_type_id = GetPointerType(context, SemIR::VtableType::TypeInstId);
class_info.vtable_decl_id =
AddInst(context, SemIR::LocIdAndInst::RuntimeVerified(
context.sem_ir(), import_ir_inst_id,
SemIR::VtableDecl{.type_id = vptr_type_id,
.vtable_id = vtable_id}));
}
class_info.body_block_id = context.inst_block_stack().Pop();
}