|
@@ -165,7 +165,7 @@ static auto ConvertAggregateElement(
|
|
|
ConversionTarget::Kind kind, SemIR::InstId target_id,
|
|
ConversionTarget::Kind kind, SemIR::InstId target_id,
|
|
|
SemIR::TypeInstId target_elem_type_inst, PendingBlock* target_block,
|
|
SemIR::TypeInstId target_elem_type_inst, PendingBlock* target_block,
|
|
|
size_t src_field_index, size_t target_field_index,
|
|
size_t src_field_index, size_t target_field_index,
|
|
|
- SemIR::InstId vtable_ptr_inst_id = SemIR::InstId::None) -> SemIR::InstId {
|
|
|
|
|
|
|
+ SemIR::ClassType* vtable_class_type = nullptr) -> SemIR::InstId {
|
|
|
auto src_elem_type =
|
|
auto src_elem_type =
|
|
|
context.types().GetTypeIdForTypeInstId(src_elem_type_inst);
|
|
context.types().GetTypeIdForTypeInstId(src_elem_type_inst);
|
|
|
auto target_elem_type =
|
|
auto target_elem_type =
|
|
@@ -193,7 +193,7 @@ static auto ConvertAggregateElement(
|
|
|
target.init_id = MakeElementAccessInst<TargetAccessInstT>(
|
|
target.init_id = MakeElementAccessInst<TargetAccessInstT>(
|
|
|
context, loc_id, target_id, target_elem_type, *target_block,
|
|
context, loc_id, target_id, target_elem_type, *target_block,
|
|
|
target_field_index);
|
|
target_field_index);
|
|
|
- return Convert(context, loc_id, src_elem_id, target, vtable_ptr_inst_id);
|
|
|
|
|
|
|
+ return Convert(context, loc_id, src_elem_id, target, vtable_class_type);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Performs a conversion from a tuple to an array type. This function only
|
|
// Performs a conversion from a tuple to an array type. This function only
|
|
@@ -390,7 +390,7 @@ template <typename TargetAccessInstT>
|
|
|
static auto ConvertStructToStructOrClass(
|
|
static auto ConvertStructToStructOrClass(
|
|
|
Context& context, SemIR::StructType src_type, SemIR::StructType dest_type,
|
|
Context& context, SemIR::StructType src_type, SemIR::StructType dest_type,
|
|
|
SemIR::InstId value_id, ConversionTarget target,
|
|
SemIR::InstId value_id, ConversionTarget target,
|
|
|
- SemIR::InstId vtable_ptr_inst_id = SemIR::InstId::None) -> SemIR::InstId {
|
|
|
|
|
|
|
+ SemIR::ClassType* vtable_class_type = nullptr) -> SemIR::InstId {
|
|
|
static_assert(std::is_same_v<SemIR::ClassElementAccess, TargetAccessInstT> ||
|
|
static_assert(std::is_same_v<SemIR::ClassElementAccess, TargetAccessInstT> ||
|
|
|
std::is_same_v<SemIR::StructAccess, TargetAccessInstT>);
|
|
std::is_same_v<SemIR::StructAccess, TargetAccessInstT>);
|
|
|
constexpr bool ToClass =
|
|
constexpr bool ToClass =
|
|
@@ -480,11 +480,22 @@ static auto ConvertStructToStructOrClass(
|
|
|
{.type_id = vptr_type_id,
|
|
{.type_id = vptr_type_id,
|
|
|
.base_id = target.init_id,
|
|
.base_id = target.init_id,
|
|
|
.index = SemIR::ElementIndex(i)});
|
|
.index = SemIR::ElementIndex(i)});
|
|
|
- auto init_id =
|
|
|
|
|
- AddInst<SemIR::InitializeFrom>(context, value_loc_id,
|
|
|
|
|
- {.type_id = vptr_type_id,
|
|
|
|
|
- .src_id = vtable_ptr_inst_id,
|
|
|
|
|
- .dest_id = dest_id});
|
|
|
|
|
|
|
+ auto vtable_decl_id =
|
|
|
|
|
+ context.classes().Get(vtable_class_type->class_id).vtable_decl_id;
|
|
|
|
|
+ LoadImportRef(context, vtable_decl_id);
|
|
|
|
|
+ auto canonical_vtable_decl_id =
|
|
|
|
|
+ context.constant_values().GetConstantInstId(vtable_decl_id);
|
|
|
|
|
+ auto vtable_ptr_id = AddInst<SemIR::VtablePtr>(
|
|
|
|
|
+ context, value_loc_id,
|
|
|
|
|
+ {.type_id = GetPointerType(context, SemIR::VtableType::TypeInstId),
|
|
|
|
|
+ .vtable_id = context.insts()
|
|
|
|
|
+ .GetAs<SemIR::VtableDecl>(canonical_vtable_decl_id)
|
|
|
|
|
+ .vtable_id,
|
|
|
|
|
+ .specific_id = vtable_class_type->specific_id});
|
|
|
|
|
+ auto init_id = AddInst<SemIR::InitializeFrom>(context, value_loc_id,
|
|
|
|
|
+ {.type_id = vptr_type_id,
|
|
|
|
|
+ .src_id = vtable_ptr_id,
|
|
|
|
|
+ .dest_id = dest_id});
|
|
|
new_block.Set(i, init_id);
|
|
new_block.Set(i, init_id);
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
@@ -526,7 +537,7 @@ static auto ConvertStructToStructOrClass(
|
|
|
context, value_loc_id, value_id, src_field.type_inst_id,
|
|
context, value_loc_id, value_id, src_field.type_inst_id,
|
|
|
literal_elems, inner_kind, target.init_id, dest_field.type_inst_id,
|
|
literal_elems, inner_kind, target.init_id, dest_field.type_inst_id,
|
|
|
target.init_block, src_field_index,
|
|
target.init_block, src_field_index,
|
|
|
- src_field_index + dest_vptr_offset, vtable_ptr_inst_id);
|
|
|
|
|
|
|
+ src_field_index + dest_vptr_offset, vtable_class_type);
|
|
|
if (init_id == SemIR::ErrorInst::InstId) {
|
|
if (init_id == SemIR::ErrorInst::InstId) {
|
|
|
return SemIR::ErrorInst::InstId;
|
|
return SemIR::ErrorInst::InstId;
|
|
|
}
|
|
}
|
|
@@ -568,10 +579,11 @@ static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type,
|
|
|
// Performs a conversion from a struct to a class type. This function only
|
|
// Performs a conversion from a struct to a class type. This function only
|
|
|
// converts the type, and does not perform a final conversion to the requested
|
|
// converts the type, and does not perform a final conversion to the requested
|
|
|
// expression category.
|
|
// expression category.
|
|
|
-static auto ConvertStructToClass(
|
|
|
|
|
- Context& context, SemIR::StructType src_type, SemIR::ClassType dest_type,
|
|
|
|
|
- SemIR::InstId value_id, ConversionTarget target,
|
|
|
|
|
- SemIR::InstId dest_vtable_ptr_inst_id = SemIR::InstId::None)
|
|
|
|
|
|
|
+static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
|
|
|
|
|
+ SemIR::ClassType dest_type,
|
|
|
|
|
+ SemIR::InstId value_id,
|
|
|
|
|
+ ConversionTarget target,
|
|
|
|
|
+ SemIR::ClassType* vtable_class_type)
|
|
|
-> SemIR::InstId {
|
|
-> SemIR::InstId {
|
|
|
PendingBlock target_block(&context);
|
|
PendingBlock target_block(&context);
|
|
|
auto& dest_class_info = context.classes().Get(dest_type.class_id);
|
|
auto& dest_class_info = context.classes().Get(dest_type.class_id);
|
|
@@ -598,24 +610,9 @@ static auto ConvertStructToClass(
|
|
|
SemIR::LocId(value_id), {.type_id = target.type_id});
|
|
SemIR::LocId(value_id), {.type_id = target.type_id});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!dest_vtable_ptr_inst_id.has_value()) {
|
|
|
|
|
- dest_vtable_ptr_inst_id = dest_class_info.vtable_ptr_id;
|
|
|
|
|
- if (dest_type.specific_id.has_value() &&
|
|
|
|
|
- dest_vtable_ptr_inst_id.has_value()) {
|
|
|
|
|
- LoadImportRef(context, dest_vtable_ptr_inst_id);
|
|
|
|
|
- dest_vtable_ptr_inst_id = context.constant_values().GetInstId(
|
|
|
|
|
- GetConstantValueInSpecific(context.sem_ir(), dest_type.specific_id,
|
|
|
|
|
- dest_vtable_ptr_inst_id));
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (dest_vtable_ptr_inst_id.has_value()) {
|
|
|
|
|
- LoadImportRef(context, dest_vtable_ptr_inst_id);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
auto result_id = ConvertStructToStructOrClass<SemIR::ClassElementAccess>(
|
|
auto result_id = ConvertStructToStructOrClass<SemIR::ClassElementAccess>(
|
|
|
context, src_type, dest_struct_type, value_id, target,
|
|
context, src_type, dest_struct_type, value_id, target,
|
|
|
- dest_vtable_ptr_inst_id);
|
|
|
|
|
|
|
+ vtable_class_type ? vtable_class_type : &dest_type);
|
|
|
|
|
|
|
|
if (need_temporary) {
|
|
if (need_temporary) {
|
|
|
target_block.InsertHere();
|
|
target_block.InsertHere();
|
|
@@ -799,8 +796,8 @@ static auto DiagnoseConversionFailureToConstraintValue(
|
|
|
|
|
|
|
|
static auto PerformBuiltinConversion(
|
|
static auto PerformBuiltinConversion(
|
|
|
Context& context, SemIR::LocId loc_id, SemIR::InstId value_id,
|
|
Context& context, SemIR::LocId loc_id, SemIR::InstId value_id,
|
|
|
- ConversionTarget target,
|
|
|
|
|
- SemIR::InstId vtable_ptr_inst_id = SemIR::InstId::None) -> SemIR::InstId {
|
|
|
|
|
|
|
+ ConversionTarget target, SemIR::ClassType* vtable_class_type = nullptr)
|
|
|
|
|
+ -> SemIR::InstId {
|
|
|
auto& sem_ir = context.sem_ir();
|
|
auto& sem_ir = context.sem_ir();
|
|
|
auto value = sem_ir.insts().Get(value_id);
|
|
auto value = sem_ir.insts().Get(value_id);
|
|
|
auto value_type_id = value.type_id();
|
|
auto value_type_id = value.type_id();
|
|
@@ -974,7 +971,7 @@ static auto PerformBuiltinConversion(
|
|
|
.adapt_id.has_value()) {
|
|
.adapt_id.has_value()) {
|
|
|
return ConvertStructToClass(context, *src_struct_type,
|
|
return ConvertStructToClass(context, *src_struct_type,
|
|
|
*target_class_type, value_id, target,
|
|
*target_class_type, value_id, target,
|
|
|
- vtable_ptr_inst_id);
|
|
|
|
|
|
|
+ vtable_class_type);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1201,7 +1198,7 @@ auto PerformAction(Context& context, SemIR::LocId loc_id,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
|
- ConversionTarget target, SemIR::InstId vtable_ptr_inst_id)
|
|
|
|
|
|
|
+ ConversionTarget target, SemIR::ClassType* vtable_class_type)
|
|
|
-> SemIR::InstId {
|
|
-> SemIR::InstId {
|
|
|
auto& sem_ir = context.sem_ir();
|
|
auto& sem_ir = context.sem_ir();
|
|
|
auto orig_expr_id = expr_id;
|
|
auto orig_expr_id = expr_id;
|
|
@@ -1266,7 +1263,7 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
|
|
|
|
|
|
// Check whether any builtin conversion applies.
|
|
// Check whether any builtin conversion applies.
|
|
|
expr_id = PerformBuiltinConversion(context, loc_id, expr_id, target,
|
|
expr_id = PerformBuiltinConversion(context, loc_id, expr_id, target,
|
|
|
- vtable_ptr_inst_id);
|
|
|
|
|
|
|
+ vtable_class_type);
|
|
|
if (expr_id == SemIR::ErrorInst::InstId) {
|
|
if (expr_id == SemIR::ErrorInst::InstId) {
|
|
|
return expr_id;
|
|
return expr_id;
|
|
|
}
|
|
}
|