Sort functions in import_cpp.cpp per import_cpp.h (#6048)

Context:
https://github.com/carbon-language/carbon-lang/pull/5891#discussion_r2247678242
This commit is contained in:
Boaz Brickner
2025-09-11 12:58:26 +00:00
committed by GitHub
parent 4776f3230b
commit 34805543a1
+61 -61
View File
@@ -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<clang::TagDecl>(
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::CXXRecordDecl>(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::EnumDecl>(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<clang::TagDecl>(
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::CXXRecordDecl>(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::EnumDecl>(clang_decl)) {
BuildEnumDefinition(context, import_ir_inst_id, class_id, class_inst_id,
enum_decl);
}
return true;
}
} // namespace Carbon::Check