mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:31:24 +01:00
Abbreviate "representation" -> "repr" (#3464)
Specifically using these abbreviations: * InitRepr: "initializing representation" * ObjectRepr: "object representation" * ValueRepr: "value representation" As discussed in [#toolchain discord](https://discord.com/channels/655572317891461132/655578254970716160/1182086098470572143) and now documented in the [list of abbreviations](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).
This commit is contained in:
+65
-78
@@ -516,7 +516,7 @@ namespace {
|
||||
//
|
||||
// - An `AddNestedIncompleteTypes` step adds a task for all incomplete types
|
||||
// nested within a type to the work list.
|
||||
// - A `BuildValueRepresentation` step computes the value representation for a
|
||||
// - A `BuildValueRepr` step computes the value representation for a
|
||||
// type, once all of its nested types are complete, and marks the type as
|
||||
// complete.
|
||||
class TypeCompleter {
|
||||
@@ -570,31 +570,28 @@ class TypeCompleter {
|
||||
}
|
||||
CARBON_CHECK(work_list_.size() >= old_work_list_size)
|
||||
<< "AddNestedIncompleteTypes should not remove work items";
|
||||
work_list_[old_work_list_size - 1].phase =
|
||||
Phase::BuildValueRepresentation;
|
||||
work_list_[old_work_list_size - 1].phase = Phase::BuildValueRepr;
|
||||
break;
|
||||
|
||||
case Phase::BuildValueRepresentation: {
|
||||
auto value_rep = BuildValueRepresentation(type_id, inst);
|
||||
case Phase::BuildValueRepr: {
|
||||
auto value_rep = BuildValueRepr(type_id, inst);
|
||||
context_.sem_ir().CompleteType(type_id, value_rep);
|
||||
CARBON_CHECK(old_work_list_size == work_list_.size())
|
||||
<< "BuildValueRepresentation should not change work items";
|
||||
<< "BuildValueRepr should not change work items";
|
||||
work_list_.pop_back();
|
||||
|
||||
// Also complete the value representation type, if necessary. This
|
||||
// should never fail: the value representation shouldn't require any
|
||||
// additional nested types to be complete.
|
||||
if (!context_.sem_ir().IsTypeComplete(value_rep.type_id)) {
|
||||
work_list_.push_back(
|
||||
{value_rep.type_id, Phase::BuildValueRepresentation});
|
||||
work_list_.push_back({value_rep.type_id, Phase::BuildValueRepr});
|
||||
}
|
||||
// For a pointer representation, the pointee also needs to be complete.
|
||||
if (value_rep.kind == SemIR::ValueRepresentation::Pointer) {
|
||||
if (value_rep.kind == SemIR::ValueRepr::Pointer) {
|
||||
auto pointee_type_id =
|
||||
context_.sem_ir().GetPointeeType(value_rep.type_id);
|
||||
if (!context_.sem_ir().IsTypeComplete(pointee_type_id)) {
|
||||
work_list_.push_back(
|
||||
{pointee_type_id, Phase::BuildValueRepresentation});
|
||||
work_list_.push_back({pointee_type_id, Phase::BuildValueRepr});
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -639,7 +636,7 @@ class TypeCompleter {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Push(class_info.object_representation_id);
|
||||
Push(class_info.object_repr_id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -656,51 +653,47 @@ class TypeCompleter {
|
||||
|
||||
// Makes an empty value representation, which is used for types that have no
|
||||
// state, such as empty structs and tuples.
|
||||
auto MakeEmptyRepresentation(Parse::NodeId parse_node) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
return {.kind = SemIR::ValueRepresentation::None,
|
||||
auto MakeEmptyValueRepr(Parse::NodeId parse_node) const -> SemIR::ValueRepr {
|
||||
return {.kind = SemIR::ValueRepr::None,
|
||||
.type_id = context_.CanonicalizeTupleType(parse_node, {})};
|
||||
}
|
||||
|
||||
// Makes a value representation that uses pass-by-copy, copying the given
|
||||
// type.
|
||||
auto MakeCopyRepresentation(
|
||||
SemIR::TypeId rep_id,
|
||||
SemIR::ValueRepresentation::AggregateKind aggregate_kind =
|
||||
SemIR::ValueRepresentation::NotAggregate) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
return {.kind = SemIR::ValueRepresentation::Copy,
|
||||
auto MakeCopyValueRepr(SemIR::TypeId rep_id,
|
||||
SemIR::ValueRepr::AggregateKind aggregate_kind =
|
||||
SemIR::ValueRepr::NotAggregate) const
|
||||
-> SemIR::ValueRepr {
|
||||
return {.kind = SemIR::ValueRepr::Copy,
|
||||
.aggregate_kind = aggregate_kind,
|
||||
.type_id = rep_id};
|
||||
}
|
||||
|
||||
// Makes a value representation that uses pass-by-address with the given
|
||||
// pointee type.
|
||||
auto MakePointerRepresentation(
|
||||
Parse::NodeId parse_node, SemIR::TypeId pointee_id,
|
||||
SemIR::ValueRepresentation::AggregateKind aggregate_kind =
|
||||
SemIR::ValueRepresentation::NotAggregate) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
auto MakePointerValueRepr(Parse::NodeId parse_node, SemIR::TypeId pointee_id,
|
||||
SemIR::ValueRepr::AggregateKind aggregate_kind =
|
||||
SemIR::ValueRepr::NotAggregate) const
|
||||
-> SemIR::ValueRepr {
|
||||
// TODO: Should we add `const` qualification to `pointee_id`?
|
||||
return {.kind = SemIR::ValueRepresentation::Pointer,
|
||||
return {.kind = SemIR::ValueRepr::Pointer,
|
||||
.aggregate_kind = aggregate_kind,
|
||||
.type_id = context_.GetPointerType(parse_node, pointee_id)};
|
||||
}
|
||||
|
||||
// Gets the value representation of a nested type, which should already be
|
||||
// complete.
|
||||
auto GetNestedValueRepresentation(SemIR::TypeId nested_type_id) const {
|
||||
auto GetNestedValueRepr(SemIR::TypeId nested_type_id) const {
|
||||
CARBON_CHECK(context_.sem_ir().IsTypeComplete(nested_type_id))
|
||||
<< "Nested type should already be complete";
|
||||
auto value_rep = context_.sem_ir().GetValueRepresentation(nested_type_id);
|
||||
CARBON_CHECK(value_rep.kind != SemIR::ValueRepresentation::Unknown)
|
||||
auto value_rep = context_.sem_ir().GetValueRepr(nested_type_id);
|
||||
CARBON_CHECK(value_rep.kind != SemIR::ValueRepr::Unknown)
|
||||
<< "Complete type should have a value representation";
|
||||
return value_rep;
|
||||
};
|
||||
|
||||
auto BuildCrossRefValueRepresentation(SemIR::TypeId type_id,
|
||||
SemIR::CrossRef xref) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
auto BuildCrossRefValueRepr(SemIR::TypeId type_id, SemIR::CrossRef xref) const
|
||||
-> SemIR::ValueRepr {
|
||||
auto xref_inst =
|
||||
context_.cross_ref_irs().Get(xref.ir_id)->insts().Get(xref.inst_id);
|
||||
|
||||
@@ -723,25 +716,25 @@ class TypeCompleter {
|
||||
case SemIR::BuiltinKind::NamespaceType:
|
||||
case SemIR::BuiltinKind::FunctionType:
|
||||
case SemIR::BuiltinKind::BoundMethodType:
|
||||
return MakeCopyRepresentation(type_id);
|
||||
return MakeCopyValueRepr(type_id);
|
||||
|
||||
case SemIR::BuiltinKind::StringType:
|
||||
// TODO: Decide on string value semantics. This should probably be a
|
||||
// custom value representation carrying a pointer and size or
|
||||
// similar.
|
||||
return MakePointerRepresentation(Parse::NodeId::Invalid, type_id);
|
||||
return MakePointerValueRepr(Parse::NodeId::Invalid, type_id);
|
||||
}
|
||||
llvm_unreachable("All builtin kinds were handled above");
|
||||
}
|
||||
|
||||
auto BuildStructOrTupleValueRepresentation(Parse::NodeId parse_node,
|
||||
std::size_t num_elements,
|
||||
SemIR::TypeId elementwise_rep,
|
||||
bool same_as_object_rep) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
SemIR::ValueRepresentation::AggregateKind aggregate_kind =
|
||||
same_as_object_rep ? SemIR::ValueRepresentation::ValueAndObjectAggregate
|
||||
: SemIR::ValueRepresentation::ValueAggregate;
|
||||
auto BuildStructOrTupleValueRepr(Parse::NodeId parse_node,
|
||||
std::size_t num_elements,
|
||||
SemIR::TypeId elementwise_rep,
|
||||
bool same_as_object_rep) const
|
||||
-> SemIR::ValueRepr {
|
||||
SemIR::ValueRepr::AggregateKind aggregate_kind =
|
||||
same_as_object_rep ? SemIR::ValueRepr::ValueAndObjectAggregate
|
||||
: SemIR::ValueRepr::ValueAggregate;
|
||||
|
||||
if (num_elements == 1) {
|
||||
// The value representation for a struct or tuple with a single element
|
||||
@@ -749,21 +742,20 @@ class TypeCompleter {
|
||||
// element.
|
||||
// TODO: Consider doing the same whenever `elementwise_rep` is
|
||||
// sufficiently small.
|
||||
return MakeCopyRepresentation(elementwise_rep, aggregate_kind);
|
||||
return MakeCopyValueRepr(elementwise_rep, aggregate_kind);
|
||||
}
|
||||
// For a struct or tuple with multiple fields, we use a pointer
|
||||
// to the elementwise value representation.
|
||||
return MakePointerRepresentation(parse_node, elementwise_rep,
|
||||
aggregate_kind);
|
||||
return MakePointerValueRepr(parse_node, elementwise_rep, aggregate_kind);
|
||||
}
|
||||
|
||||
auto BuildStructTypeValueRepresentation(SemIR::TypeId type_id,
|
||||
SemIR::StructType struct_type) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
auto BuildStructTypeValueRepr(SemIR::TypeId type_id,
|
||||
SemIR::StructType struct_type) const
|
||||
-> SemIR::ValueRepr {
|
||||
// TODO: Share more code with tuples.
|
||||
auto fields = context_.inst_blocks().Get(struct_type.fields_id);
|
||||
if (fields.empty()) {
|
||||
return MakeEmptyRepresentation(struct_type.parse_node);
|
||||
return MakeEmptyValueRepr(struct_type.parse_node);
|
||||
}
|
||||
|
||||
// Find the value representation for each field, and construct a struct
|
||||
@@ -773,7 +765,7 @@ class TypeCompleter {
|
||||
bool same_as_object_rep = true;
|
||||
for (auto field_id : fields) {
|
||||
auto field = context_.insts().GetAs<SemIR::StructTypeField>(field_id);
|
||||
auto field_value_rep = GetNestedValueRepresentation(field.field_type_id);
|
||||
auto field_value_rep = GetNestedValueRepr(field.field_type_id);
|
||||
if (field_value_rep.type_id != field.field_type_id) {
|
||||
same_as_object_rep = false;
|
||||
field.field_type_id = field_value_rep.type_id;
|
||||
@@ -787,17 +779,17 @@ class TypeCompleter {
|
||||
: context_.CanonicalizeStructType(
|
||||
struct_type.parse_node,
|
||||
context_.inst_blocks().Add(value_rep_fields));
|
||||
return BuildStructOrTupleValueRepresentation(
|
||||
struct_type.parse_node, fields.size(), value_rep, same_as_object_rep);
|
||||
return BuildStructOrTupleValueRepr(struct_type.parse_node, fields.size(),
|
||||
value_rep, same_as_object_rep);
|
||||
}
|
||||
|
||||
auto BuildTupleTypeValueRepresentation(SemIR::TypeId type_id,
|
||||
SemIR::TupleType tuple_type) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
auto BuildTupleTypeValueRepr(SemIR::TypeId type_id,
|
||||
SemIR::TupleType tuple_type) const
|
||||
-> SemIR::ValueRepr {
|
||||
// TODO: Share more code with structs.
|
||||
auto elements = context_.type_blocks().Get(tuple_type.elements_id);
|
||||
if (elements.empty()) {
|
||||
return MakeEmptyRepresentation(tuple_type.parse_node);
|
||||
return MakeEmptyValueRepr(tuple_type.parse_node);
|
||||
}
|
||||
|
||||
// Find the value representation for each element, and construct a tuple
|
||||
@@ -806,7 +798,7 @@ class TypeCompleter {
|
||||
value_rep_elements.reserve(elements.size());
|
||||
bool same_as_object_rep = true;
|
||||
for (auto element_type_id : elements) {
|
||||
auto element_value_rep = GetNestedValueRepresentation(element_type_id);
|
||||
auto element_value_rep = GetNestedValueRepr(element_type_id);
|
||||
if (element_value_rep.type_id != element_type_id) {
|
||||
same_as_object_rep = false;
|
||||
}
|
||||
@@ -817,14 +809,14 @@ class TypeCompleter {
|
||||
? type_id
|
||||
: context_.CanonicalizeTupleType(tuple_type.parse_node,
|
||||
value_rep_elements);
|
||||
return BuildStructOrTupleValueRepresentation(
|
||||
tuple_type.parse_node, elements.size(), value_rep, same_as_object_rep);
|
||||
return BuildStructOrTupleValueRepr(tuple_type.parse_node, elements.size(),
|
||||
value_rep, same_as_object_rep);
|
||||
}
|
||||
|
||||
// Builds and returns the value representation for the given type. All nested
|
||||
// types, as found by AddNestedIncompleteTypes, are known to be complete.
|
||||
auto BuildValueRepresentation(SemIR::TypeId type_id, SemIR::Inst inst) const
|
||||
-> SemIR::ValueRepresentation {
|
||||
auto BuildValueRepr(SemIR::TypeId type_id, SemIR::Inst inst) const
|
||||
-> SemIR::ValueRepr {
|
||||
// TODO: This can emit new SemIR instructions. Consider emitting them into a
|
||||
// dedicated file-scope instruction block where possible, or somewhere else
|
||||
// that better reflects the definition of the type, rather than wherever the
|
||||
@@ -887,50 +879,45 @@ class TypeCompleter {
|
||||
CARBON_FATAL() << "Type refers to non-type inst " << inst;
|
||||
|
||||
case SemIR::CrossRef::Kind:
|
||||
return BuildCrossRefValueRepresentation(type_id,
|
||||
inst.As<SemIR::CrossRef>());
|
||||
return BuildCrossRefValueRepr(type_id, inst.As<SemIR::CrossRef>());
|
||||
|
||||
case SemIR::ArrayType::Kind: {
|
||||
// For arrays, it's convenient to always use a pointer representation,
|
||||
// even when the array has zero or one element, in order to support
|
||||
// indexing.
|
||||
return MakePointerRepresentation(
|
||||
inst.parse_node(), type_id,
|
||||
SemIR::ValueRepresentation::ObjectAggregate);
|
||||
return MakePointerValueRepr(inst.parse_node(), type_id,
|
||||
SemIR::ValueRepr::ObjectAggregate);
|
||||
}
|
||||
|
||||
case SemIR::StructType::Kind:
|
||||
return BuildStructTypeValueRepresentation(type_id,
|
||||
inst.As<SemIR::StructType>());
|
||||
return BuildStructTypeValueRepr(type_id, inst.As<SemIR::StructType>());
|
||||
|
||||
case SemIR::TupleType::Kind:
|
||||
return BuildTupleTypeValueRepresentation(type_id,
|
||||
inst.As<SemIR::TupleType>());
|
||||
return BuildTupleTypeValueRepr(type_id, inst.As<SemIR::TupleType>());
|
||||
|
||||
case SemIR::ClassType::Kind:
|
||||
// The value representation for a class is a pointer to the object
|
||||
// representation.
|
||||
// TODO: Support customized value representations for classes.
|
||||
// TODO: Pick a better value representation when possible.
|
||||
return MakePointerRepresentation(
|
||||
return MakePointerValueRepr(
|
||||
inst.parse_node(),
|
||||
context_.classes()
|
||||
.Get(inst.As<SemIR::ClassType>().class_id)
|
||||
.object_representation_id,
|
||||
SemIR::ValueRepresentation::ObjectAggregate);
|
||||
.object_repr_id,
|
||||
SemIR::ValueRepr::ObjectAggregate);
|
||||
|
||||
case SemIR::Builtin::Kind:
|
||||
CARBON_FATAL() << "Builtins should be named as cross-references";
|
||||
|
||||
case SemIR::PointerType::Kind:
|
||||
case SemIR::UnboundElementType::Kind:
|
||||
return MakeCopyRepresentation(type_id);
|
||||
return MakeCopyValueRepr(type_id);
|
||||
|
||||
case SemIR::ConstType::Kind:
|
||||
// The value representation of `const T` is the same as that of `T`.
|
||||
// Objects are not modifiable through their value representations.
|
||||
return GetNestedValueRepresentation(
|
||||
inst.As<SemIR::ConstType>().inner_id);
|
||||
return GetNestedValueRepr(inst.As<SemIR::ConstType>().inner_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,7 +925,7 @@ class TypeCompleter {
|
||||
// The next step is to add nested types to the list of types to complete.
|
||||
AddNestedIncompleteTypes,
|
||||
// The next step is to build the value representation for the type.
|
||||
BuildValueRepresentation,
|
||||
BuildValueRepr,
|
||||
};
|
||||
|
||||
struct WorkItem {
|
||||
|
||||
+15
-18
@@ -48,8 +48,7 @@ static auto FindReturnSlotForInitializer(SemIR::File& sem_ir,
|
||||
|
||||
case SemIR::Call::Kind: {
|
||||
auto call = init.As<SemIR::Call>();
|
||||
if (!SemIR::GetInitializingRepresentation(sem_ir, call.type_id)
|
||||
.has_return_slot()) {
|
||||
if (!SemIR::GetInitRepr(sem_ir, call.type_id).has_return_slot()) {
|
||||
return SemIR::InstId::Invalid;
|
||||
}
|
||||
return sem_ir.inst_blocks().Get(call.args_id).back();
|
||||
@@ -353,8 +352,8 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
|
||||
bool is_init = target.is_initializer();
|
||||
ConversionTarget::Kind inner_kind =
|
||||
!is_init ? ConversionTarget::Value
|
||||
: SemIR::GetInitializingRepresentation(sem_ir, target.type_id).kind ==
|
||||
SemIR::InitializingRepresentation::InPlace
|
||||
: SemIR::GetInitRepr(sem_ir, target.type_id).kind ==
|
||||
SemIR::InitRepr::InPlace
|
||||
? ConversionTarget::FullInitializer
|
||||
: ConversionTarget::Initializer;
|
||||
|
||||
@@ -444,8 +443,8 @@ static auto ConvertStructToStructOrClass(Context& context,
|
||||
bool is_init = target.is_initializer();
|
||||
ConversionTarget::Kind inner_kind =
|
||||
!is_init ? ConversionTarget::Value
|
||||
: SemIR::GetInitializingRepresentation(sem_ir, target.type_id).kind ==
|
||||
SemIR::InitializingRepresentation::InPlace
|
||||
: SemIR::GetInitRepr(sem_ir, target.type_id).kind ==
|
||||
SemIR::InitRepr::InPlace
|
||||
? ConversionTarget::FullInitializer
|
||||
: ConversionTarget::Initializer;
|
||||
|
||||
@@ -548,8 +547,7 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
|
||||
return SemIR::InstId::BuiltinError;
|
||||
}
|
||||
auto dest_struct_type = context.insts().GetAs<SemIR::StructType>(
|
||||
context.sem_ir().GetTypeAllowBuiltinTypes(
|
||||
class_info.object_representation_id));
|
||||
context.sem_ir().GetTypeAllowBuiltinTypes(class_info.object_repr_id));
|
||||
|
||||
// If we're trying to create a class value, form a temporary for the value to
|
||||
// point to.
|
||||
@@ -645,10 +643,10 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
|
||||
if (value_cat == SemIR::ExprCategory::Initializing &&
|
||||
IsValidExprCategoryForConversionTarget(SemIR::ExprCategory::Value,
|
||||
target.kind) &&
|
||||
SemIR::GetInitializingRepresentation(sem_ir, value_type_id).kind ==
|
||||
SemIR::InitializingRepresentation::ByCopy) {
|
||||
auto value_rep = SemIR::GetValueRepresentation(sem_ir, value_type_id);
|
||||
if (value_rep.kind == SemIR::ValueRepresentation::Copy &&
|
||||
SemIR::GetInitRepr(sem_ir, value_type_id).kind ==
|
||||
SemIR::InitRepr::ByCopy) {
|
||||
auto value_rep = SemIR::GetValueRepr(sem_ir, value_type_id);
|
||||
if (value_rep.kind == SemIR::ValueRepr::Copy &&
|
||||
value_rep.type_id == value_type_id) {
|
||||
// The initializer produces an object representation by copy, and the
|
||||
// value representation is a copy of the object representation, so we
|
||||
@@ -747,9 +745,9 @@ static auto PerformCopy(Context& context, SemIR::InstId expr_id)
|
||||
|
||||
// TODO: Directly track on the value representation whether it's a copy of
|
||||
// the object representation.
|
||||
auto value_rep = SemIR::GetValueRepresentation(context.sem_ir(), type_id);
|
||||
if (value_rep.kind == SemIR::ValueRepresentation::Copy &&
|
||||
value_rep.aggregate_kind == SemIR::ValueRepresentation::NotAggregate &&
|
||||
auto value_rep = SemIR::GetValueRepr(context.sem_ir(), type_id);
|
||||
if (value_rep.kind == SemIR::ValueRepr::Copy &&
|
||||
value_rep.aggregate_kind == SemIR::ValueRepr::NotAggregate &&
|
||||
value_rep.type_id == type_id) {
|
||||
// For by-value scalar types, no explicit action is required. Initializing
|
||||
// from a value expression is treated as copying the value.
|
||||
@@ -905,9 +903,8 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
|
||||
|
||||
// Perform a final destination store, if necessary.
|
||||
if (target.kind == ConversionTarget::FullInitializer) {
|
||||
if (auto init_rep =
|
||||
SemIR::GetInitializingRepresentation(sem_ir, target.type_id);
|
||||
init_rep.kind == SemIR::InitializingRepresentation::ByCopy) {
|
||||
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(SemIR::InitializeFrom{
|
||||
parse_node, target.type_id, expr_id, target.init_id});
|
||||
|
||||
@@ -280,7 +280,7 @@ auto HandleClassDefinition(Context& context, Parse::NodeId parse_node) -> bool {
|
||||
|
||||
// The class type is now fully defined.
|
||||
auto& class_info = context.classes().Get(class_id);
|
||||
class_info.object_representation_id =
|
||||
class_info.object_repr_id =
|
||||
context.CanonicalizeStructType(parse_node, fields_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,7 @@ static auto BuildFunctionDecl(Context& context, bool is_definition)
|
||||
context.sem_ir().StringifyType(return_type_id));
|
||||
})) {
|
||||
return_type_id = SemIR::TypeId::Error;
|
||||
} else if (!SemIR::GetInitializingRepresentation(context.sem_ir(),
|
||||
return_type_id)
|
||||
} else if (!SemIR::GetInitRepr(context.sem_ir(), return_type_id)
|
||||
.has_return_slot()) {
|
||||
// The function only has a return slot if it uses in-place initialization.
|
||||
} else {
|
||||
|
||||
@@ -81,12 +81,10 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id)
|
||||
sem_ir().inst_blocks().Get(function.implicit_param_refs_id);
|
||||
auto param_refs = sem_ir().inst_blocks().Get(function.param_refs_id);
|
||||
|
||||
SemIR::InitializingRepresentation return_rep =
|
||||
SemIR::InitRepr return_rep =
|
||||
function.return_type_id.is_valid()
|
||||
? SemIR::GetInitializingRepresentation(sem_ir(),
|
||||
function.return_type_id)
|
||||
: SemIR::InitializingRepresentation{
|
||||
.kind = SemIR::InitializingRepresentation::None};
|
||||
? SemIR::GetInitRepr(sem_ir(), function.return_type_id)
|
||||
: SemIR::InitRepr{.kind = SemIR::InitRepr::None};
|
||||
CARBON_CHECK(return_rep.has_return_slot() == has_return_slot);
|
||||
|
||||
llvm::SmallVector<llvm::Type*> param_types;
|
||||
@@ -106,17 +104,16 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id)
|
||||
for (auto param_ref_id :
|
||||
llvm::concat<const SemIR::InstId>(implicit_param_refs, param_refs)) {
|
||||
auto param_type_id = sem_ir().insts().Get(param_ref_id).type_id();
|
||||
switch (auto value_rep =
|
||||
SemIR::GetValueRepresentation(sem_ir(), param_type_id);
|
||||
switch (auto value_rep = SemIR::GetValueRepr(sem_ir(), param_type_id);
|
||||
value_rep.kind) {
|
||||
case SemIR::ValueRepresentation::Unknown:
|
||||
case SemIR::ValueRepr::Unknown:
|
||||
CARBON_FATAL()
|
||||
<< "Incomplete parameter type lowering function declaration";
|
||||
case SemIR::ValueRepresentation::None:
|
||||
case SemIR::ValueRepr::None:
|
||||
break;
|
||||
case SemIR::ValueRepresentation::Copy:
|
||||
case SemIR::ValueRepresentation::Custom:
|
||||
case SemIR::ValueRepresentation::Pointer:
|
||||
case SemIR::ValueRepr::Copy:
|
||||
case SemIR::ValueRepr::Custom:
|
||||
case SemIR::ValueRepr::Pointer:
|
||||
param_types.push_back(GetType(value_rep.type_id));
|
||||
param_inst_ids.push_back(param_ref_id);
|
||||
break;
|
||||
@@ -125,10 +122,9 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id)
|
||||
|
||||
// If the initializing representation doesn't produce a value, set the return
|
||||
// type to void.
|
||||
llvm::Type* return_type =
|
||||
return_rep.kind == SemIR::InitializingRepresentation::ByCopy
|
||||
? GetType(function.return_type_id)
|
||||
: llvm::Type::getVoidTy(llvm_context());
|
||||
llvm::Type* return_type = return_rep.kind == SemIR::InitRepr::ByCopy
|
||||
? GetType(function.return_type_id)
|
||||
: llvm::Type::getVoidTy(llvm_context());
|
||||
|
||||
std::string mangled_name;
|
||||
if (SemIR::IsEntryPoint(sem_ir(), function_id)) {
|
||||
@@ -199,8 +195,8 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id)
|
||||
for (auto param_ref_id :
|
||||
llvm::concat<const SemIR::InstId>(implicit_param_refs, param_refs)) {
|
||||
auto param_type_id = sem_ir().insts().Get(param_ref_id).type_id();
|
||||
if (SemIR::GetValueRepresentation(sem_ir(), param_type_id).kind ==
|
||||
SemIR::ValueRepresentation::None) {
|
||||
if (SemIR::GetValueRepr(sem_ir(), param_type_id).kind ==
|
||||
SemIR::ValueRepr::None) {
|
||||
function_lowering.SetLocal(
|
||||
param_ref_id, llvm::PoisonValue::get(GetType(param_type_id)));
|
||||
} else {
|
||||
@@ -260,11 +256,10 @@ auto FileContext::BuildType(SemIR::InstId inst_id) -> llvm::Type* {
|
||||
sem_ir_->GetArrayBoundValue(array_type.bound_id));
|
||||
}
|
||||
case SemIR::ClassType::Kind: {
|
||||
auto object_representation_id =
|
||||
sem_ir_->classes()
|
||||
.Get(inst.As<SemIR::ClassType>().class_id)
|
||||
.object_representation_id;
|
||||
return GetType(object_representation_id);
|
||||
auto object_repr_id = sem_ir_->classes()
|
||||
.Get(inst.As<SemIR::ClassType>().class_id)
|
||||
.object_repr_id;
|
||||
return GetType(object_repr_id);
|
||||
}
|
||||
case SemIR::ConstType::Kind:
|
||||
return GetType(inst.As<SemIR::ConstType>().inner_id);
|
||||
|
||||
@@ -80,11 +80,11 @@ auto FunctionContext::CreateSyntheticBlock() -> llvm::BasicBlock* {
|
||||
|
||||
auto FunctionContext::FinishInit(SemIR::TypeId type_id, SemIR::InstId dest_id,
|
||||
SemIR::InstId source_id) -> void {
|
||||
switch (SemIR::GetInitializingRepresentation(sem_ir(), type_id).kind) {
|
||||
case SemIR::InitializingRepresentation::None:
|
||||
case SemIR::InitializingRepresentation::InPlace:
|
||||
switch (SemIR::GetInitRepr(sem_ir(), type_id).kind) {
|
||||
case SemIR::InitRepr::None:
|
||||
case SemIR::InitRepr::InPlace:
|
||||
break;
|
||||
case SemIR::InitializingRepresentation::ByCopy:
|
||||
case SemIR::InitRepr::ByCopy:
|
||||
CopyValue(type_id, source_id, dest_id);
|
||||
break;
|
||||
}
|
||||
@@ -92,16 +92,15 @@ auto FunctionContext::FinishInit(SemIR::TypeId type_id, SemIR::InstId dest_id,
|
||||
|
||||
auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id,
|
||||
SemIR::InstId dest_id) -> void {
|
||||
switch (auto rep = SemIR::GetValueRepresentation(sem_ir(), type_id);
|
||||
rep.kind) {
|
||||
case SemIR::ValueRepresentation::Unknown:
|
||||
switch (auto rep = SemIR::GetValueRepr(sem_ir(), type_id); rep.kind) {
|
||||
case SemIR::ValueRepr::Unknown:
|
||||
CARBON_FATAL() << "Attempt to copy incomplete type";
|
||||
case SemIR::ValueRepresentation::None:
|
||||
case SemIR::ValueRepr::None:
|
||||
break;
|
||||
case SemIR::ValueRepresentation::Copy:
|
||||
case SemIR::ValueRepr::Copy:
|
||||
builder().CreateStore(GetValue(source_id), GetValue(dest_id));
|
||||
break;
|
||||
case SemIR::ValueRepresentation::Pointer: {
|
||||
case SemIR::ValueRepr::Pointer: {
|
||||
const auto& layout = llvm_module().getDataLayout();
|
||||
auto* type = GetType(type_id);
|
||||
// TODO: Compute known alignment of the source and destination, which may
|
||||
@@ -114,7 +113,7 @@ auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id,
|
||||
align, layout.getTypeAllocSize(type));
|
||||
break;
|
||||
}
|
||||
case SemIR::ValueRepresentation::Custom:
|
||||
case SemIR::ValueRepr::Custom:
|
||||
CARBON_FATAL() << "TODO: Add support for CopyValue with custom value rep";
|
||||
}
|
||||
}
|
||||
|
||||
+10
-11
@@ -144,16 +144,15 @@ auto HandleCall(FunctionContext& context, SemIR::InstId inst_id,
|
||||
llvm::ArrayRef<SemIR::InstId> arg_ids =
|
||||
context.sem_ir().inst_blocks().Get(inst.args_id);
|
||||
|
||||
if (SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id)
|
||||
.has_return_slot()) {
|
||||
if (SemIR::GetInitRepr(context.sem_ir(), inst.type_id).has_return_slot()) {
|
||||
args.push_back(context.GetValue(arg_ids.back()));
|
||||
arg_ids = arg_ids.drop_back();
|
||||
}
|
||||
|
||||
for (auto arg_id : arg_ids) {
|
||||
auto arg_type_id = context.sem_ir().insts().Get(arg_id).type_id();
|
||||
if (SemIR::GetValueRepresentation(context.sem_ir(), arg_type_id).kind !=
|
||||
SemIR::ValueRepresentation::None) {
|
||||
if (SemIR::GetValueRepr(context.sem_ir(), arg_type_id).kind !=
|
||||
SemIR::ValueRepr::None) {
|
||||
args.push_back(context.GetValue(arg_id));
|
||||
}
|
||||
}
|
||||
@@ -256,16 +255,16 @@ auto HandleReturn(FunctionContext& context, SemIR::InstId /*inst_id*/,
|
||||
|
||||
auto HandleReturnExpr(FunctionContext& context, SemIR::InstId /*inst_id*/,
|
||||
SemIR::ReturnExpr inst) -> void {
|
||||
switch (SemIR::GetInitializingRepresentation(
|
||||
context.sem_ir(),
|
||||
context.sem_ir().insts().Get(inst.expr_id).type_id())
|
||||
.kind) {
|
||||
case SemIR::InitializingRepresentation::None:
|
||||
case SemIR::InitializingRepresentation::InPlace:
|
||||
switch (
|
||||
SemIR::GetInitRepr(context.sem_ir(),
|
||||
context.sem_ir().insts().Get(inst.expr_id).type_id())
|
||||
.kind) {
|
||||
case SemIR::InitRepr::None:
|
||||
case SemIR::InitRepr::InPlace:
|
||||
// Nothing to return.
|
||||
context.builder().CreateRetVoid();
|
||||
return;
|
||||
case SemIR::InitializingRepresentation::ByCopy:
|
||||
case SemIR::InitRepr::ByCopy:
|
||||
// The expression produces the value representation for the type.
|
||||
context.builder().CreateRet(context.GetValue(inst.expr_id));
|
||||
return;
|
||||
|
||||
@@ -37,20 +37,19 @@ static auto GetAggregateElement(FunctionContext& context,
|
||||
|
||||
case SemIR::ExprCategory::Value: {
|
||||
auto value_rep =
|
||||
SemIR::GetValueRepresentation(context.sem_ir(), aggr_inst.type_id());
|
||||
CARBON_CHECK(value_rep.aggregate_kind !=
|
||||
SemIR::ValueRepresentation::NotAggregate)
|
||||
SemIR::GetValueRepr(context.sem_ir(), aggr_inst.type_id());
|
||||
CARBON_CHECK(value_rep.aggregate_kind != SemIR::ValueRepr::NotAggregate)
|
||||
<< "aggregate type should have aggregate value representation";
|
||||
switch (value_rep.kind) {
|
||||
case SemIR::ValueRepresentation::Unknown:
|
||||
case SemIR::ValueRepr::Unknown:
|
||||
CARBON_FATAL() << "Lowering access to incomplete aggregate type";
|
||||
case SemIR::ValueRepresentation::None:
|
||||
case SemIR::ValueRepr::None:
|
||||
return aggr_value;
|
||||
case SemIR::ValueRepresentation::Copy:
|
||||
case SemIR::ValueRepr::Copy:
|
||||
// We are holding the values of the aggregate directly, elementwise.
|
||||
return context.builder().CreateExtractValue(aggr_value, idx.index,
|
||||
name);
|
||||
case SemIR::ValueRepresentation::Pointer: {
|
||||
case SemIR::ValueRepr::Pointer: {
|
||||
// The value representation is a pointer to an aggregate that we want
|
||||
// to index into.
|
||||
auto pointee_type_id =
|
||||
@@ -67,12 +66,11 @@ static auto GetAggregateElement(FunctionContext& context,
|
||||
|
||||
// `elem_ptr` points to a value representation. Load it.
|
||||
auto result_value_type_id =
|
||||
SemIR::GetValueRepresentation(context.sem_ir(), result_type_id)
|
||||
.type_id;
|
||||
SemIR::GetValueRepr(context.sem_ir(), result_type_id).type_id;
|
||||
return context.builder().CreateLoad(
|
||||
context.GetType(result_value_type_id), elem_ptr, name + ".load");
|
||||
}
|
||||
case SemIR::ValueRepresentation::Custom:
|
||||
case SemIR::ValueRepr::Custom:
|
||||
CARBON_FATAL()
|
||||
<< "Aggregate should never have custom value representation";
|
||||
}
|
||||
@@ -120,8 +118,7 @@ auto HandleClassElementAccess(FunctionContext& context, SemIR::InstId inst_id,
|
||||
inst_id,
|
||||
GetAggregateElement(
|
||||
context, inst.base_id, inst.index, inst.type_id,
|
||||
GetStructFieldName(context, class_info.object_representation_id,
|
||||
inst.index)));
|
||||
GetStructFieldName(context, class_info.object_repr_id, inst.index)));
|
||||
}
|
||||
|
||||
static auto EmitAggregateInitializer(FunctionContext& context,
|
||||
@@ -130,14 +127,13 @@ static auto EmitAggregateInitializer(FunctionContext& context,
|
||||
llvm::Twine name) -> llvm::Value* {
|
||||
auto* llvm_type = context.GetType(type_id);
|
||||
|
||||
switch (
|
||||
SemIR::GetInitializingRepresentation(context.sem_ir(), type_id).kind) {
|
||||
case SemIR::InitializingRepresentation::None:
|
||||
case SemIR::InitializingRepresentation::InPlace:
|
||||
switch (SemIR::GetInitRepr(context.sem_ir(), type_id).kind) {
|
||||
case SemIR::InitRepr::None:
|
||||
case SemIR::InitRepr::InPlace:
|
||||
// TODO: Add a helper to poison a value slot.
|
||||
return llvm::PoisonValue::get(llvm_type);
|
||||
|
||||
case SemIR::InitializingRepresentation::ByCopy: {
|
||||
case SemIR::InitRepr::ByCopy: {
|
||||
auto refs = context.sem_ir().inst_blocks().Get(refs_id);
|
||||
CARBON_CHECK(refs.size() == 1)
|
||||
<< "Unexpected size for aggregate with by-copy value representation";
|
||||
@@ -185,20 +181,19 @@ auto HandleStructLiteral(FunctionContext& /*context*/,
|
||||
|
||||
// Emits the value representation for a struct or tuple whose elements are the
|
||||
// contents of `refs_id`.
|
||||
auto EmitAggregateValueRepresentation(FunctionContext& context,
|
||||
SemIR::TypeId type_id,
|
||||
SemIR::InstBlockId refs_id,
|
||||
llvm::Twine name) -> llvm::Value* {
|
||||
auto value_rep = SemIR::GetValueRepresentation(context.sem_ir(), type_id);
|
||||
auto EmitAggregateValueRepr(FunctionContext& context, SemIR::TypeId type_id,
|
||||
SemIR::InstBlockId refs_id, llvm::Twine name)
|
||||
-> llvm::Value* {
|
||||
auto value_rep = SemIR::GetValueRepr(context.sem_ir(), type_id);
|
||||
switch (value_rep.kind) {
|
||||
case SemIR::ValueRepresentation::Unknown:
|
||||
case SemIR::ValueRepr::Unknown:
|
||||
CARBON_FATAL() << "Incomplete aggregate type in lowering";
|
||||
|
||||
case SemIR::ValueRepresentation::None:
|
||||
case SemIR::ValueRepr::None:
|
||||
// TODO: Add a helper to get a "no value representation" value.
|
||||
return llvm::PoisonValue::get(context.GetType(value_rep.type_id));
|
||||
|
||||
case SemIR::ValueRepresentation::Copy: {
|
||||
case SemIR::ValueRepr::Copy: {
|
||||
auto refs = context.sem_ir().inst_blocks().Get(refs_id);
|
||||
CARBON_CHECK(refs.size() == 1)
|
||||
<< "Unexpected size for aggregate with by-copy value representation";
|
||||
@@ -209,7 +204,7 @@ auto EmitAggregateValueRepresentation(FunctionContext& context,
|
||||
context.GetValue(refs[0]), {0});
|
||||
}
|
||||
|
||||
case SemIR::ValueRepresentation::Pointer: {
|
||||
case SemIR::ValueRepr::Pointer: {
|
||||
auto pointee_type_id = context.sem_ir().GetPointeeType(value_rep.type_id);
|
||||
auto* llvm_value_rep_type = context.GetType(pointee_type_id);
|
||||
|
||||
@@ -227,7 +222,7 @@ auto EmitAggregateValueRepresentation(FunctionContext& context,
|
||||
return alloca;
|
||||
}
|
||||
|
||||
case SemIR::ValueRepresentation::Custom:
|
||||
case SemIR::ValueRepr::Custom:
|
||||
CARBON_FATAL()
|
||||
<< "Aggregate should never have custom value representation";
|
||||
}
|
||||
@@ -242,9 +237,8 @@ auto HandleStructInit(FunctionContext& context, SemIR::InstId inst_id,
|
||||
|
||||
auto HandleStructValue(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::StructValue inst) -> void {
|
||||
context.SetLocal(
|
||||
inst_id, EmitAggregateValueRepresentation(context, inst.type_id,
|
||||
inst.elements_id, "struct"));
|
||||
context.SetLocal(inst_id, EmitAggregateValueRepr(context, inst.type_id,
|
||||
inst.elements_id, "struct"));
|
||||
}
|
||||
|
||||
auto HandleStructTypeField(FunctionContext& /*context*/,
|
||||
@@ -285,9 +279,8 @@ auto HandleTupleInit(FunctionContext& context, SemIR::InstId inst_id,
|
||||
|
||||
auto HandleTupleValue(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::TupleValue inst) -> void {
|
||||
context.SetLocal(inst_id,
|
||||
EmitAggregateValueRepresentation(context, inst.type_id,
|
||||
inst.elements_id, "tuple"));
|
||||
context.SetLocal(inst_id, EmitAggregateValueRepr(context, inst.type_id,
|
||||
inst.elements_id, "tuple"));
|
||||
}
|
||||
|
||||
} // namespace Carbon::Lower
|
||||
|
||||
@@ -9,28 +9,27 @@ namespace Carbon::Lower {
|
||||
|
||||
auto HandleBindValue(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::BindValue inst) -> void {
|
||||
switch (auto rep =
|
||||
SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id);
|
||||
switch (auto rep = SemIR::GetValueRepr(context.sem_ir(), inst.type_id);
|
||||
rep.kind) {
|
||||
case SemIR::ValueRepresentation::Unknown:
|
||||
case SemIR::ValueRepr::Unknown:
|
||||
CARBON_FATAL()
|
||||
<< "Value binding for type with incomplete value representation";
|
||||
case SemIR::ValueRepresentation::None:
|
||||
case SemIR::ValueRepr::None:
|
||||
// Nothing should use this value, but StubRef needs a value to
|
||||
// propagate.
|
||||
// TODO: Remove this now the StubRefs are gone.
|
||||
context.SetLocal(inst_id,
|
||||
llvm::PoisonValue::get(context.GetType(inst.type_id)));
|
||||
break;
|
||||
case SemIR::ValueRepresentation::Copy:
|
||||
case SemIR::ValueRepr::Copy:
|
||||
context.SetLocal(inst_id, context.builder().CreateLoad(
|
||||
context.GetType(inst.type_id),
|
||||
context.GetValue(inst.value_id)));
|
||||
break;
|
||||
case SemIR::ValueRepresentation::Pointer:
|
||||
case SemIR::ValueRepr::Pointer:
|
||||
context.SetLocal(inst_id, context.GetValue(inst.value_id));
|
||||
break;
|
||||
case SemIR::ValueRepresentation::Custom:
|
||||
case SemIR::ValueRepr::Custom:
|
||||
CARBON_FATAL() << "TODO: Add support for BindValue with custom value rep";
|
||||
}
|
||||
}
|
||||
@@ -52,9 +51,8 @@ auto HandleValueAsRef(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::ValueAsRef inst) -> void {
|
||||
CARBON_CHECK(SemIR::GetExprCategory(context.sem_ir(), inst.value_id) ==
|
||||
SemIR::ExprCategory::Value);
|
||||
CARBON_CHECK(
|
||||
SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id).kind ==
|
||||
SemIR::ValueRepresentation::Pointer);
|
||||
CARBON_CHECK(SemIR::GetValueRepr(context.sem_ir(), inst.type_id).kind ==
|
||||
SemIR::ValueRepr::Pointer);
|
||||
context.SetLocal(inst_id, context.GetValue(inst.value_id));
|
||||
}
|
||||
|
||||
@@ -62,12 +60,10 @@ auto HandleValueOfInitializer(FunctionContext& context, SemIR::InstId inst_id,
|
||||
SemIR::ValueOfInitializer inst) -> void {
|
||||
CARBON_CHECK(SemIR::GetExprCategory(context.sem_ir(), inst.init_id) ==
|
||||
SemIR::ExprCategory::Initializing);
|
||||
CARBON_CHECK(
|
||||
SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id).kind ==
|
||||
SemIR::ValueRepresentation::Copy);
|
||||
CARBON_CHECK(
|
||||
SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id)
|
||||
.kind == SemIR::InitializingRepresentation::ByCopy);
|
||||
CARBON_CHECK(SemIR::GetValueRepr(context.sem_ir(), inst.type_id).kind ==
|
||||
SemIR::ValueRepr::Copy);
|
||||
CARBON_CHECK(SemIR::GetInitRepr(context.sem_ir(), inst.type_id).kind ==
|
||||
SemIR::InitRepr::ByCopy);
|
||||
context.SetLocal(inst_id, context.GetValue(inst.init_id));
|
||||
}
|
||||
|
||||
|
||||
+12
-13
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace Carbon::SemIR {
|
||||
|
||||
auto ValueRepresentation::Print(llvm::raw_ostream& out) const -> void {
|
||||
auto ValueRepr::Print(llvm::raw_ostream& out) const -> void {
|
||||
out << "{kind: ";
|
||||
switch (kind) {
|
||||
case Unknown:
|
||||
@@ -39,7 +39,7 @@ auto ValueRepresentation::Print(llvm::raw_ostream& out) const -> void {
|
||||
}
|
||||
|
||||
auto TypeInfo::Print(llvm::raw_ostream& out) const -> void {
|
||||
out << "{inst: " << inst_id << ", value_rep: " << value_representation << "}";
|
||||
out << "{inst: " << inst_id << ", value_rep: " << value_repr << "}";
|
||||
}
|
||||
|
||||
File::File(SharedValueStores& value_stores)
|
||||
@@ -585,23 +585,22 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
|
||||
}
|
||||
}
|
||||
|
||||
auto GetInitializingRepresentation(const File& file, TypeId type_id)
|
||||
-> InitializingRepresentation {
|
||||
auto value_rep = GetValueRepresentation(file, type_id);
|
||||
auto GetInitRepr(const File& file, TypeId type_id) -> InitRepr {
|
||||
auto value_rep = GetValueRepr(file, type_id);
|
||||
switch (value_rep.kind) {
|
||||
case ValueRepresentation::None:
|
||||
return {.kind = InitializingRepresentation::None};
|
||||
case ValueRepr::None:
|
||||
return {.kind = InitRepr::None};
|
||||
|
||||
case ValueRepresentation::Copy:
|
||||
case ValueRepr::Copy:
|
||||
// TODO: Use in-place initialization for types that have non-trivial
|
||||
// destructive move.
|
||||
return {.kind = InitializingRepresentation::ByCopy};
|
||||
return {.kind = InitRepr::ByCopy};
|
||||
|
||||
case ValueRepresentation::Pointer:
|
||||
case ValueRepresentation::Custom:
|
||||
return {.kind = InitializingRepresentation::InPlace};
|
||||
case ValueRepr::Pointer:
|
||||
case ValueRepr::Custom:
|
||||
return {.kind = InitRepr::InPlace};
|
||||
|
||||
case ValueRepresentation::Unknown:
|
||||
case ValueRepr::Unknown:
|
||||
CARBON_FATAL()
|
||||
<< "Attempting to perform initialization of incomplete type";
|
||||
}
|
||||
|
||||
+16
-21
@@ -78,9 +78,7 @@ struct Class : public Printable<Class> {
|
||||
|
||||
// Determines whether this class has been fully defined. This is false until
|
||||
// we reach the `}` of the class definition.
|
||||
auto is_defined() const -> bool {
|
||||
return object_representation_id.is_valid();
|
||||
}
|
||||
auto is_defined() const -> bool { return object_repr_id.is_valid(); }
|
||||
|
||||
// The following members always have values, and do not change throughout the
|
||||
// lifetime of the class.
|
||||
@@ -115,11 +113,11 @@ struct Class : public Printable<Class> {
|
||||
|
||||
// The object representation type to use for this class. This is valid once
|
||||
// the class is defined.
|
||||
TypeId object_representation_id = TypeId::Invalid;
|
||||
TypeId object_repr_id = TypeId::Invalid;
|
||||
};
|
||||
|
||||
// The value representation to use when passing by value.
|
||||
struct ValueRepresentation : public Printable<ValueRepresentation> {
|
||||
struct ValueRepr : public Printable<ValueRepr> {
|
||||
auto Print(llvm::raw_ostream& out) const -> void;
|
||||
|
||||
enum Kind : int8_t {
|
||||
@@ -178,7 +176,7 @@ struct TypeInfo : public Printable<TypeInfo> {
|
||||
InstId inst_id;
|
||||
// The value representation for this type. Will be `Unknown` if the type is
|
||||
// not complete.
|
||||
ValueRepresentation value_representation = ValueRepresentation();
|
||||
ValueRepr value_repr = ValueRepr();
|
||||
};
|
||||
|
||||
// Provides semantic analysis on a Parse::Tree.
|
||||
@@ -213,16 +211,15 @@ class File : public Printable<File> {
|
||||
}
|
||||
|
||||
// Marks a type as complete, and sets its value representation.
|
||||
auto CompleteType(TypeId object_type_id,
|
||||
ValueRepresentation value_representation) -> void {
|
||||
auto CompleteType(TypeId object_type_id, ValueRepr value_repr) -> void {
|
||||
if (object_type_id.index < 0) {
|
||||
// We already know our builtin types are complete.
|
||||
return;
|
||||
}
|
||||
CARBON_CHECK(types().Get(object_type_id).value_representation.kind ==
|
||||
ValueRepresentation::Unknown)
|
||||
CARBON_CHECK(types().Get(object_type_id).value_repr.kind ==
|
||||
ValueRepr::Unknown)
|
||||
<< "Type " << object_type_id << " completed more than once";
|
||||
types().Get(object_type_id).value_representation = value_representation;
|
||||
types().Get(object_type_id).value_repr = value_repr;
|
||||
complete_types_.push_back(object_type_id);
|
||||
}
|
||||
|
||||
@@ -240,18 +237,18 @@ class File : public Printable<File> {
|
||||
|
||||
// Gets the value representation to use for a type. This returns an
|
||||
// invalid type if the given type is not complete.
|
||||
auto GetValueRepresentation(TypeId type_id) const -> ValueRepresentation {
|
||||
auto GetValueRepr(TypeId type_id) const -> ValueRepr {
|
||||
if (type_id.index < 0) {
|
||||
// TypeType and InvalidType are their own value representation.
|
||||
return {.kind = ValueRepresentation::Copy, .type_id = type_id};
|
||||
return {.kind = ValueRepr::Copy, .type_id = type_id};
|
||||
}
|
||||
return types().Get(type_id).value_representation;
|
||||
return types().Get(type_id).value_repr;
|
||||
}
|
||||
|
||||
// Determines whether the given type is known to be complete. This does not
|
||||
// determine whether the type could be completed, only whether it has been.
|
||||
auto IsTypeComplete(TypeId type_id) const -> bool {
|
||||
return GetValueRepresentation(type_id).kind != ValueRepresentation::Unknown;
|
||||
return GetValueRepr(type_id).kind != ValueRepr::Unknown;
|
||||
}
|
||||
|
||||
// Gets the pointee type of the given type, which must be a pointer type.
|
||||
@@ -420,13 +417,12 @@ enum class ExprCategory : int8_t {
|
||||
auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory;
|
||||
|
||||
// Returns information about the value representation to use for a type.
|
||||
inline auto GetValueRepresentation(const File& file, TypeId type_id)
|
||||
-> ValueRepresentation {
|
||||
return file.GetValueRepresentation(type_id);
|
||||
inline auto GetValueRepr(const File& file, TypeId type_id) -> ValueRepr {
|
||||
return file.GetValueRepr(type_id);
|
||||
}
|
||||
|
||||
// The initializing representation to use when returning by value.
|
||||
struct InitializingRepresentation {
|
||||
struct InitRepr {
|
||||
enum Kind : int8_t {
|
||||
// The type has no initializing representation. This is used for empty
|
||||
// types, where no initialization is necessary.
|
||||
@@ -449,8 +445,7 @@ struct InitializingRepresentation {
|
||||
};
|
||||
|
||||
// Returns information about the initializing representation to use for a type.
|
||||
auto GetInitializingRepresentation(const File& file, TypeId type_id)
|
||||
-> InitializingRepresentation;
|
||||
auto GetInitRepr(const File& file, TypeId type_id) -> InitRepr;
|
||||
|
||||
} // namespace Carbon::SemIR
|
||||
|
||||
|
||||
@@ -789,8 +789,7 @@ class Formatter {
|
||||
|
||||
llvm::ArrayRef<InstId> args = sem_ir_.inst_blocks().Get(inst.args_id);
|
||||
|
||||
bool has_return_slot =
|
||||
GetInitializingRepresentation(sem_ir_, inst.type_id).has_return_slot();
|
||||
bool has_return_slot = GetInitRepr(sem_ir_, inst.type_id).has_return_slot();
|
||||
InstId return_slot_id = InstId::Invalid;
|
||||
if (has_return_slot) {
|
||||
return_slot_id = args.back();
|
||||
|
||||
Reference in New Issue
Block a user