From 34805543a166f92d5ed8a2608ec5cde7e5d4da0b Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Thu, 11 Sep 2025 14:58:26 +0200 Subject: [PATCH] Sort functions in `import_cpp.cpp` per `import_cpp.h` (#6048) Context: https://github.com/carbon-language/carbon-lang/pull/5891#discussion_r2247678242 --- toolchain/check/import_cpp.cpp | 122 ++++++++++++++++----------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index 5d46689414bc..6428f8f432a0 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -1088,67 +1088,6 @@ static auto BuildEnumDefinition(Context& context, class_info.body_block_id = context.inst_block_stack().Pop(); } -auto ImportClassDefinitionForClangDecl(Context& context, SemIR::LocId loc_id, - SemIR::ClassId class_id, - SemIR::ClangDeclId clang_decl_id) - -> bool { - clang::ASTUnit* ast = context.sem_ir().clang_ast_unit(); - CARBON_CHECK(ast); - - auto* clang_decl = cast( - context.sem_ir().clang_decls().Get(clang_decl_id).decl); - auto class_inst_id = context.types().GetAsTypeInstId( - context.classes().Get(class_id).first_owning_decl_id); - - // TODO: Map loc_id into a clang location and use it for diagnostics if - // instantiation fails, instead of annotating the diagnostic with another - // location. - clang::SourceLocation loc = clang_decl->getLocation(); - Diagnostics::AnnotationScope annotate_diagnostics( - &context.emitter(), [&](auto& builder) { - CARBON_DIAGNOSTIC(InCppTypeCompletion, Note, - "while completing C++ type {0}", SemIR::TypeId); - builder.Note(loc_id, InCppTypeCompletion, - context.classes().Get(class_id).self_type_id); - }); - - // Ask Clang whether the type is complete. This triggers template - // instantiation if necessary. - clang::DiagnosticErrorTrap trap(ast->getDiagnostics()); - if (!ast->getSema().isCompleteType( - loc, context.ast_context().getCanonicalTagType(clang_decl))) { - // Type is incomplete. Nothing more to do, but tell the caller if we - // produced an error. - return !trap.hasErrorOccurred(); - } - - auto import_ir_inst_id = - context.insts().GetCanonicalLocId(class_inst_id).import_ir_inst_id(); - - if (auto* class_decl = dyn_cast(clang_decl)) { - auto* class_def = class_decl->getDefinition(); - CARBON_CHECK(class_def, "Complete type has no definition"); - - if (class_def->getNumVBases()) { - // TODO: Handle virtual bases. We don't actually know where they go in the - // layout. We may also want to use a different size in the layout for - // `partial C`, excluding the virtual base. It's also not entirely safe to - // just skip over the virtual base, as the type we would construct would - // have a misleading size. For now, treat a C++ class with vbases as - // incomplete in Carbon. - context.TODO(loc_id, "class with virtual bases"); - return false; - } - - BuildClassDefinition(context, import_ir_inst_id, class_id, class_inst_id, - class_def); - } else if (auto* enum_decl = dyn_cast(clang_decl)) { - BuildEnumDefinition(context, import_ir_inst_id, class_id, class_inst_id, - enum_decl); - } - return true; -} - // Imports an enumerator declaration from Clang to Carbon. static auto ImportEnumConstantDecl(Context& context, clang::EnumConstantDecl* enumerator_decl) @@ -2253,4 +2192,65 @@ auto ImportOperatorFromCpp(Context& context, SemIR::LocId loc_id, access_kind); } +auto ImportClassDefinitionForClangDecl(Context& context, SemIR::LocId loc_id, + SemIR::ClassId class_id, + SemIR::ClangDeclId clang_decl_id) + -> bool { + clang::ASTUnit* ast = context.sem_ir().clang_ast_unit(); + CARBON_CHECK(ast); + + auto* clang_decl = cast( + context.sem_ir().clang_decls().Get(clang_decl_id).decl); + auto class_inst_id = context.types().GetAsTypeInstId( + context.classes().Get(class_id).first_owning_decl_id); + + // TODO: Map loc_id into a clang location and use it for diagnostics if + // instantiation fails, instead of annotating the diagnostic with another + // location. + clang::SourceLocation loc = clang_decl->getLocation(); + Diagnostics::AnnotationScope annotate_diagnostics( + &context.emitter(), [&](auto& builder) { + CARBON_DIAGNOSTIC(InCppTypeCompletion, Note, + "while completing C++ type {0}", SemIR::TypeId); + builder.Note(loc_id, InCppTypeCompletion, + context.classes().Get(class_id).self_type_id); + }); + + // Ask Clang whether the type is complete. This triggers template + // instantiation if necessary. + clang::DiagnosticErrorTrap trap(ast->getDiagnostics()); + if (!ast->getSema().isCompleteType( + loc, context.ast_context().getCanonicalTagType(clang_decl))) { + // Type is incomplete. Nothing more to do, but tell the caller if we + // produced an error. + return !trap.hasErrorOccurred(); + } + + auto import_ir_inst_id = + context.insts().GetCanonicalLocId(class_inst_id).import_ir_inst_id(); + + if (auto* class_decl = dyn_cast(clang_decl)) { + auto* class_def = class_decl->getDefinition(); + CARBON_CHECK(class_def, "Complete type has no definition"); + + if (class_def->getNumVBases()) { + // TODO: Handle virtual bases. We don't actually know where they go in the + // layout. We may also want to use a different size in the layout for + // `partial C`, excluding the virtual base. It's also not entirely safe to + // just skip over the virtual base, as the type we would construct would + // have a misleading size. For now, treat a C++ class with vbases as + // incomplete in Carbon. + context.TODO(loc_id, "class with virtual bases"); + return false; + } + + BuildClassDefinition(context, import_ir_inst_id, class_id, class_inst_id, + class_def); + } else if (auto* enum_decl = dyn_cast(clang_decl)) { + BuildEnumDefinition(context, import_ir_inst_id, class_id, class_inst_id, + enum_decl); + } + return true; +} + } // namespace Carbon::Check