Import C++ class A final as Carbon final class. (#5866)

Also import unions as final classes, and abstract classes as `abstract
class`es.
This commit is contained in:
Richard Smith
2025-07-30 00:41:42 +00:00
committed by GitHub
parent 6b83414ee8
commit ef475d8197
4 changed files with 214 additions and 578 deletions
+33
View File
@@ -497,6 +497,37 @@ static auto BuildClassDecl(Context& context,
return {class_decl.class_id, context.types().GetAsTypeInstId(class_decl_id)};
}
// Determines the Carbon inheritance kind to use for a C++ class definition.
static auto GetInheritanceKind(clang::CXXRecordDecl* class_def)
-> SemIR::Class::InheritanceKind {
if (class_def->isUnion()) {
// Treat all unions as final classes to match their C++ semantics. While we
// could support this, the author of a C++ union has no way to mark their
// type as `final` to prevent it, and so we assume the intent was to
// disallow inheritance.
return SemIR::Class::Final;
}
if (class_def->hasAttr<clang::FinalAttr>()) {
// The class is final in C++; don't allow Carbon types to derive from it.
// Note that such a type might also be abstract in C++; we treat final as
// taking precedence.
//
// We could also treat classes with a final destructor as being final, as
// Clang does when determining whether a class is "effectively final", but
// to keep our rules simpler we do not.
return SemIR::Class::Final;
}
if (class_def->isAbstract()) {
// If the class has any abstract members, it's abstract.
return SemIR::Class::Abstract;
}
// Allow inheritance from any other C++ class type.
return SemIR::Class::Base;
}
// Checks that the specified finished class definition is valid and builds and
// returns a corresponding complete type witness instruction.
// TODO: Remove recursion into mapping field types.
@@ -685,6 +716,8 @@ static auto BuildClassDefinition(Context& context,
context.inst_block_stack().Push();
class_info.inheritance_kind = GetInheritanceKind(clang_def);
// Compute the class's object representation.
auto object_repr_id = ImportClassObjectRepr(
context, class_id, import_ir_inst_id, class_inst_id, clang_def);