mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:20:13 +01:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user