|
|
@@ -100,9 +100,10 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id,
|
|
|
<< "initialized multiple times? Have "
|
|
|
<< sem_ir.insts().Get(return_slot_id);
|
|
|
auto init = sem_ir.insts().Get(init_id);
|
|
|
- return context.AddInst(
|
|
|
- {sem_ir.insts().GetLocId(init_id),
|
|
|
- SemIR::Temporary{init.type_id(), return_slot_id, init_id}});
|
|
|
+ return context.AddInst<SemIR::Temporary>(sem_ir.insts().GetLocId(init_id),
|
|
|
+ {.type_id = init.type_id(),
|
|
|
+ .storage_id = return_slot_id,
|
|
|
+ .init_id = init_id});
|
|
|
}
|
|
|
|
|
|
if (discarded) {
|
|
|
@@ -117,10 +118,11 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id,
|
|
|
// instructions.
|
|
|
auto init = sem_ir.insts().Get(init_id);
|
|
|
auto loc_id = sem_ir.insts().GetLocId(init_id);
|
|
|
- auto temporary_id =
|
|
|
- context.AddInst({loc_id, SemIR::TemporaryStorage{init.type_id()}});
|
|
|
- return context.AddInst(
|
|
|
- {loc_id, SemIR::Temporary{init.type_id(), temporary_id, init_id}});
|
|
|
+ auto temporary_id = context.AddInst<SemIR::TemporaryStorage>(
|
|
|
+ loc_id, {.type_id = init.type_id()});
|
|
|
+ return context.AddInst<SemIR::Temporary>(loc_id, {.type_id = init.type_id(),
|
|
|
+ .storage_id = temporary_id,
|
|
|
+ .init_id = init_id});
|
|
|
}
|
|
|
|
|
|
// Materialize a temporary to hold the result of the given expression if it is
|
|
|
@@ -144,15 +146,14 @@ static auto MakeElementAccessInst(Context& context, SemIR::LocId loc_id,
|
|
|
// TODO: Add a new instruction kind for indexing an array at a constant
|
|
|
// index so that we don't need an integer literal instruction here, and
|
|
|
// remove this special case.
|
|
|
- auto index_id = block.AddInst(
|
|
|
- {loc_id,
|
|
|
- SemIR::IntLiteral{context.GetBuiltinType(SemIR::BuiltinKind::IntType),
|
|
|
- context.ints().Add(llvm::APInt(32, i))}});
|
|
|
- return block.AddInst(
|
|
|
- {loc_id, AccessInstT{elem_type_id, aggregate_id, index_id}});
|
|
|
+ auto index_id = block.template AddInst<SemIR::IntLiteral>(
|
|
|
+ loc_id, {.type_id = context.GetBuiltinType(SemIR::BuiltinKind::IntType),
|
|
|
+ .int_id = context.ints().Add(llvm::APInt(32, i))});
|
|
|
+ return block.template AddInst<AccessInstT>(
|
|
|
+ loc_id, {elem_type_id, aggregate_id, index_id});
|
|
|
} else {
|
|
|
- return block.AddInst({loc_id, AccessInstT{elem_type_id, aggregate_id,
|
|
|
- SemIR::ElementIndex(i)}});
|
|
|
+ return block.template AddInst<AccessInstT>(
|
|
|
+ loc_id, {elem_type_id, aggregate_id, SemIR::ElementIndex(i)});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -250,8 +251,8 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
|
|
|
// destination for the array initialization if we weren't given one.
|
|
|
SemIR::InstId return_slot_id = target.init_id;
|
|
|
if (!target.init_id.is_valid()) {
|
|
|
- return_slot_id = target_block->AddInst(
|
|
|
- {value_loc_id, SemIR::TemporaryStorage{target.type_id}});
|
|
|
+ return_slot_id = target_block->AddInst<SemIR::TemporaryStorage>(
|
|
|
+ value_loc_id, {.type_id = target.type_id});
|
|
|
}
|
|
|
|
|
|
// Initialize each element of the array from the corresponding element of the
|
|
|
@@ -277,10 +278,10 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
|
|
|
// Flush the temporary here if we didn't insert it earlier, so we can add a
|
|
|
// reference to the return slot.
|
|
|
target_block->InsertHere();
|
|
|
- return context.AddInst(
|
|
|
- {value_loc_id,
|
|
|
- SemIR::ArrayInit{target.type_id, sem_ir.inst_blocks().Add(inits),
|
|
|
- return_slot_id}});
|
|
|
+ return context.AddInst<SemIR::ArrayInit>(
|
|
|
+ value_loc_id, {.type_id = target.type_id,
|
|
|
+ .inits_id = sem_ir.inst_blocks().Add(inits),
|
|
|
+ .dest_id = return_slot_id});
|
|
|
}
|
|
|
|
|
|
// Performs a conversion from a tuple to a tuple type. This function only
|
|
|
@@ -357,12 +358,14 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
|
|
|
|
|
|
if (is_init) {
|
|
|
target.init_block->InsertHere();
|
|
|
- return context.AddInst(
|
|
|
- {value_loc_id,
|
|
|
- SemIR::TupleInit{target.type_id, new_block.id(), target.init_id}});
|
|
|
+ return context.AddInst<SemIR::TupleInit>(value_loc_id,
|
|
|
+ {.type_id = target.type_id,
|
|
|
+ .elements_id = new_block.id(),
|
|
|
+ .dest_id = target.init_id});
|
|
|
} else {
|
|
|
- return context.AddInst(
|
|
|
- {value_loc_id, SemIR::TupleValue{target.type_id, new_block.id()}});
|
|
|
+ return context.AddInst<SemIR::TupleValue>(
|
|
|
+ value_loc_id,
|
|
|
+ {.type_id = target.type_id, .elements_id = new_block.id()});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -488,17 +491,20 @@ static auto ConvertStructToStructOrClass(Context& context,
|
|
|
target.init_block->InsertHere();
|
|
|
CARBON_CHECK(is_init)
|
|
|
<< "Converting directly to a class value is not supported";
|
|
|
- return context.AddInst(
|
|
|
- {value_loc_id,
|
|
|
- SemIR::ClassInit{target.type_id, new_block.id(), target.init_id}});
|
|
|
+ return context.AddInst<SemIR::ClassInit>(value_loc_id,
|
|
|
+ {.type_id = target.type_id,
|
|
|
+ .elements_id = new_block.id(),
|
|
|
+ .dest_id = target.init_id});
|
|
|
} else if (is_init) {
|
|
|
target.init_block->InsertHere();
|
|
|
- return context.AddInst(
|
|
|
- {value_loc_id,
|
|
|
- SemIR::StructInit{target.type_id, new_block.id(), target.init_id}});
|
|
|
+ return context.AddInst<SemIR::StructInit>(value_loc_id,
|
|
|
+ {.type_id = target.type_id,
|
|
|
+ .elements_id = new_block.id(),
|
|
|
+ .dest_id = target.init_id});
|
|
|
} else {
|
|
|
- return context.AddInst(
|
|
|
- {value_loc_id, SemIR::StructValue{target.type_id, new_block.id()}});
|
|
|
+ return context.AddInst<SemIR::StructValue>(
|
|
|
+ value_loc_id,
|
|
|
+ {.type_id = target.type_id, .elements_id = new_block.id()});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -543,9 +549,8 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
|
|
|
if (need_temporary) {
|
|
|
target.kind = ConversionTarget::Initializer;
|
|
|
target.init_block = &target_block;
|
|
|
- target.init_id =
|
|
|
- target_block.AddInst({context.insts().GetLocId(value_id),
|
|
|
- SemIR::TemporaryStorage{target.type_id}});
|
|
|
+ target.init_id = target_block.AddInst<SemIR::TemporaryStorage>(
|
|
|
+ context.insts().GetLocId(value_id), {.type_id = target.type_id});
|
|
|
}
|
|
|
|
|
|
auto result_id = ConvertStructToStructOrClass<SemIR::ClassElementAccess>(
|
|
|
@@ -553,9 +558,10 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
|
|
|
|
|
|
if (need_temporary) {
|
|
|
target_block.InsertHere();
|
|
|
- result_id = context.AddInst(
|
|
|
- {context.insts().GetLocId(value_id),
|
|
|
- SemIR::Temporary{target.type_id, target.init_id, result_id}});
|
|
|
+ result_id = context.AddInst<SemIR::Temporary>(
|
|
|
+ context.insts().GetLocId(value_id), {.type_id = target.type_id,
|
|
|
+ .storage_id = target.init_id,
|
|
|
+ .init_id = result_id});
|
|
|
}
|
|
|
return result_id;
|
|
|
}
|
|
|
@@ -610,9 +616,10 @@ static auto ConvertDerivedToBase(Context& context, SemIR::LocId loc_id,
|
|
|
// Add a series of `.base` accesses.
|
|
|
for (auto base_id : path) {
|
|
|
auto base_decl = context.insts().GetAs<SemIR::BaseDecl>(base_id);
|
|
|
- value_id = context.AddInst(
|
|
|
- {loc_id, SemIR::ClassElementAccess{base_decl.base_type_id, value_id,
|
|
|
- base_decl.index}});
|
|
|
+ value_id = context.AddInst<SemIR::ClassElementAccess>(
|
|
|
+ loc_id, {.type_id = base_decl.base_type_id,
|
|
|
+ .base_id = value_id,
|
|
|
+ .index = base_decl.index});
|
|
|
}
|
|
|
return value_id;
|
|
|
}
|
|
|
@@ -624,14 +631,15 @@ static auto ConvertDerivedPointerToBasePointer(
|
|
|
const InheritancePath& path) -> SemIR::InstId {
|
|
|
// Form `*p`.
|
|
|
ptr_id = ConvertToValueExpr(context, ptr_id);
|
|
|
- auto ref_id =
|
|
|
- context.AddInst({loc_id, SemIR::Deref{src_ptr_type.pointee_id, ptr_id}});
|
|
|
+ auto ref_id = context.AddInst<SemIR::Deref>(
|
|
|
+ loc_id, {.type_id = src_ptr_type.pointee_id, .pointer_id = ptr_id});
|
|
|
|
|
|
// Convert as a reference expression.
|
|
|
ref_id = ConvertDerivedToBase(context, loc_id, ref_id, path);
|
|
|
|
|
|
// Take the address.
|
|
|
- return context.AddInst({loc_id, SemIR::AddrOf{dest_ptr_type_id, ref_id}});
|
|
|
+ return context.AddInst<SemIR::AddrOf>(
|
|
|
+ loc_id, {.type_id = dest_ptr_type_id, .lvalue_id = ref_id});
|
|
|
}
|
|
|
|
|
|
// Returns whether `category` is a valid expression category to produce as a
|
|
|
@@ -729,8 +737,8 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
|
|
|
// The initializer produces an object representation by copy, and the
|
|
|
// value representation is a copy of the object representation, so we
|
|
|
// already have a value of the right form.
|
|
|
- return context.AddInst(
|
|
|
- {loc_id, SemIR::ValueOfInitializer{value_type_id, value_id}});
|
|
|
+ return context.AddInst<SemIR::ValueOfInitializer>(
|
|
|
+ loc_id, {.type_id = value_type_id, .init_id = value_id});
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -750,8 +758,8 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
|
|
|
ConversionTarget{.kind = ConversionTarget::Value,
|
|
|
.type_id = value_type_id});
|
|
|
}
|
|
|
- return context.AddInst(
|
|
|
- {loc_id, SemIR::AsCompatible{target.type_id, value_id}});
|
|
|
+ return context.AddInst<SemIR::AsCompatible>(
|
|
|
+ loc_id, {.type_id = target.type_id, .source_id = value_id});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -856,8 +864,8 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
|
|
|
// TODO: Support converting tuple and struct values to facet types,
|
|
|
// combining the above conversions and this one in a single conversion.
|
|
|
if (sem_ir.types().Is<SemIR::InterfaceType>(value_type_id)) {
|
|
|
- return context.AddInst(
|
|
|
- {loc_id, SemIR::FacetTypeAccess{target.type_id, value_id}});
|
|
|
+ return context.AddInst<SemIR::FacetTypeAccess>(
|
|
|
+ loc_id, {.type_id = target.type_id, .facet_id = value_id});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -967,8 +975,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
|
|
|
|
// Track that we performed a type conversion, if we did so.
|
|
|
if (orig_expr_id != expr_id) {
|
|
|
- expr_id = context.AddInst(
|
|
|
- {loc_id, SemIR::Converted{target.type_id, orig_expr_id, expr_id}});
|
|
|
+ expr_id =
|
|
|
+ context.AddInst<SemIR::Converted>(loc_id, {.type_id = target.type_id,
|
|
|
+ .original_id = orig_expr_id,
|
|
|
+ .result_id = expr_id});
|
|
|
}
|
|
|
|
|
|
// For `as`, don't perform any value category conversions. In particular, an
|
|
|
@@ -1018,8 +1028,9 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
|
|
|
|
// If we have a reference and don't want one, form a value binding.
|
|
|
// TODO: Support types with custom value representations.
|
|
|
- expr_id = context.AddInst({context.insts().GetLocId(expr_id),
|
|
|
- SemIR::BindValue{expr.type_id(), expr_id}});
|
|
|
+ expr_id = context.AddInst<SemIR::BindValue>(
|
|
|
+ context.insts().GetLocId(expr_id),
|
|
|
+ {.type_id = expr.type_id(), .value_id = expr_id});
|
|
|
// We now have a value expression.
|
|
|
[[fallthrough]];
|
|
|
|
|
|
@@ -1036,9 +1047,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
|
|
|
if (auto init_rep = SemIR::GetInitRepr(sem_ir, target.type_id);
|
|
|
init_rep.kind == SemIR::InitRepr::ByCopy) {
|
|
|
target.init_block->InsertHere();
|
|
|
- expr_id = context.AddInst(
|
|
|
- {loc_id,
|
|
|
- SemIR::InitializeFrom{target.type_id, expr_id, target.init_id}});
|
|
|
+ expr_id = context.AddInst<SemIR::InitializeFrom>(
|
|
|
+ loc_id, {.type_id = target.type_id,
|
|
|
+ .src_id = expr_id,
|
|
|
+ .dest_id = target.init_id});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1143,9 +1155,9 @@ static auto ConvertSelf(Context& context, SemIR::LocId call_loc_id,
|
|
|
return SemIR::InstId::BuiltinError;
|
|
|
}
|
|
|
auto loc_id = context.insts().GetLocId(self_or_addr_id);
|
|
|
- self_or_addr_id = context.AddInst(
|
|
|
- {loc_id, SemIR::AddrOf{context.GetPointerType(self.type_id()),
|
|
|
- self_or_addr_id}});
|
|
|
+ self_or_addr_id = context.AddInst<SemIR::AddrOf>(
|
|
|
+ loc_id, {.type_id = context.GetPointerType(self.type_id()),
|
|
|
+ .lvalue_id = self_or_addr_id});
|
|
|
}
|
|
|
|
|
|
return ConvertToValueOfType(context, call_loc_id, self_or_addr_id,
|