diff --git a/toolchain/check/cpp/generate_ast.cpp b/toolchain/check/cpp/generate_ast.cpp index 7d6149c35e61..5a75ac6a540e 100644 --- a/toolchain/check/cpp/generate_ast.cpp +++ b/toolchain/check/cpp/generate_ast.cpp @@ -501,10 +501,14 @@ auto CarbonExternalASTSource::CompleteType(clang::TagDecl* tag_decl) -> void { llvm::SmallVector pending_virtual_functions; if (class_info.vtable_decl_id.has_value()) { + LoadImportRef(*context_, class_info.vtable_decl_id); + auto canonical_vtable_decl_id = + context_->constant_values().GetConstantInstId( + class_info.vtable_decl_id); auto vtable_inst_block = context_->inst_blocks().Get( context_->vtables() .Get(context_->insts() - .GetAs(class_info.vtable_decl_id) + .GetAs(canonical_vtable_decl_id) .vtable_id) .virtual_functions_id); for (auto vtable_entry_id : vtable_inst_block) { diff --git a/toolchain/check/cpp/import.cpp b/toolchain/check/cpp/import.cpp index 753303875f24..0b1aa7950ad4 100644 --- a/toolchain/check/cpp/import.cpp +++ b/toolchain/check/cpp/import.cpp @@ -362,28 +362,13 @@ auto ImportCppConstantFromFile(Context& context, SemIR::LocId loc_id, return SemIR::ErrorInst::ConstantId; } - auto const_inst_id = file.constant_values().GetConstantInstId(inst_id); - CARBON_KIND_SWITCH(file.insts().Get(const_inst_id)) { - case CARBON_KIND(SemIR::ClassType class_type): { - const auto& class_info = file.classes().Get(class_type.class_id); - CARBON_CHECK(class_info.scope_id.has_value()); - return ImportCppDeclFromFile( - context, loc_id, file, - file.name_scopes().Get(class_info.scope_id).clang_decl_context_id()); - } - - case CARBON_KIND(SemIR::Namespace namespace_decl): { - return ImportCppDeclFromFile(context, loc_id, file, - file.name_scopes() - .Get(namespace_decl.name_scope_id) - .clang_decl_context_id()); - } - - default: { - context.TODO(loc_id, "indirect import of unsupported C++ declaration"); - return SemIR::ErrorInst::ConstantId; - } + if (const auto* clang_decl = file.clang_decls().Lookup(inst_id)) { + auto clang_decl_id = file.clang_decls().LookupId(clang_decl->key); + return ImportCppDeclFromFile(context, loc_id, file, clang_decl_id); } + + context.TODO(loc_id, "indirect import of unsupported C++ declaration"); + return SemIR::ErrorInst::ConstantId; } // Returns the Clang `DeclContext` for the given name scope. Return the diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 8900b155b80a..9393efed26fc 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -2612,6 +2612,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, auto thunk_specific_data = GetLocalSpecificData( resolver, import_thunk_info ? import_thunk_info->specific_id : SemIR::SpecificId::None); + auto thunk_override_self_type_const_id = SemIR::ConstantId::None; + if (import_thunk_info) { + thunk_override_self_type_const_id = + GetLocalConstantId(resolver, import_thunk_info->override_self_type_id); + } auto& new_function = resolver.local_functions().Get(function_id); if (resolver.HasNewWork()) { @@ -2680,6 +2685,11 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver, local_thunk_info.specific_id = GetOrAddLocalSpecific( resolver, import_thunk_info->specific_id, thunk_specific_data); } + if (thunk_override_self_type_const_id.has_value()) { + local_thunk_info.override_self_type_id = + resolver.local_types().GetTypeIdForTypeConstantId( + thunk_override_self_type_const_id); + } new_function.SetThunk(resolver.local_ir().thunks().Add(local_thunk_info)); break; } diff --git a/toolchain/check/testdata/interop/cpp/class/export/override.carbon b/toolchain/check/testdata/interop/cpp/class/export/override.carbon index 6627eec6ec7c..222f591d54a5 100644 --- a/toolchain/check/testdata/interop/cpp/class/export/override.carbon +++ b/toolchain/check/testdata/interop/cpp/class/export/override.carbon @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // INCLUDE-FILE: toolchain/testing/testdata/min_prelude/destroy.carbon +// EXTRA-ARGS: --share-cpp-ast // // AUTOUPDATE // TIP: To test this file alone, run: @@ -30,3 +31,29 @@ class B { inline Cpp ''' Carbon::B b; '''; + +// --- base.h +struct Base { + virtual ~Base(); + virtual void F() = 0; +}; + +// --- derived.carbon +library "derived"; +import Cpp library "base.h"; + +class Derived { + extend base: Cpp.Base; + override fn F(unused self) {} +} + +// --- imported.carbon +library "imported"; +import Cpp library "base.h"; +import library "derived"; + +inline Cpp ''' +void Test() { + Carbon::Derived d; +} +''';