inst_categories.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_
  6. #include "toolchain/sem_ir/ids.h"
  7. #include "toolchain/sem_ir/inst_kind.h"
  8. #include "toolchain/sem_ir/typed_insts.h"
  9. // An inst category is a set of inst kinds that can be treated polymorphically.
  10. // Each inst category is represented by a C++ type, just like an inst kind,
  11. // which can losslessly represent any inst in the category. `CategoryOf`
  12. // is used to declare the typed insts that belong to the category.
  13. namespace Carbon::SemIR {
  14. // Declares a category consisting of `TypedInsts...`, which is a list of typed
  15. // insts (not kinds). Should only be used to define a public type alias member
  16. // of a category inst type:
  17. //
  18. // struct MyCategory {
  19. // using CategoryInfo = CARBON_INST_CATEGORY_INFO(MyCategory);
  20. // InstKind kind;
  21. // ...
  22. // }
  23. template <typename... TypedInsts>
  24. struct CategoryOf {
  25. // The InstKinds that belong to the category.
  26. static constexpr InstKind Kinds[] = {TypedInsts::Kind...};
  27. };
  28. // For each category, we provide `CategoryName_CARBON_INST_CATEGORY` for the
  29. // `CARBON_KIND_ANY` macro. This macro uses the same expansion to provide a
  30. // `CategoryOf` for the category.
  31. #define CARBON_INST_CATEGORY_INFO(Name) \
  32. CategoryOf<Name##_CARBON_INST_CATEGORY( \
  33. CARBON_INST_CATEGORY_INFO_INTERNAL_NAME, \
  34. CARBON_INST_CATEGORY_INFO_INTERNAL_COMMA)>
  35. #define CARBON_INST_CATEGORY_INFO_INTERNAL_NAME(Name) Name
  36. #define CARBON_INST_CATEGORY_INFO_INTERNAL_COMMA ,
  37. // clang-format off
  38. #define AnyAggregateAccess_CARBON_INST_CATEGORY(X, Sep) \
  39. X(::Carbon::SemIR::ClassElementAccess) Sep \
  40. X(::Carbon::SemIR::StructAccess) Sep \
  41. X(::Carbon::SemIR::TupleAccess)
  42. // clang-format on
  43. #define AnyAggregateAccess_CARBON_KIND_ANY_EXPAND \
  44. CARBON_KIND_ANY_EXPAND_BEGIN AnyAggregateAccess_CARBON_INST_CATEGORY( \
  45. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  46. // Common representation for aggregate access nodes, which access a fixed
  47. // element of an aggregate.
  48. struct AnyAggregateAccess {
  49. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyAggregateAccess);
  50. InstKind kind;
  51. TypeId type_id;
  52. InstId aggregate_id;
  53. ElementIndex index;
  54. };
  55. // clang-format off
  56. #define AnyAggregateInit_CARBON_INST_CATEGORY(X, Sep) \
  57. X(::Carbon::SemIR::ArrayInit) Sep \
  58. X(::Carbon::SemIR::ClassInit) Sep \
  59. X(::Carbon::SemIR::StructInit) Sep \
  60. X(::Carbon::SemIR::TupleInit)
  61. // clang-format on
  62. #define AnyAggregateInit_CARBON_KIND_ANY_EXPAND \
  63. CARBON_KIND_ANY_EXPAND_BEGIN AnyAggregateInit_CARBON_INST_CATEGORY( \
  64. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  65. // Common representation for all kinds of aggregate initialization.
  66. struct AnyAggregateInit {
  67. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyAggregateInit);
  68. InstKind kind;
  69. TypeId type_id;
  70. InstBlockId elements_id;
  71. DestInstId dest_id;
  72. };
  73. // clang-format off
  74. #define AnyAggregateValue_CARBON_INST_CATEGORY(X, Sep) \
  75. X(::Carbon::SemIR::StructValue) Sep \
  76. X(::Carbon::SemIR::TupleValue)
  77. // clang-format on
  78. #define AnyAggregateValue_CARBON_KIND_ANY_EXPAND \
  79. CARBON_KIND_ANY_EXPAND_BEGIN AnyAggregateValue_CARBON_INST_CATEGORY( \
  80. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  81. // Common representation for all kinds of aggregate value.
  82. struct AnyAggregateValue {
  83. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyAggregateValue);
  84. InstKind kind;
  85. TypeId type_id;
  86. InstBlockId elements_id;
  87. };
  88. // clang-format off
  89. #define AnyBindingPattern_CARBON_INST_CATEGORY(X, Sep) \
  90. X(::Carbon::SemIR::FormBindingPattern) Sep \
  91. X(::Carbon::SemIR::RefBindingPattern) Sep \
  92. X(::Carbon::SemIR::SymbolicBindingPattern) Sep \
  93. X(::Carbon::SemIR::ValueBindingPattern)
  94. // clang-format on
  95. #define AnyBindingPattern_CARBON_KIND_ANY_EXPAND \
  96. CARBON_KIND_ANY_EXPAND_BEGIN AnyBindingPattern_CARBON_INST_CATEGORY( \
  97. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  98. // Common representation for various `*binding_pattern` nodes.
  99. struct AnyBindingPattern {
  100. // TODO: Also handle TemplateBindingPattern once it exists.
  101. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBindingPattern);
  102. InstKind kind;
  103. // Always a PatternType whose scrutinee type is the declared type of the
  104. // binding.
  105. TypeId type_id;
  106. // The name declared by the binding pattern. `None` indicates that the
  107. // pattern has `_` in the name position, and so does not truly declare
  108. // a name.
  109. EntityNameId entity_name_id;
  110. };
  111. // clang-format off
  112. #define AnyBinding_CARBON_INST_CATEGORY(X, Sep) \
  113. X(::Carbon::SemIR::AliasBinding) Sep \
  114. X(::Carbon::SemIR::FormBinding) Sep \
  115. X(::Carbon::SemIR::RefBinding) Sep \
  116. X(::Carbon::SemIR::SymbolicBinding) Sep \
  117. X(::Carbon::SemIR::ValueBinding)
  118. // clang-format on
  119. #define AnyBinding_CARBON_KIND_ANY_EXPAND \
  120. CARBON_KIND_ANY_EXPAND_BEGIN AnyBinding_CARBON_INST_CATEGORY( \
  121. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  122. // Common representation for various `bind*` nodes.
  123. struct AnyBinding {
  124. // TODO: Also handle BindTemplateName once it exists.
  125. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBinding);
  126. InstKind kind;
  127. TypeId type_id;
  128. EntityNameId entity_name_id;
  129. // The value is inline in the inst so that value access doesn't require an
  130. // indirection.
  131. InstId value_id;
  132. };
  133. // clang-format off
  134. #define AnyBindingOrExportDecl_CARBON_INST_CATEGORY(X, Sep) \
  135. X(::Carbon::SemIR::AliasBinding) Sep \
  136. X(::Carbon::SemIR::FormBinding) Sep \
  137. X(::Carbon::SemIR::RefBinding) Sep \
  138. X(::Carbon::SemIR::SymbolicBinding) Sep \
  139. X(::Carbon::SemIR::ValueBinding) Sep \
  140. X(::Carbon::SemIR::ExportDecl)
  141. // clang-format on
  142. #define AnyBindingOrExportDecl_CARBON_KIND_ANY_EXPAND \
  143. CARBON_KIND_ANY_EXPAND_BEGIN AnyBindingOrExportDecl_CARBON_INST_CATEGORY( \
  144. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  145. // Common representation for various `bind*` nodes, and `export name`.
  146. struct AnyBindingOrExportDecl {
  147. // TODO: Also handle BindTemplateName once it exists.
  148. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBindingOrExportDecl);
  149. InstKind kind;
  150. TypeId type_id;
  151. EntityNameId entity_name_id;
  152. InstId value_id;
  153. };
  154. // clang-format off
  155. #define AnyBranch_CARBON_INST_CATEGORY(X, Sep) \
  156. X(::Carbon::SemIR::Branch) Sep \
  157. X(::Carbon::SemIR::BranchIf) Sep \
  158. X(::Carbon::SemIR::BranchWithArg)
  159. // clang-format on
  160. #define AnyBranch_CARBON_KIND_ANY_EXPAND \
  161. CARBON_KIND_ANY_EXPAND_BEGIN AnyBranch_CARBON_INST_CATEGORY( \
  162. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  163. // Common representation for all kinds of `Branch*` node.
  164. struct AnyBranch {
  165. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBranch);
  166. InstKind kind;
  167. // Branches don't produce a value, so have no type.
  168. LabelId target_id;
  169. // Kind-specific data.
  170. AnyRawId arg1;
  171. };
  172. // clang-format off
  173. #define AnyFoundationDecl_CARBON_INST_CATEGORY(X, Sep) \
  174. X(::Carbon::SemIR::AdaptDecl) Sep \
  175. X(::Carbon::SemIR::BaseDecl)
  176. // clang-format on
  177. #define AnyFoundationDecl_CARBON_KIND_ANY_EXPAND \
  178. CARBON_KIND_ANY_EXPAND_BEGIN AnyFoundationDecl_CARBON_INST_CATEGORY( \
  179. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  180. // Common representation for declarations describing the foundation type of a
  181. // class -- either its adapted type or its base class.
  182. struct AnyFoundationDecl {
  183. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyFoundationDecl);
  184. InstKind kind;
  185. TypeId type_id;
  186. TypeInstId foundation_type_inst_id;
  187. // Kind-specific data.
  188. AnyRawId arg1;
  189. };
  190. // clang-format off
  191. #define AnyImportRef_CARBON_INST_CATEGORY(X, Sep) \
  192. X(::Carbon::SemIR::ImportRefLoaded) Sep \
  193. X(::Carbon::SemIR::ImportRefUnloaded)
  194. // clang-format on
  195. #define AnyImportRef_CARBON_KIND_ANY_EXPAND \
  196. CARBON_KIND_ANY_EXPAND_BEGIN AnyImportRef_CARBON_INST_CATEGORY( \
  197. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  198. // Common representation for all kinds of `ImportRef*` node.
  199. struct AnyImportRef {
  200. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyImportRef);
  201. InstKind kind;
  202. TypeId type_id;
  203. ImportIRInstId import_ir_inst_id;
  204. // A BindName is currently only set on directly imported names. It is not
  205. // generically available.
  206. EntityNameId entity_name_id;
  207. };
  208. // clang-format off
  209. #define AnyParam_CARBON_INST_CATEGORY(X, Sep) \
  210. X(::Carbon::SemIR::OutParam) Sep \
  211. X(::Carbon::SemIR::RefParam) Sep \
  212. X(::Carbon::SemIR::ValueParam)
  213. // clang-format on
  214. #define AnyParam_CARBON_KIND_ANY_EXPAND \
  215. CARBON_KIND_ANY_EXPAND_BEGIN AnyParam_CARBON_INST_CATEGORY( \
  216. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  217. // A `Call` parameter for a function or other parameterized block.
  218. struct AnyParam {
  219. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyParam);
  220. InstKind kind;
  221. TypeId type_id;
  222. CallParamIndex index;
  223. // A name to associate with this Param in pretty-printed IR. This is not
  224. // necessarily unique, and can even be `None`; it has no semantic
  225. // significance.
  226. NameId pretty_name_id;
  227. };
  228. // clang-format off
  229. #define AnyParamPattern_CARBON_INST_CATEGORY(X, Sep) \
  230. X(::Carbon::SemIR::FormParamPattern) Sep \
  231. X(::Carbon::SemIR::OutParamPattern) Sep \
  232. X(::Carbon::SemIR::RefParamPattern) Sep \
  233. X(::Carbon::SemIR::ValueParamPattern) Sep \
  234. X(::Carbon::SemIR::VarParamPattern)
  235. // clang-format on
  236. #define AnyParamPattern_CARBON_KIND_ANY_EXPAND \
  237. CARBON_KIND_ANY_EXPAND_BEGIN AnyParamPattern_CARBON_INST_CATEGORY( \
  238. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  239. // A pattern that represents a `Call` parameter. It delegates to subpattern_id
  240. // in pattern matching.
  241. struct AnyParamPattern {
  242. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyParamPattern);
  243. InstKind kind;
  244. // Always a PatternType that represents the same type as the type of
  245. // `subpattern_id`.
  246. TypeId type_id;
  247. InstId subpattern_id;
  248. };
  249. // clang-format off
  250. #define AnyPrimitiveForm_CARBON_INST_CATEGORY(X, Sep) \
  251. X(::Carbon::SemIR::InitForm) Sep \
  252. X(::Carbon::SemIR::RefForm) Sep \
  253. X(::Carbon::SemIR::ValueForm)
  254. // clang-format on
  255. #define AnyPrimitiveForm_CARBON_KIND_ANY_EXPAND \
  256. CARBON_KIND_ANY_EXPAND_BEGIN AnyPrimitiveForm_CARBON_INST_CATEGORY( \
  257. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  258. // An inst that represents a primitive form.
  259. struct AnyPrimitiveForm {
  260. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyPrimitiveForm);
  261. InstKind kind;
  262. // Always FormType.
  263. TypeId type_id;
  264. // The type component of the form.
  265. TypeInstId type_component_id;
  266. };
  267. // clang-format off
  268. #define AnyQualifiedType_CARBON_INST_CATEGORY(X, Sep) \
  269. X(::Carbon::SemIR::ConstType) Sep \
  270. X(::Carbon::SemIR::MaybeUnformedType) Sep \
  271. X(::Carbon::SemIR::PartialType)
  272. // clang-format on
  273. #define AnyQualifiedType_CARBON_KIND_ANY_EXPAND \
  274. CARBON_KIND_ANY_EXPAND_BEGIN AnyQualifiedType_CARBON_INST_CATEGORY( \
  275. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  276. // A type qualifier that wraps another type and has the same object
  277. // representation. Qualifiers are arranged so that adding a qualifier is
  278. // generally safe, and removing a qualifier is not necessarily safe or correct.
  279. struct AnyQualifiedType {
  280. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyQualifiedType);
  281. InstKind kind;
  282. TypeId type_id;
  283. TypeInstId inner_id;
  284. };
  285. // clang-format off
  286. #define AnyStructType_CARBON_INST_CATEGORY(X, Sep) \
  287. X(::Carbon::SemIR::CustomLayoutType) Sep \
  288. X(::Carbon::SemIR::StructType)
  289. // clang-format on
  290. #define AnyStructType_CARBON_KIND_ANY_EXPAND \
  291. CARBON_KIND_ANY_EXPAND_BEGIN AnyStructType_CARBON_INST_CATEGORY( \
  292. CARBON_KIND_ANY_EXPAND_CASE, CARBON_KIND_ANY_EXPAND_SEP)
  293. // A struct-like type with a list of named fields.
  294. struct AnyStructType {
  295. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyStructType);
  296. InstKind kind;
  297. TypeId type_id;
  298. StructTypeFieldsId fields_id;
  299. AnyRawId arg1;
  300. };
  301. } // namespace Carbon::SemIR
  302. #endif // CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_