inst_categories.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  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. // Helper for defining `AnyKind_CARBON_KIND_ANY_EXPAND`.
  38. #define CARBON_INST_CATEGORY_ANY_EXPAND(AnyKind) \
  39. CARBON_KIND_ANY_EXPAND_BEGIN() \
  40. AnyKind##_CARBON_INST_CATEGORY(CARBON_KIND_ANY_EXPAND_CASE, \
  41. CARBON_KIND_ANY_EXPAND_SEP)
  42. // clang-format off
  43. #define AnyAggregateAccess_CARBON_INST_CATEGORY(X, Sep) \
  44. X(::Carbon::SemIR::ClassElementAccess) Sep() \
  45. X(::Carbon::SemIR::StructAccess) Sep() \
  46. X(::Carbon::SemIR::TupleAccess)
  47. // clang-format on
  48. #define AnyAggregateAccess_CARBON_KIND_ANY_EXPAND \
  49. CARBON_INST_CATEGORY_ANY_EXPAND(AnyAggregateAccess)
  50. // Common representation for aggregate access nodes, which access a fixed
  51. // element of an aggregate.
  52. struct AnyAggregateAccess {
  53. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyAggregateAccess);
  54. InstKind kind;
  55. TypeId type_id;
  56. InstId aggregate_id;
  57. ElementIndex index;
  58. };
  59. // clang-format off
  60. #define AnyAggregateInit_CARBON_INST_CATEGORY(X, Sep) \
  61. X(::Carbon::SemIR::ArrayInit) Sep() \
  62. X(::Carbon::SemIR::ClassInit) Sep() \
  63. X(::Carbon::SemIR::StructInit) Sep() \
  64. X(::Carbon::SemIR::TupleInit)
  65. // clang-format on
  66. #define AnyAggregateInit_CARBON_KIND_ANY_EXPAND \
  67. CARBON_INST_CATEGORY_ANY_EXPAND(AnyAggregateInit)
  68. // Common representation for all kinds of aggregate initialization.
  69. struct AnyAggregateInit {
  70. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyAggregateInit);
  71. InstKind kind;
  72. TypeId type_id;
  73. InstBlockId elements_id;
  74. DestInstId dest_id;
  75. };
  76. // clang-format off
  77. #define AnyAggregateValue_CARBON_INST_CATEGORY(X, Sep) \
  78. X(::Carbon::SemIR::StructValue) Sep() \
  79. X(::Carbon::SemIR::TupleValue)
  80. // clang-format on
  81. #define AnyAggregateValue_CARBON_KIND_ANY_EXPAND \
  82. CARBON_INST_CATEGORY_ANY_EXPAND(AnyAggregateValue)
  83. // Common representation for all kinds of aggregate value.
  84. struct AnyAggregateValue {
  85. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyAggregateValue);
  86. InstKind kind;
  87. TypeId type_id;
  88. InstBlockId elements_id;
  89. };
  90. // clang-format off
  91. #define AnyBindingPattern_CARBON_INST_CATEGORY(X, Sep) \
  92. X(::Carbon::SemIR::RefBindingPattern) Sep() \
  93. X(::Carbon::SemIR::SymbolicBindingPattern) Sep() \
  94. X(::Carbon::SemIR::ValueBindingPattern) Sep() \
  95. X(::Carbon::SemIR::WrapperBindingPattern)
  96. // clang-format on
  97. #define AnyBindingPattern_CARBON_KIND_ANY_EXPAND \
  98. CARBON_INST_CATEGORY_ANY_EXPAND(AnyBindingPattern)
  99. // Common representation for various `*binding_pattern` nodes.
  100. struct AnyBindingPattern {
  101. // TODO: Also handle TemplateBindingPattern once it exists.
  102. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBindingPattern);
  103. InstKind kind;
  104. // Always a PatternType whose scrutinee type is the declared type of the
  105. // binding.
  106. TypeId type_id;
  107. // The name declared by the binding pattern. `None` indicates that the
  108. // pattern has `_` in the name position, and so does not truly declare
  109. // a name.
  110. EntityNameId entity_name_id;
  111. // None unless this is an WrapperBindingPattern.
  112. InstId subpattern_id;
  113. };
  114. // clang-format off
  115. #define AnyBinding_CARBON_INST_CATEGORY(X, Sep) \
  116. X(::Carbon::SemIR::AliasBinding) Sep() \
  117. X(::Carbon::SemIR::RefBinding) Sep() \
  118. X(::Carbon::SemIR::SymbolicBinding) Sep() \
  119. X(::Carbon::SemIR::ValueBinding)
  120. // clang-format on
  121. #define AnyBinding_CARBON_KIND_ANY_EXPAND \
  122. CARBON_INST_CATEGORY_ANY_EXPAND(AnyBinding)
  123. // Common representation for various `bind*` nodes.
  124. struct AnyBinding {
  125. // TODO: Also handle BindTemplateName once it exists.
  126. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBinding);
  127. InstKind kind;
  128. TypeId type_id;
  129. EntityNameId entity_name_id;
  130. // The value is inline in the inst so that value access doesn't require an
  131. // indirection.
  132. InstId value_id;
  133. };
  134. // clang-format off
  135. #define AnyBindingOrExportDecl_CARBON_INST_CATEGORY(X, Sep) \
  136. AnyBinding_CARBON_INST_CATEGORY(X, Sep) Sep() \
  137. X(::Carbon::SemIR::ExportDecl)
  138. // clang-format on
  139. #define AnyBindingOrExportDecl_CARBON_KIND_ANY_EXPAND \
  140. CARBON_INST_CATEGORY_ANY_EXPAND(AnyBindingOrExportDecl)
  141. // Common representation for various `bind*` nodes, and `export name`.
  142. struct AnyBindingOrExportDecl {
  143. // TODO: Also handle BindTemplateName once it exists.
  144. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBindingOrExportDecl);
  145. InstKind kind;
  146. TypeId type_id;
  147. EntityNameId entity_name_id;
  148. InstId value_id;
  149. };
  150. // clang-format off
  151. #define AnyBranch_CARBON_INST_CATEGORY(X, Sep) \
  152. X(::Carbon::SemIR::Branch) Sep() \
  153. X(::Carbon::SemIR::BranchIf) Sep() \
  154. X(::Carbon::SemIR::BranchWithArg)
  155. // clang-format on
  156. #define AnyBranch_CARBON_KIND_ANY_EXPAND \
  157. CARBON_INST_CATEGORY_ANY_EXPAND(AnyBranch)
  158. // Common representation for all kinds of `Branch*` node.
  159. struct AnyBranch {
  160. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyBranch);
  161. InstKind kind;
  162. // Branches don't produce a value, so have no type.
  163. LabelId target_id;
  164. // Kind-specific data.
  165. AnyRawId arg1;
  166. };
  167. // clang-format off
  168. #define AnyFormParamAction_CARBON_INST_CATEGORY(X, Sep) \
  169. X(::Carbon::SemIR::FormParamPatternAction) Sep() \
  170. X(::Carbon::SemIR::OutFormParamPatternAction)
  171. // clang-format on
  172. #define AnyFormParamAction_CARBON_KIND_ANY_EXPAND \
  173. CARBON_INST_CATEGORY_ANY_EXPAND(AnyFormParamAction)
  174. // Common representation for various form-parameterized actions.
  175. struct AnyFormParamAction {
  176. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyFormParamAction);
  177. InstKind kind;
  178. // Always InstType.
  179. TypeId type_id;
  180. // The form of the parameter. Note that this is not the form of the pattern;
  181. // in particular, its type component is not a pattern type.
  182. MetaInstId form_id;
  183. AnyRawId arg1;
  184. };
  185. // clang-format off
  186. #define AnyFoundationDecl_CARBON_INST_CATEGORY(X, Sep) \
  187. X(::Carbon::SemIR::AdaptDecl) Sep() \
  188. X(::Carbon::SemIR::BaseDecl)
  189. // clang-format on
  190. #define AnyFoundationDecl_CARBON_KIND_ANY_EXPAND \
  191. CARBON_INST_CATEGORY_ANY_EXPAND(AnyFoundationDecl)
  192. // Common representation for declarations describing the foundation type of a
  193. // class -- either its adapted type or its base class.
  194. struct AnyFoundationDecl {
  195. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyFoundationDecl);
  196. InstKind kind;
  197. TypeId type_id;
  198. TypeInstId foundation_type_inst_id;
  199. // Kind-specific data.
  200. AnyRawId arg1;
  201. };
  202. // clang-format off
  203. #define AnyImportRef_CARBON_INST_CATEGORY(X, Sep) \
  204. X(::Carbon::SemIR::ImportRefLoaded) Sep() \
  205. X(::Carbon::SemIR::ImportRefUnloaded)
  206. // clang-format on
  207. #define AnyImportRef_CARBON_KIND_ANY_EXPAND \
  208. CARBON_INST_CATEGORY_ANY_EXPAND(AnyImportRef)
  209. // Common representation for all kinds of `ImportRef*` node.
  210. struct AnyImportRef {
  211. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyImportRef);
  212. InstKind kind;
  213. TypeId type_id;
  214. ImportIRInstId import_ir_inst_id;
  215. // A BindName is currently only set on directly imported names. It is not
  216. // generically available.
  217. EntityNameId entity_name_id;
  218. };
  219. // clang-format off
  220. #define AnyParam_CARBON_INST_CATEGORY(X, Sep) \
  221. X(::Carbon::SemIR::OutParam) Sep() \
  222. X(::Carbon::SemIR::RefParam) Sep() \
  223. X(::Carbon::SemIR::ValueParam)
  224. // clang-format on
  225. #define AnyParam_CARBON_KIND_ANY_EXPAND \
  226. CARBON_INST_CATEGORY_ANY_EXPAND(AnyParam)
  227. // A `Call` parameter for a function or other parameterized block.
  228. struct AnyParam {
  229. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyParam);
  230. InstKind kind;
  231. TypeId type_id;
  232. CallParamIndex index;
  233. // A name to associate with this Param in pretty-printed IR. This is not
  234. // necessarily unique, and can even be `None`; it has no semantic
  235. // significance.
  236. NameId pretty_name_id;
  237. };
  238. // clang-format off
  239. #define AnyLeafParamPattern_CARBON_INST_CATEGORY(X, Sep) \
  240. X(::Carbon::SemIR::OutParamPattern) Sep() \
  241. X(::Carbon::SemIR::RefParamPattern) Sep() \
  242. X(::Carbon::SemIR::ValueParamPattern)
  243. // clang-format on
  244. #define AnyLeafParamPattern_CARBON_KIND_ANY_EXPAND \
  245. CARBON_INST_CATEGORY_ANY_EXPAND(AnyLeafParamPattern)
  246. // A pattern that represents a `Call` parameter.
  247. struct AnyLeafParamPattern {
  248. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyLeafParamPattern);
  249. InstKind kind;
  250. // Always a PatternType.
  251. TypeId type_id;
  252. // A name to associate with this parameter in pretty-printed IR. This is not
  253. // necessarily unique, and can even be `None`; it has no semantic
  254. // significance.
  255. NameId pretty_name_id;
  256. AnyRawId arg1 = AnyRawId(AnyIdBase::NoneIndex);
  257. };
  258. // clang-format off
  259. #define AnyParamPattern_CARBON_INST_CATEGORY(X, Sep) \
  260. AnyLeafParamPattern_CARBON_INST_CATEGORY(X, Sep) Sep() \
  261. X(::Carbon::SemIR::VarParamPattern)
  262. // clang-format on
  263. #define AnyParamPattern_CARBON_KIND_ANY_EXPAND \
  264. CARBON_INST_CATEGORY_ANY_EXPAND(AnyParamPattern)
  265. // A pattern that represents a `Call` parameter.
  266. struct AnyParamPattern {
  267. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyParamPattern);
  268. InstKind kind;
  269. // Always a PatternType.
  270. TypeId type_id;
  271. AnyRawId arg0;
  272. AnyRawId arg1;
  273. };
  274. // clang-format off
  275. #define AnyPrimitiveForm_CARBON_INST_CATEGORY(X, Sep) \
  276. X(::Carbon::SemIR::InitForm) Sep() \
  277. X(::Carbon::SemIR::RefForm) Sep() \
  278. X(::Carbon::SemIR::ValueForm)
  279. // clang-format on
  280. #define AnyPrimitiveForm_CARBON_KIND_ANY_EXPAND \
  281. CARBON_INST_CATEGORY_ANY_EXPAND(AnyPrimitiveForm)
  282. // An inst that represents a primitive form.
  283. struct AnyPrimitiveForm {
  284. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyPrimitiveForm);
  285. InstKind kind;
  286. // Always FormType.
  287. TypeId type_id;
  288. // The type component of the form.
  289. TypeInstId type_component_id;
  290. };
  291. // clang-format off
  292. #define AnyQualifiedType_CARBON_INST_CATEGORY(X, Sep) \
  293. X(::Carbon::SemIR::ConstType) Sep() \
  294. X(::Carbon::SemIR::MaybeUnformedType) Sep() \
  295. X(::Carbon::SemIR::PartialType)
  296. // clang-format on
  297. #define AnyQualifiedType_CARBON_KIND_ANY_EXPAND \
  298. CARBON_INST_CATEGORY_ANY_EXPAND(AnyQualifiedType)
  299. // A type qualifier that wraps another type and has the same object
  300. // representation. Qualifiers are arranged so that adding a qualifier is
  301. // generally safe, and removing a qualifier is not necessarily safe or correct.
  302. struct AnyQualifiedType {
  303. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyQualifiedType);
  304. InstKind kind;
  305. TypeId type_id;
  306. TypeInstId inner_id;
  307. };
  308. // clang-format off
  309. #define AnyStructType_CARBON_INST_CATEGORY(X, Sep) \
  310. X(::Carbon::SemIR::CustomLayoutType) Sep() \
  311. X(::Carbon::SemIR::StructType)
  312. // clang-format on
  313. #define AnyStructType_CARBON_KIND_ANY_EXPAND \
  314. CARBON_INST_CATEGORY_ANY_EXPAND(AnyStructType)
  315. // A struct-like type with a list of named fields.
  316. struct AnyStructType {
  317. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyStructType);
  318. InstKind kind;
  319. TypeId type_id;
  320. StructTypeFieldsId fields_id;
  321. AnyRawId arg1;
  322. };
  323. // clang-format off
  324. #define AnyReturnPattern_CARBON_INST_CATEGORY(X, Sep) \
  325. X(::Carbon::SemIR::RefReturnPattern) Sep() \
  326. X(::Carbon::SemIR::ValueReturnPattern)
  327. // clang-format on
  328. #define AnyReturnPattern_CARBON_KIND_ANY_EXPAND \
  329. CARBON_INST_CATEGORY_ANY_EXPAND(AnyReturnPattern)
  330. struct AnyReturnPattern {
  331. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyReturnPattern);
  332. InstKind kind;
  333. TypeId type_id;
  334. };
  335. // clang-format off
  336. #define AnyVarPattern_CARBON_INST_CATEGORY(X, Sep) \
  337. X(::Carbon::SemIR::VarParamPattern) Sep() \
  338. X(::Carbon::SemIR::VarPattern)
  339. // clang-format on
  340. #define AnyVarPattern_CARBON_KIND_ANY_EXPAND \
  341. CARBON_INST_CATEGORY_ANY_EXPAND(AnyVarPattern)
  342. // A `var` pattern.
  343. struct AnyVarPattern {
  344. using CategoryInfo = CARBON_INST_CATEGORY_INFO(AnyVarPattern);
  345. InstKind kind;
  346. // Always a PatternType.
  347. TypeId type_id;
  348. // The pattern nested inside the `var`.
  349. InstId subpattern_id;
  350. };
  351. } // namespace Carbon::SemIR
  352. #endif // CARBON_TOOLCHAIN_SEM_IR_INST_CATEGORIES_H_