mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +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 {
|
||||
|
||||
Reference in New Issue
Block a user