mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Make C++ types impl Core.Default. (#6962)
C++ classes that are default-constructible now implement `Core.Default` by calling the default constructor.
This commit is contained in:
@@ -119,31 +119,6 @@ static auto BuildCopyWitness(
|
||||
query_specific_interface_id, {fn_id});
|
||||
}
|
||||
|
||||
static auto BuildDestroyWitness(
|
||||
Context& context, SemIR::LocId loc_id,
|
||||
SemIR::ConstantId query_self_const_id,
|
||||
SemIR::SpecificInterfaceId query_specific_interface_id,
|
||||
const TypeStructure* best_impl_type_structure,
|
||||
SemIR::LocId best_impl_loc_id) -> SemIR::InstId {
|
||||
auto& clang_sema = context.clang_sema();
|
||||
|
||||
// TODO: This should provide `Destroy` for enums and other trivially
|
||||
// destructible types.
|
||||
auto* class_decl = TypeAsClassDecl(context, query_self_const_id);
|
||||
if (!class_decl) {
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
auto decl_info = DeclInfo{.decl = clang_sema.LookupDestructor(class_decl),
|
||||
.signature = {.num_params = 0}};
|
||||
auto fn_id = GetFunctionId(context, loc_id, decl_info,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
||||
return fn_id;
|
||||
}
|
||||
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id, {fn_id});
|
||||
}
|
||||
|
||||
static auto BuildCppUnsafeDerefWitness(
|
||||
Context& context, SemIR::LocId loc_id,
|
||||
SemIR::ConstantId query_self_const_id,
|
||||
@@ -187,6 +162,61 @@ static auto BuildCppUnsafeDerefWitness(
|
||||
{result_type_id, fn_id});
|
||||
}
|
||||
|
||||
static auto BuildDefaultWitness(
|
||||
Context& context, SemIR::LocId loc_id,
|
||||
SemIR::ConstantId query_self_const_id,
|
||||
SemIR::SpecificInterfaceId query_specific_interface_id,
|
||||
const TypeStructure* best_impl_type_structure,
|
||||
SemIR::LocId best_impl_loc_id) -> SemIR::InstId {
|
||||
auto& clang_sema = context.clang_sema();
|
||||
|
||||
auto* class_decl = TypeAsClassDecl(context, query_self_const_id);
|
||||
if (!class_decl) {
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
// Clang would produce a warning for classes with uninitialized
|
||||
// [[clang::requires_init]] fields for which default initialization is
|
||||
// performed, and we don't have a good place to produce that warning.
|
||||
// That happens if class_decl->hasUninitializedExplicitInitFields() is true.
|
||||
//
|
||||
// TODO: Consider treating such types as not implementing `Default`.
|
||||
auto decl_info =
|
||||
DeclInfo{.decl = clang_sema.LookupDefaultConstructor(class_decl),
|
||||
.signature = {.num_params = 0}};
|
||||
auto fn_id = GetFunctionId(context, loc_id, decl_info,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
||||
return fn_id;
|
||||
}
|
||||
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id, {fn_id});
|
||||
}
|
||||
|
||||
static auto BuildDestroyWitness(
|
||||
Context& context, SemIR::LocId loc_id,
|
||||
SemIR::ConstantId query_self_const_id,
|
||||
SemIR::SpecificInterfaceId query_specific_interface_id,
|
||||
const TypeStructure* best_impl_type_structure,
|
||||
SemIR::LocId best_impl_loc_id) -> SemIR::InstId {
|
||||
auto& clang_sema = context.clang_sema();
|
||||
|
||||
// TODO: This should provide `Destroy` for enums and other trivially
|
||||
// destructible types.
|
||||
auto* class_decl = TypeAsClassDecl(context, query_self_const_id);
|
||||
if (!class_decl) {
|
||||
return SemIR::InstId::None;
|
||||
}
|
||||
auto decl_info = DeclInfo{.decl = clang_sema.LookupDestructor(class_decl),
|
||||
.signature = {.num_params = 0}};
|
||||
auto fn_id = GetFunctionId(context, loc_id, decl_info,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
if (fn_id == SemIR::ErrorInst::InstId || fn_id == SemIR::InstId::None) {
|
||||
return fn_id;
|
||||
}
|
||||
return BuildCustomWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id, {fn_id});
|
||||
}
|
||||
|
||||
auto LookupCppImpl(Context& context, SemIR::LocId loc_id,
|
||||
CoreInterface core_interface,
|
||||
SemIR::ConstantId query_self_const_id,
|
||||
@@ -198,14 +228,18 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id,
|
||||
return BuildCopyWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
case CoreInterface::Destroy:
|
||||
return BuildDestroyWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
case CoreInterface::CppUnsafeDeref:
|
||||
return BuildCppUnsafeDerefWitness(
|
||||
context, loc_id, query_self_const_id, query_specific_interface_id,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
case CoreInterface::Default:
|
||||
return BuildDefaultWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
case CoreInterface::Destroy:
|
||||
return BuildDestroyWitness(context, loc_id, query_self_const_id,
|
||||
query_specific_interface_id,
|
||||
best_impl_type_structure, best_impl_loc_id);
|
||||
|
||||
// IntFitsIn is for Carbon integer types only.
|
||||
case CoreInterface::IntFitsIn:
|
||||
|
||||
Reference in New Issue
Block a user