mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Alphabetize typed_insts.h (#5401)
As requested [here](https://github.com/carbon-language/carbon-lang/pull/5400#discussion_r2070631805). --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
42dc24d26b
commit
0b3edee177
@@ -26,6 +26,7 @@
|
||||
#include "toolchain/sem_ir/generic.h"
|
||||
#include "toolchain/sem_ir/id_kind.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst_categories.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "toolchain/sem_ir/generic.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/inst_categories.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
#include "toolchain/sem_ir/pattern.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
@@ -27,6 +27,7 @@ cc_library(
|
||||
hdrs = [
|
||||
"id_kind.h",
|
||||
"ids.h",
|
||||
"inst_categories.h",
|
||||
"inst_kind.h",
|
||||
"singleton_insts.h",
|
||||
"typed_insts.h",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "toolchain/sem_ir/builtin_function_kind.h"
|
||||
#include "toolchain/sem_ir/entity_with_params_base.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst_categories.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
namespace Carbon::SemIR {
|
||||
|
||||
+58
-7
@@ -24,12 +24,14 @@
|
||||
|
||||
namespace Carbon::SemIR {
|
||||
|
||||
template <typename... TypedInsts>
|
||||
struct CategoryOf;
|
||||
|
||||
// InstLikeTypeInfo is an implementation detail, and not public API.
|
||||
namespace Internal {
|
||||
|
||||
// Information about an instruction-like type, which is a type that an Inst can
|
||||
// be converted to and from. The `Enabled` parameter is used to check
|
||||
// requirements on the type in the specializations of this template.
|
||||
// be converted to and from.
|
||||
template <typename InstLikeType>
|
||||
struct InstLikeTypeInfo;
|
||||
|
||||
@@ -74,15 +76,60 @@ struct InstLikeTypeInfo<TypedInst> : InstLikeTypeInfoBase<TypedInst> {
|
||||
static auto DebugName() -> InstKind { return TypedInst::Kind; }
|
||||
};
|
||||
|
||||
// If `TypedInst` has an Nth field, validates that `CategoryInst` has a
|
||||
// corresponding field with a compatible type.
|
||||
template <typename CategoryInst, typename TypedInst, size_t N>
|
||||
static consteval auto ValidateCategoryFieldForTypedInst() -> void {
|
||||
if constexpr (InstLikeTypeInfoBase<TypedInst>::NumArgs > N) {
|
||||
if constexpr (!std::is_same_v<typename InstLikeTypeInfoBase<
|
||||
CategoryInst>::template ArgType<N>,
|
||||
AnyRawId>) {
|
||||
static_assert(
|
||||
std::is_same_v<
|
||||
typename InstLikeTypeInfoBase<CategoryInst>::template ArgType<N>,
|
||||
typename InstLikeTypeInfoBase<TypedInst>::template ArgType<N>>,
|
||||
"Inst category field should be the same type as the "
|
||||
"corresponding fields of its typed insts, or AnyRawId if "
|
||||
"they have different types");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validates that `CategoryInst` is compatible with `TypedInst`
|
||||
template <typename CategoryInst, typename TypedInst>
|
||||
static consteval auto ValidateCategoryForTypedInst() -> void {
|
||||
static_assert(Internal::HasKindMemberAsField<CategoryInst>,
|
||||
"Inst category should have an `InstKind` field");
|
||||
static_assert(!HasTypeIdMember<TypedInst> || HasTypeIdMember<CategoryInst>,
|
||||
"Inst category should have a `TypeId` field if any of its "
|
||||
"typed insts do");
|
||||
|
||||
static_assert(InstLikeTypeInfoBase<CategoryInst>::NumArgs >=
|
||||
InstLikeTypeInfoBase<TypedInst>::NumArgs,
|
||||
"Inst category should have as many fields as any of its typed "
|
||||
"insts");
|
||||
|
||||
ValidateCategoryFieldForTypedInst<CategoryInst, TypedInst, 0>();
|
||||
ValidateCategoryFieldForTypedInst<CategoryInst, TypedInst, 1>();
|
||||
}
|
||||
|
||||
// Validates that `CategoryInst` is compatible with all of `TypedInsts`.
|
||||
// Always returns true; validation failure will cause build errors when
|
||||
// instantiating the function.
|
||||
template <typename CategoryInst, typename... TypedInsts>
|
||||
static consteval auto ValidateCategory(
|
||||
CategoryOf<TypedInsts...> /*category_info*/) -> bool {
|
||||
(ValidateCategoryForTypedInst<CategoryInst, TypedInsts>(), ...);
|
||||
return true;
|
||||
}
|
||||
|
||||
// An instruction category is instruction-like.
|
||||
template <typename InstCat>
|
||||
requires std::same_as<const InstKind&, decltype(InstCat::Kinds[0])>
|
||||
requires requires { typename InstCat::CategoryInfo; }
|
||||
struct InstLikeTypeInfo<InstCat> : InstLikeTypeInfoBase<InstCat> {
|
||||
static_assert(HasKindMemberAsField<InstCat>,
|
||||
"Instruction category should have a kind field");
|
||||
static auto GetKind(InstCat cat) -> InstKind { return cat.kind; }
|
||||
static constexpr auto IsKind(InstKind kind) -> bool {
|
||||
for (InstKind k : InstCat::Kinds) {
|
||||
for (InstKind k : InstCat::CategoryInfo::Kinds) {
|
||||
if (k == kind) {
|
||||
return true;
|
||||
}
|
||||
@@ -94,12 +141,16 @@ struct InstLikeTypeInfo<InstCat> : InstLikeTypeInfoBase<InstCat> {
|
||||
RawStringOstream out;
|
||||
out << "{";
|
||||
llvm::ListSeparator sep;
|
||||
for (auto kind : InstCat::Kinds) {
|
||||
for (auto kind : InstCat::CategoryInfo::Kinds) {
|
||||
out << sep << kind;
|
||||
}
|
||||
out << "}";
|
||||
return out.TakeStr();
|
||||
}
|
||||
|
||||
private:
|
||||
// Trigger validation of `InstCat`.
|
||||
static_assert(ValidateCategory<InstCat>(typename InstCat::CategoryInfo()));
|
||||
};
|
||||
|
||||
// HasInstCategory is true if T::Kind is an element of InstCat::Kinds.
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_
|
||||
#define CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_
|
||||
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
// An inst category is a set of inst kinds that can be treated polymorphically.
|
||||
// Each inst category is represented by a C++ type, just like an inst kind,
|
||||
// which can losslessly represent any inst in the category. `CategoryOf`
|
||||
// is used to declare the typed insts that belong to the category.
|
||||
|
||||
namespace Carbon::SemIR {
|
||||
|
||||
// Declares a category consisting of `TypedInsts...`, which is a list of typed
|
||||
// insts (not kinds). Should only be used to define a public type alias member
|
||||
// of a category inst type:
|
||||
//
|
||||
// struct MyCategory {
|
||||
// using CategoryInfo = CategoryOf<X, Y, Z>;
|
||||
// InstKind kind;
|
||||
// ...
|
||||
// }
|
||||
template <typename... TypedInsts>
|
||||
struct CategoryOf {
|
||||
// The InstKinds that belong to the category.
|
||||
static constexpr InstKind Kinds[] = {TypedInsts::Kind...};
|
||||
};
|
||||
|
||||
// Common representation for aggregate access nodes, which access a fixed
|
||||
// element of an aggregate.
|
||||
struct AnyAggregateAccess {
|
||||
using CategoryInfo =
|
||||
CategoryOf<ClassElementAccess, StructAccess, TupleAccess>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
InstId aggregate_id;
|
||||
ElementIndex index;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of aggregate initialization.
|
||||
struct AnyAggregateInit {
|
||||
using CategoryInfo = CategoryOf<ArrayInit, ClassInit, StructInit, TupleInit>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
InstBlockId elements_id;
|
||||
DestInstId dest_id;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of aggregate value.
|
||||
struct AnyAggregateValue {
|
||||
using CategoryInfo = CategoryOf<StructValue, TupleValue>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
InstBlockId elements_id;
|
||||
};
|
||||
|
||||
// Common representation for various `*binding_pattern` nodes.
|
||||
struct AnyBindingPattern {
|
||||
// TODO: Also handle TemplateBindingPattern once it exists.
|
||||
using CategoryInfo = CategoryOf<BindingPattern, SymbolicBindingPattern>;
|
||||
|
||||
InstKind kind;
|
||||
|
||||
// Always a PatternType whose scrutinee type is the declared type of the
|
||||
// binding.
|
||||
TypeId type_id;
|
||||
|
||||
// The name declared by the binding pattern. `None` indicates that the
|
||||
// pattern has `_` in the name position, and so does not truly declare
|
||||
// a name.
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// Common representation for various `bind*` nodes.
|
||||
struct AnyBindName {
|
||||
// TODO: Also handle BindTemplateName once it exists.
|
||||
using CategoryInfo = CategoryOf<BindAlias, BindName, BindSymbolicName>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
// Common representation for various `bind*` nodes, and `export name`.
|
||||
struct AnyBindNameOrExportDecl {
|
||||
// TODO: Also handle BindTemplateName once it exists.
|
||||
using CategoryInfo =
|
||||
CategoryOf<BindAlias, BindName, BindSymbolicName, ExportDecl>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of `Branch*` node.
|
||||
struct AnyBranch {
|
||||
using CategoryInfo = CategoryOf<Branch, BranchIf, BranchWithArg>;
|
||||
|
||||
InstKind kind;
|
||||
// Branches don't produce a value, so have no type.
|
||||
LabelId target_id;
|
||||
// Kind-specific data.
|
||||
AnyRawId arg1;
|
||||
};
|
||||
|
||||
// Common representation for declarations describing the foundation type of a
|
||||
// class -- either its adapted type or its base class.
|
||||
struct AnyFoundationDecl {
|
||||
using CategoryInfo = CategoryOf<AdaptDecl, BaseDecl>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
TypeInstId foundation_type_inst_id;
|
||||
// Kind-specific data.
|
||||
AnyRawId arg1;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of `ImportRef*` node.
|
||||
struct AnyImportRef {
|
||||
using CategoryInfo = CategoryOf<ImportRefUnloaded, ImportRefLoaded>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
ImportIRInstId import_ir_inst_id;
|
||||
// A BindName is currently only set on directly imported names. It is not
|
||||
// generically available.
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// A `Call` parameter for a function or other parameterized block.
|
||||
struct AnyParam {
|
||||
using CategoryInfo = CategoryOf<OutParam, RefParam, ValueParam>;
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
CallParamIndex index;
|
||||
|
||||
// A name to associate with this Param in pretty-printed IR. This is not
|
||||
// necessarily unique, and can even be `None`; it has no semantic
|
||||
// significance.
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// A pattern that represents a `Call` parameter. It delegates to subpattern_id
|
||||
// in pattern matching. The sub-kinds differ only in the expression category
|
||||
// of the corresponding parameter inst.
|
||||
struct AnyParamPattern {
|
||||
using CategoryInfo =
|
||||
CategoryOf<OutParamPattern, RefParamPattern, ValueParamPattern>;
|
||||
|
||||
InstKind kind;
|
||||
|
||||
// Always a PatternType that represents the same type as the type of
|
||||
// `subpattern_id`.
|
||||
TypeId type_id;
|
||||
InstId subpattern_id;
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
} // namespace Carbon::SemIR
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "toolchain/parse/tree.h"
|
||||
#include "toolchain/sem_ir/file.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst_categories.h"
|
||||
#include "toolchain/sem_ir/inst_fingerprinter.h"
|
||||
|
||||
namespace Carbon::SemIR {
|
||||
|
||||
+169
-307
@@ -76,17 +76,6 @@ struct AccessOptionalMemberAction {
|
||||
NameId name_id;
|
||||
};
|
||||
|
||||
// Common representation for declarations describing the foundation type of a
|
||||
// class -- either its adapted type or its base class.
|
||||
struct AnyFoundationDecl {
|
||||
static constexpr InstKind Kinds[] = {InstKind::AdaptDecl, InstKind::BaseDecl};
|
||||
|
||||
InstKind kind;
|
||||
TypeInstId foundation_type_inst_id;
|
||||
// Kind-specific data.
|
||||
AnyRawId arg1;
|
||||
};
|
||||
|
||||
// An adapted type declaration in a class, of the form `adapt T;`.
|
||||
struct AdaptDecl {
|
||||
static constexpr auto Kind = InstKind::AdaptDecl.Define<Parse::AdaptDeclId>(
|
||||
@@ -139,41 +128,6 @@ struct ArrayIndex {
|
||||
InstId index_id;
|
||||
};
|
||||
|
||||
// Common representation for aggregate access nodes, which access a fixed
|
||||
// element of an aggregate.
|
||||
struct AnyAggregateAccess {
|
||||
static constexpr InstKind Kinds[] = {InstKind::ClassElementAccess,
|
||||
InstKind::StructAccess,
|
||||
InstKind::TupleAccess};
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
InstId aggregate_id;
|
||||
ElementIndex index;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of aggregate initialization.
|
||||
struct AnyAggregateInit {
|
||||
static constexpr InstKind Kinds[] = {InstKind::ArrayInit, InstKind::ClassInit,
|
||||
InstKind::StructInit,
|
||||
InstKind::TupleInit};
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
InstBlockId elements_id;
|
||||
DestInstId dest_id;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of aggregate value.
|
||||
struct AnyAggregateValue {
|
||||
static constexpr InstKind Kinds[] = {InstKind::StructValue,
|
||||
InstKind::TupleValue};
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
InstBlockId elements_id;
|
||||
};
|
||||
|
||||
// Initializes an array from a tuple. `tuple_id` is the source tuple
|
||||
// expression. `inits_id` contains one initializer per array element.
|
||||
// `dest_id` is the destination array object for the initialization.
|
||||
@@ -296,31 +250,6 @@ struct BaseDecl {
|
||||
ElementIndex index;
|
||||
};
|
||||
|
||||
// Common representation for various `bind*` nodes.
|
||||
struct AnyBindName {
|
||||
// TODO: Also handle BindTemplateName once it exists.
|
||||
static constexpr InstKind Kinds[] = {InstKind::BindAlias, InstKind::BindName,
|
||||
InstKind::BindSymbolicName};
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
// Common representation for various `bind*` nodes, and `export name`.
|
||||
struct AnyBindNameOrExportDecl {
|
||||
// TODO: Also handle BindTemplateName once it exists.
|
||||
static constexpr InstKind Kinds[] = {InstKind::BindAlias, InstKind::BindName,
|
||||
InstKind::BindSymbolicName,
|
||||
InstKind::ExportDecl};
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
// Binds a name as an alias.
|
||||
struct BindAlias {
|
||||
static constexpr auto Kind =
|
||||
@@ -366,25 +295,8 @@ struct BindValue {
|
||||
InstId value_id;
|
||||
};
|
||||
|
||||
// Common representation for various `*binding_pattern` nodes.
|
||||
struct AnyBindingPattern {
|
||||
// TODO: Also handle TemplateBindingPattern once it exists.
|
||||
static constexpr InstKind Kinds[] = {InstKind::BindingPattern,
|
||||
InstKind::SymbolicBindingPattern};
|
||||
|
||||
InstKind kind;
|
||||
|
||||
// Always a PatternType whose scrutinee type is the declared type of the
|
||||
// binding.
|
||||
TypeId type_id;
|
||||
|
||||
// The name declared by the binding pattern. `None` indicates that the
|
||||
// pattern has `_` in the name position, and so does not truly declare
|
||||
// a name.
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// Represents a non-symbolic binding pattern.
|
||||
// Represents a non-symbolic binding pattern. See `AnyBindingPattern` for member
|
||||
// documentation.
|
||||
struct BindingPattern {
|
||||
static constexpr auto Kind = InstKind::BindingPattern.Define<Parse::NodeId>(
|
||||
{.ir_name = "binding_pattern",
|
||||
@@ -395,19 +307,6 @@ struct BindingPattern {
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// Represents a symbolic binding pattern.
|
||||
struct SymbolicBindingPattern {
|
||||
static constexpr auto Kind =
|
||||
InstKind::SymbolicBindingPattern.Define<Parse::NodeId>({
|
||||
.ir_name = "symbolic_binding_pattern",
|
||||
.constant_kind = InstConstantKind::AlwaysUnique,
|
||||
.is_lowered = false,
|
||||
});
|
||||
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// Reads an argument from `BranchWithArg`.
|
||||
struct BlockArg {
|
||||
static constexpr auto Kind = InstKind::BlockArg.Define<Parse::NodeId>(
|
||||
@@ -471,18 +370,6 @@ struct BoundMethodType {
|
||||
TypeId type_id;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of `Branch*` node.
|
||||
struct AnyBranch {
|
||||
static constexpr InstKind Kinds[] = {InstKind::Branch, InstKind::BranchIf,
|
||||
InstKind::BranchWithArg};
|
||||
|
||||
InstKind kind;
|
||||
// Branches don't produce a value, so have no type.
|
||||
LabelId target_id;
|
||||
// Kind-specific data.
|
||||
AnyRawId arg1;
|
||||
};
|
||||
|
||||
// Control flow to branch to the target block.
|
||||
struct Branch {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
@@ -625,6 +512,19 @@ struct ConstType {
|
||||
TypeInstId inner_id;
|
||||
};
|
||||
|
||||
// Records that a type conversion `original as new_type` was done, producing the
|
||||
// result.
|
||||
struct Converted {
|
||||
static constexpr auto Kind =
|
||||
InstKind::Converted.Define<Parse::NodeId>({.ir_name = "converted"});
|
||||
|
||||
TypeId type_id;
|
||||
// The operand prior to being converted. This is tracked only for tooling
|
||||
// purposes and has no associated semantics.
|
||||
AbsoluteInstId original_id;
|
||||
InstId result_id;
|
||||
};
|
||||
|
||||
// An action that performs simple conversion to a value expression of a given
|
||||
// type.
|
||||
struct ConvertToValueAction {
|
||||
@@ -639,19 +539,6 @@ struct ConvertToValueAction {
|
||||
TypeInstId target_type_inst_id;
|
||||
};
|
||||
|
||||
// Records that a type conversion `original as new_type` was done, producing the
|
||||
// result.
|
||||
struct Converted {
|
||||
static constexpr auto Kind =
|
||||
InstKind::Converted.Define<Parse::NodeId>({.ir_name = "converted"});
|
||||
|
||||
TypeId type_id;
|
||||
// The operand prior to being converted. This is tracked only for tooling
|
||||
// purposes and has no associated semantics.
|
||||
AbsoluteInstId original_id;
|
||||
InstId result_id;
|
||||
};
|
||||
|
||||
// The `*` dereference operator, as in `*pointer`.
|
||||
struct Deref {
|
||||
static constexpr auto Kind =
|
||||
@@ -774,22 +661,6 @@ struct FloatType {
|
||||
InstId bit_width_id;
|
||||
};
|
||||
|
||||
// The legacy float type. This is currently used for real literals, and is
|
||||
// treated as f64. It's separate from `FloatType`, and should change to mirror
|
||||
// integers, likely replacing this with a `FloatLiteralType`.
|
||||
struct LegacyFloatType {
|
||||
static constexpr auto Kind =
|
||||
InstKind::LegacyFloatType.Define<Parse::NoneNodeId>(
|
||||
{.ir_name = "f64",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::Always});
|
||||
// This is a singleton instruction. However, it may still evolve into a more
|
||||
// standard type and be removed.
|
||||
static constexpr auto TypeInstId = MakeSingletonTypeInstId<Kind>();
|
||||
|
||||
TypeId type_id;
|
||||
};
|
||||
|
||||
// A function declaration.
|
||||
struct FunctionDecl {
|
||||
static constexpr auto Kind =
|
||||
@@ -1017,19 +888,8 @@ struct ImportDecl {
|
||||
NameId package_id;
|
||||
};
|
||||
|
||||
// Common representation for all kinds of `ImportRef*` node.
|
||||
struct AnyImportRef {
|
||||
static constexpr InstKind Kinds[] = {InstKind::ImportRefUnloaded,
|
||||
InstKind::ImportRefLoaded};
|
||||
|
||||
InstKind kind;
|
||||
ImportIRInstId import_ir_inst_id;
|
||||
// A BindName is currently only set on directly imported names. It is not
|
||||
// generically available.
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// An imported entity that is not yet been loaded.
|
||||
// An imported entity that is not yet been loaded. See `AnyImportRef` for
|
||||
// member documentation.
|
||||
struct ImportRefUnloaded {
|
||||
static constexpr auto Kind =
|
||||
InstKind::ImportRefUnloaded.Define<Parse::NodeId>(
|
||||
@@ -1039,7 +899,8 @@ struct ImportRefUnloaded {
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// A imported entity that is loaded, and may be used.
|
||||
// A imported entity that is loaded, and may be used. See `AnyImportRef` for
|
||||
// member documentation.
|
||||
struct ImportRefLoaded {
|
||||
static constexpr auto Kind = InstKind::ImportRefLoaded.Define<Parse::NodeId>(
|
||||
{.ir_name = "import_ref", .is_lowered = false});
|
||||
@@ -1103,16 +964,6 @@ struct InterfaceDecl {
|
||||
DeclInstBlockId decl_block_id;
|
||||
};
|
||||
|
||||
// A literal integer value.
|
||||
struct IntValue {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::IntValue.Define<Parse::NodeId>(
|
||||
{.ir_name = "int_value", .constant_kind = InstConstantKind::Always});
|
||||
|
||||
TypeId type_id;
|
||||
IntId int_id;
|
||||
};
|
||||
|
||||
// An arbitrary-precision integer type, which is used as the type of integer
|
||||
// literals and as the parameter type of `Core.Int` and `Core.Float`. This type
|
||||
// only provides compile-time operations, and is represented as an empty type at
|
||||
@@ -1148,6 +999,32 @@ struct IntType {
|
||||
InstId bit_width_id;
|
||||
};
|
||||
|
||||
// A literal integer value.
|
||||
struct IntValue {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::IntValue.Define<Parse::NodeId>(
|
||||
{.ir_name = "int_value", .constant_kind = InstConstantKind::Always});
|
||||
|
||||
TypeId type_id;
|
||||
IntId int_id;
|
||||
};
|
||||
|
||||
// The legacy float type. This is currently used for real literals, and is
|
||||
// treated as f64. It's separate from `FloatType`, and should change to mirror
|
||||
// integers, likely replacing this with a `FloatLiteralType`.
|
||||
struct LegacyFloatType {
|
||||
static constexpr auto Kind =
|
||||
InstKind::LegacyFloatType.Define<Parse::NoneNodeId>(
|
||||
{.ir_name = "f64",
|
||||
.is_type = InstIsType::Always,
|
||||
.constant_kind = InstConstantKind::Always});
|
||||
// This is a singleton instruction. However, it may still evolve into a more
|
||||
// standard type and be removed.
|
||||
static constexpr auto TypeInstId = MakeSingletonTypeInstId<Kind>();
|
||||
|
||||
TypeId type_id;
|
||||
};
|
||||
|
||||
// A symbolic instruction that takes the place of an `ImplWitness` when the
|
||||
// result is not fully known. When evaluated it does an impl lookup query, based
|
||||
// on the stored query arguments, that a type implements an interface. The query
|
||||
@@ -1230,21 +1107,6 @@ struct NamespaceType {
|
||||
TypeId type_id;
|
||||
};
|
||||
|
||||
// A `Call` parameter for a function or other parameterized block.
|
||||
struct AnyParam {
|
||||
static constexpr InstKind Kinds[] = {InstKind::OutParam, InstKind::RefParam,
|
||||
InstKind::ValueParam};
|
||||
|
||||
InstKind kind;
|
||||
TypeId type_id;
|
||||
CallParamIndex index;
|
||||
|
||||
// A name to associate with this Param in pretty-printed IR. This is not
|
||||
// necessarily unique, and can even be `None`; it has no semantic
|
||||
// significance.
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// An output `Call` parameter. See AnyParam for member documentation.
|
||||
struct OutParam {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
@@ -1256,46 +1118,8 @@ struct OutParam {
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// A by-reference `Call` parameter. See AnyParam for member documentation.
|
||||
struct RefParam {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::RefParam.Define<Parse::NodeId>(
|
||||
{.ir_name = "ref_param", .constant_kind = InstConstantKind::Never});
|
||||
|
||||
TypeId type_id;
|
||||
CallParamIndex index;
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// A by-value `Call` parameter. See AnyParam for member documentation.
|
||||
struct ValueParam {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::ValueParam.Define<Parse::NodeId>(
|
||||
{.ir_name = "value_param", .constant_kind = InstConstantKind::Never});
|
||||
|
||||
TypeId type_id;
|
||||
CallParamIndex index;
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// A pattern that represents a `Call` parameter. It delegates to subpattern_id
|
||||
// in pattern matching. The sub-kinds differ only in the expression category
|
||||
// of the corresponding parameter inst.
|
||||
struct AnyParamPattern {
|
||||
static constexpr InstKind Kinds[] = {InstKind::OutParamPattern,
|
||||
InstKind::RefParamPattern,
|
||||
InstKind::ValueParamPattern};
|
||||
|
||||
InstKind kind;
|
||||
|
||||
// Always a PatternType that represents the same type as the type of
|
||||
// `subpattern_id`.
|
||||
TypeId type_id;
|
||||
InstId subpattern_id;
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// A pattern that represents an output `Call` parameter.
|
||||
// A pattern that represents an output `Call` parameter. See `AnyParamPattern`
|
||||
// for member documentation.
|
||||
struct OutParamPattern {
|
||||
static constexpr auto Kind =
|
||||
InstKind::OutParamPattern.Define<Parse::ReturnTypeId>(
|
||||
@@ -1308,33 +1132,6 @@ struct OutParamPattern {
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// A pattern that represents a by-reference `Call` parameter.
|
||||
struct RefParamPattern {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::RefParamPattern.Define<Parse::NodeId>(
|
||||
{.ir_name = "ref_param_pattern",
|
||||
.constant_kind = InstConstantKind::AlwaysUnique,
|
||||
.is_lowered = false});
|
||||
|
||||
TypeId type_id;
|
||||
InstId subpattern_id;
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// A pattern that represents a by-value `Call` parameter.
|
||||
struct ValueParamPattern {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind =
|
||||
InstKind::ValueParamPattern.Define<Parse::NodeId>(
|
||||
{.ir_name = "value_param_pattern",
|
||||
.constant_kind = InstConstantKind::AlwaysUnique,
|
||||
.is_lowered = false});
|
||||
|
||||
TypeId type_id;
|
||||
InstId subpattern_id;
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// The type of a pattern that matches scrutinees of type
|
||||
// `scrutinee_type_inst_id`.
|
||||
struct PatternType {
|
||||
@@ -1375,6 +1172,31 @@ struct RefineTypeAction {
|
||||
TypeInstId inst_type_inst_id;
|
||||
};
|
||||
|
||||
// A by-reference `Call` parameter. See AnyParam for member documentation.
|
||||
struct RefParam {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::RefParam.Define<Parse::NodeId>(
|
||||
{.ir_name = "ref_param", .constant_kind = InstConstantKind::Never});
|
||||
|
||||
TypeId type_id;
|
||||
CallParamIndex index;
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// A pattern that represents a by-reference `Call` parameter. See
|
||||
// `AnyParamPattern` for member documentation.
|
||||
struct RefParamPattern {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::RefParamPattern.Define<Parse::NodeId>(
|
||||
{.ir_name = "ref_param_pattern",
|
||||
.constant_kind = InstConstantKind::AlwaysUnique,
|
||||
.is_lowered = false});
|
||||
|
||||
TypeId type_id;
|
||||
InstId subpattern_id;
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// Requires a type to be complete. This is only created for generic types and
|
||||
// produces a witness that the type is complete.
|
||||
//
|
||||
@@ -1395,6 +1217,45 @@ struct RequireCompleteType {
|
||||
TypeInstId complete_type_inst_id;
|
||||
};
|
||||
|
||||
// An `expr == expr` clause in a `where` expression or `require` declaration.
|
||||
struct RequirementEquivalent {
|
||||
static constexpr auto Kind =
|
||||
InstKind::RequirementEquivalent.Define<Parse::RequirementEqualEqualId>(
|
||||
{.ir_name = "requirement_equivalent",
|
||||
.constant_kind = InstConstantKind::Never,
|
||||
.is_lowered = false});
|
||||
|
||||
// No type since not an expression
|
||||
InstId lhs_id;
|
||||
InstId rhs_id;
|
||||
};
|
||||
|
||||
// An `expr impls expr` clause in a `where` expression or `require` declaration.
|
||||
struct RequirementImpls {
|
||||
static constexpr auto Kind =
|
||||
InstKind::RequirementImpls.Define<Parse::RequirementImplsId>(
|
||||
{.ir_name = "requirement_impls",
|
||||
.constant_kind = InstConstantKind::Never,
|
||||
.is_lowered = false});
|
||||
|
||||
// No type since not an expression
|
||||
InstId lhs_id;
|
||||
InstId rhs_id;
|
||||
};
|
||||
|
||||
// A `.M = expr` clause in a `where` expression or `require` declaration.
|
||||
struct RequirementRewrite {
|
||||
static constexpr auto Kind =
|
||||
InstKind::RequirementRewrite.Define<Parse::RequirementEqualId>(
|
||||
{.ir_name = "requirement_rewrite",
|
||||
.constant_kind = InstConstantKind::Never,
|
||||
.is_lowered = false});
|
||||
|
||||
// No type since not an expression
|
||||
InstId lhs_id;
|
||||
InstId rhs_id;
|
||||
};
|
||||
|
||||
struct Return {
|
||||
static constexpr auto Kind = InstKind::Return.Define<Parse::NodeId>(
|
||||
{.ir_name = "return",
|
||||
@@ -1457,45 +1318,6 @@ struct ReturnSlotPattern {
|
||||
TypeInstId type_inst_id;
|
||||
};
|
||||
|
||||
// An `expr == expr` clause in a `where` expression or `require` declaration.
|
||||
struct RequirementEquivalent {
|
||||
static constexpr auto Kind =
|
||||
InstKind::RequirementEquivalent.Define<Parse::RequirementEqualEqualId>(
|
||||
{.ir_name = "requirement_equivalent",
|
||||
.constant_kind = InstConstantKind::Never,
|
||||
.is_lowered = false});
|
||||
|
||||
// No type since not an expression
|
||||
InstId lhs_id;
|
||||
InstId rhs_id;
|
||||
};
|
||||
|
||||
// An `expr impls expr` clause in a `where` expression or `require` declaration.
|
||||
struct RequirementImpls {
|
||||
static constexpr auto Kind =
|
||||
InstKind::RequirementImpls.Define<Parse::RequirementImplsId>(
|
||||
{.ir_name = "requirement_impls",
|
||||
.constant_kind = InstConstantKind::Never,
|
||||
.is_lowered = false});
|
||||
|
||||
// No type since not an expression
|
||||
InstId lhs_id;
|
||||
InstId rhs_id;
|
||||
};
|
||||
|
||||
// A `.M = expr` clause in a `where` expression or `require` declaration.
|
||||
struct RequirementRewrite {
|
||||
static constexpr auto Kind =
|
||||
InstKind::RequirementRewrite.Define<Parse::RequirementEqualId>(
|
||||
{.ir_name = "requirement_rewrite",
|
||||
.constant_kind = InstConstantKind::Never,
|
||||
.is_lowered = false});
|
||||
|
||||
// No type since not an expression
|
||||
InstId lhs_id;
|
||||
InstId rhs_id;
|
||||
};
|
||||
|
||||
// Given an instruction with a constant value that depends on a generic
|
||||
// parameter, selects a version of that instruction with the constant value
|
||||
// corresponding to a particular specific.
|
||||
@@ -1682,6 +1504,20 @@ struct StructValue {
|
||||
InstBlockId elements_id;
|
||||
};
|
||||
|
||||
// Represents a symbolic binding pattern. See `AnyBindingPattern` for member
|
||||
// documentation.
|
||||
struct SymbolicBindingPattern {
|
||||
static constexpr auto Kind =
|
||||
InstKind::SymbolicBindingPattern.Define<Parse::NodeId>({
|
||||
.ir_name = "symbolic_binding_pattern",
|
||||
.constant_kind = InstConstantKind::AlwaysUnique,
|
||||
.is_lowered = false,
|
||||
});
|
||||
|
||||
TypeId type_id;
|
||||
EntityNameId entity_name_id;
|
||||
};
|
||||
|
||||
// A temporary value.
|
||||
struct Temporary {
|
||||
static constexpr auto Kind =
|
||||
@@ -1858,6 +1694,32 @@ struct ValueOfInitializer {
|
||||
InstId init_id;
|
||||
};
|
||||
|
||||
// A by-value `Call` parameter. See AnyParam for member documentation.
|
||||
struct ValueParam {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind = InstKind::ValueParam.Define<Parse::NodeId>(
|
||||
{.ir_name = "value_param", .constant_kind = InstConstantKind::Never});
|
||||
|
||||
TypeId type_id;
|
||||
CallParamIndex index;
|
||||
NameId pretty_name_id;
|
||||
};
|
||||
|
||||
// A pattern that represents a by-value `Call` parameter. See `AnyParamPattern`
|
||||
// for member documentation.
|
||||
struct ValueParamPattern {
|
||||
// TODO: Make Parse::NodeId more specific.
|
||||
static constexpr auto Kind =
|
||||
InstKind::ValueParamPattern.Define<Parse::NodeId>(
|
||||
{.ir_name = "value_param_pattern",
|
||||
.constant_kind = InstConstantKind::AlwaysUnique,
|
||||
.is_lowered = false});
|
||||
|
||||
TypeId type_id;
|
||||
InstId subpattern_id;
|
||||
CallParamIndex index;
|
||||
};
|
||||
|
||||
// A `var` pattern.
|
||||
struct VarPattern {
|
||||
static constexpr auto Kind =
|
||||
@@ -1887,6 +1749,24 @@ struct VarStorage {
|
||||
AbsoluteInstId pattern_id;
|
||||
};
|
||||
|
||||
// Definition of ABI-neutral vtable information for a dynamic class.
|
||||
struct Vtable {
|
||||
static constexpr auto Kind = InstKind::Vtable.Define<Parse::NodeId>(
|
||||
{.ir_name = "vtable",
|
||||
.constant_kind = InstConstantKind::Always,
|
||||
.is_lowered = false});
|
||||
TypeId type_id;
|
||||
InstBlockId virtual_functions_id;
|
||||
};
|
||||
|
||||
// Initializer for virtual function table pointers in object initialization.
|
||||
struct VtablePtr {
|
||||
static constexpr auto Kind = InstKind::VtablePtr.Define<Parse::NodeId>(
|
||||
{.ir_name = "vtable_ptr", .constant_kind = InstConstantKind::Never});
|
||||
TypeId type_id;
|
||||
InstId vtable_id;
|
||||
};
|
||||
|
||||
// The type of virtual function tables.
|
||||
struct VtableType {
|
||||
static constexpr auto Kind = InstKind::VtableType.Define<Parse::NoneNodeId>(
|
||||
@@ -1900,24 +1780,6 @@ struct VtableType {
|
||||
TypeId type_id;
|
||||
};
|
||||
|
||||
// Initializer for virtual function table pointers in object initialization.
|
||||
struct VtablePtr {
|
||||
static constexpr auto Kind = InstKind::VtablePtr.Define<Parse::NodeId>(
|
||||
{.ir_name = "vtable_ptr", .constant_kind = InstConstantKind::Never});
|
||||
TypeId type_id;
|
||||
InstId vtable_id;
|
||||
};
|
||||
|
||||
// Definition of ABI-neutral vtable information for a dynamic class.
|
||||
struct Vtable {
|
||||
static constexpr auto Kind = InstKind::Vtable.Define<Parse::NodeId>(
|
||||
{.ir_name = "vtable",
|
||||
.constant_kind = InstConstantKind::Always,
|
||||
.is_lowered = false});
|
||||
TypeId type_id;
|
||||
InstBlockId virtual_functions_id;
|
||||
};
|
||||
|
||||
// An `expr where requirements` expression.
|
||||
struct WhereExpr {
|
||||
static constexpr auto Kind = InstKind::WhereExpr.Define<Parse::WhereExprId>(
|
||||
|
||||
Reference in New Issue
Block a user