ids.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  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_IDS_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_IDS_H_
  6. #include "common/check.h"
  7. #include "common/ostream.h"
  8. #include "toolchain/base/index_base.h"
  9. #include "toolchain/base/value_ids.h"
  10. #include "toolchain/diagnostics/diagnostic_emitter.h"
  11. #include "toolchain/parse/node_ids.h"
  12. namespace Carbon::SemIR {
  13. // Forward declare indexed types, for integration with ValueStore.
  14. class File;
  15. class Inst;
  16. class NameScope;
  17. struct AssociatedConstant;
  18. struct Class;
  19. struct EntityName;
  20. struct ExprRegion;
  21. struct FacetTypeInfo;
  22. struct Function;
  23. struct Generic;
  24. struct Specific;
  25. struct ImportIR;
  26. struct ImportIRInst;
  27. struct Impl;
  28. struct Interface;
  29. struct StructTypeField;
  30. struct TypeInfo;
  31. // The ID of an instruction.
  32. struct InstId : public IdBase<InstId> {
  33. static constexpr llvm::StringLiteral Label = "inst";
  34. using ValueType = Inst;
  35. // An ID with no value.
  36. static const InstId None;
  37. // Represents the result of a name lookup that is temporarily disallowed
  38. // because the name is currently being initialized.
  39. static const InstId InitTombstone;
  40. using IdBase::IdBase;
  41. auto Print(llvm::raw_ostream& out) const -> void;
  42. };
  43. constexpr InstId InstId::None = InstId(NoneIndex);
  44. constexpr InstId InstId::InitTombstone = InstId(NoneIndex - 2);
  45. // An ID of an instruction that is referenced absolutely by another instruction.
  46. // This should only be used as the type of a field within a typed instruction
  47. // class.
  48. //
  49. // When a typed instruction has a field of this type, that field represents an
  50. // absolute reference to another instruction that typically resides in a
  51. // different entity. This behaves in most respects like an InstId field, but
  52. // substitution into the typed instruction leaves the field unchanged rather
  53. // than substituting into it.
  54. class AbsoluteInstId : public InstId {
  55. public:
  56. // Support implicit conversion from InstId so that InstId and AbsoluteInstId
  57. // have the same interface.
  58. // NOLINTNEXTLINE(google-explicit-constructor)
  59. constexpr AbsoluteInstId(InstId inst_id) : InstId(inst_id) {}
  60. using InstId::InstId;
  61. };
  62. // The ID of a constant value of an expression. An expression is either:
  63. //
  64. // - a template constant, with an immediate value, such as `42` or `i32*` or
  65. // `("hello", "world")`, or
  66. // - a symbolic constant, whose value includes a symbolic parameter, such as
  67. // `Vector(T*)`, or
  68. // - a runtime expression, such as `Print("hello")`.
  69. //
  70. // Template constants are a thin wrapper around the instruction ID of the
  71. // constant instruction that defines the constant. Symbolic constants are an
  72. // index into a separate table of `SymbolicConstant`s maintained by the constant
  73. // value store.
  74. struct ConstantId : public IdBase<ConstantId> {
  75. static constexpr llvm::StringLiteral Label = "constant";
  76. // An ID for an expression that is not constant.
  77. static const ConstantId NotConstant;
  78. // An ID with no value.
  79. static const ConstantId None;
  80. // Returns the constant ID corresponding to a template constant, which should
  81. // either be in the `constants` block in the file or should be known to be
  82. // unique.
  83. static constexpr auto ForTemplateConstant(InstId const_id) -> ConstantId {
  84. return ConstantId(const_id.index);
  85. }
  86. // Returns the constant ID corresponding to a symbolic constant index.
  87. static constexpr auto ForSymbolicConstantIndex(int32_t symbolic_index)
  88. -> ConstantId {
  89. return ConstantId(FirstSymbolicIndex - symbolic_index);
  90. }
  91. using IdBase::IdBase;
  92. // Returns whether this represents a constant. Requires has_value.
  93. auto is_constant() const -> bool {
  94. CARBON_DCHECK(has_value());
  95. return *this != ConstantId::NotConstant;
  96. }
  97. // Returns whether this represents a symbolic constant. Requires has_value.
  98. auto is_symbolic() const -> bool {
  99. CARBON_DCHECK(has_value());
  100. return index <= FirstSymbolicIndex;
  101. }
  102. // Returns whether this represents a template constant. Requires has_value.
  103. auto is_template() const -> bool {
  104. CARBON_DCHECK(has_value());
  105. return index >= 0;
  106. }
  107. // Prints this ID to the given output stream. `disambiguate` indicates whether
  108. // template constants should be wrapped with "templateConstant(...)" so that
  109. // they aren't printed the same as an InstId. This can be set to false if
  110. // there is no risk of ambiguity.
  111. auto Print(llvm::raw_ostream& out, bool disambiguate = true) const -> void;
  112. private:
  113. friend class ConstantValueStore;
  114. // TODO: C++23 makes std::abs constexpr, but until then we mirror std::abs
  115. // logic here. LLVM should still optimize this.
  116. static constexpr auto Abs(int32_t i) -> int32_t { return i > 0 ? i : -i; }
  117. // Returns the instruction that describes this template constant value.
  118. // Requires `is_template()`. Use `ConstantValueStore::GetInstId` to get the
  119. // instruction ID of a `ConstantId`.
  120. constexpr auto template_inst_id() const -> InstId {
  121. CARBON_DCHECK(is_template());
  122. return InstId(index);
  123. }
  124. // Returns the symbolic constant index that describes this symbolic constant
  125. // value. Requires `is_symbolic()`.
  126. constexpr auto symbolic_index() const -> int32_t {
  127. CARBON_DCHECK(is_symbolic());
  128. return FirstSymbolicIndex - index;
  129. }
  130. static constexpr int32_t NotConstantIndex = NoneIndex - 1;
  131. static constexpr int32_t FirstSymbolicIndex = NoneIndex - 2;
  132. };
  133. constexpr ConstantId ConstantId::NotConstant = ConstantId(NotConstantIndex);
  134. constexpr ConstantId ConstantId::None = ConstantId(NoneIndex);
  135. // The ID of a EntityName.
  136. struct EntityNameId : public IdBase<EntityNameId> {
  137. static constexpr llvm::StringLiteral Label = "entity_name";
  138. using ValueType = EntityName;
  139. // An ID with no value.
  140. static const EntityNameId None;
  141. using IdBase::IdBase;
  142. };
  143. constexpr EntityNameId EntityNameId::None = EntityNameId(NoneIndex);
  144. // The index of a compile-time binding. This is the de Bruijn level for the
  145. // binding -- that is, this is the number of other compile time bindings whose
  146. // scope encloses this binding.
  147. struct CompileTimeBindIndex : public IndexBase<CompileTimeBindIndex> {
  148. static constexpr llvm::StringLiteral Label = "comp_time_bind";
  149. // An index with no value.
  150. static const CompileTimeBindIndex None;
  151. using IndexBase::IndexBase;
  152. };
  153. constexpr CompileTimeBindIndex CompileTimeBindIndex::None =
  154. CompileTimeBindIndex(NoneIndex);
  155. // The index of a runtime parameter in a function. These are allocated
  156. // sequentially, left-to-right, to the function parameters that will have
  157. // arguments passed to them at runtime. In a `call` instruction, a runtime
  158. // argument will have the position in the argument list corresponding to its
  159. // runtime parameter index.
  160. // TODO: Rename this to CallParamIndex, for consistency with the "`Call`
  161. // parameters" terminology in EntityWithParamsBase.
  162. struct RuntimeParamIndex : public IndexBase<RuntimeParamIndex> {
  163. static constexpr llvm::StringLiteral Label = "runtime_param";
  164. // An index with no value.
  165. static const RuntimeParamIndex None;
  166. // An placeholder for index whose value is not yet known.
  167. static const RuntimeParamIndex Unknown;
  168. using IndexBase::IndexBase;
  169. auto Print(llvm::raw_ostream& out) const -> void;
  170. };
  171. constexpr RuntimeParamIndex RuntimeParamIndex::None =
  172. RuntimeParamIndex(NoneIndex);
  173. constexpr RuntimeParamIndex RuntimeParamIndex::Unknown =
  174. RuntimeParamIndex(NoneIndex - 1);
  175. // The ID of a function.
  176. struct FunctionId : public IdBase<FunctionId> {
  177. static constexpr llvm::StringLiteral Label = "function";
  178. using ValueType = Function;
  179. // An ID with no value.
  180. static const FunctionId None;
  181. using IdBase::IdBase;
  182. };
  183. constexpr FunctionId FunctionId::None = FunctionId(NoneIndex);
  184. // The ID of an IR within the set of all IRs being evaluated in the current
  185. // check execution.
  186. struct CheckIRId : public IdBase<CheckIRId> {
  187. static constexpr llvm::StringLiteral Label = "check_ir";
  188. using IdBase::IdBase;
  189. };
  190. // The ID of a class.
  191. struct ClassId : public IdBase<ClassId> {
  192. static constexpr llvm::StringLiteral Label = "class";
  193. using ValueType = Class;
  194. // An ID with no value.
  195. static const ClassId None;
  196. using IdBase::IdBase;
  197. };
  198. constexpr ClassId ClassId::None = ClassId(NoneIndex);
  199. // The ID of an interface.
  200. struct InterfaceId : public IdBase<InterfaceId> {
  201. static constexpr llvm::StringLiteral Label = "interface";
  202. using ValueType = Interface;
  203. // An ID with no value.
  204. static const InterfaceId None;
  205. using IdBase::IdBase;
  206. };
  207. constexpr InterfaceId InterfaceId::None = InterfaceId(NoneIndex);
  208. // The ID of an associated constant.
  209. struct AssociatedConstantId : public IdBase<AssociatedConstantId> {
  210. static constexpr llvm::StringLiteral Label = "assoc_const";
  211. using ValueType = AssociatedConstant;
  212. // An explicitly invalid ID.
  213. static const AssociatedConstantId None;
  214. using IdBase::IdBase;
  215. };
  216. constexpr AssociatedConstantId AssociatedConstantId::None =
  217. AssociatedConstantId(NoneIndex);
  218. // The ID of an faceet type value.
  219. struct FacetTypeId : public IdBase<FacetTypeId> {
  220. static constexpr llvm::StringLiteral Label = "facet_type";
  221. using ValueType = FacetTypeInfo;
  222. // An ID with no value.
  223. static const FacetTypeId None;
  224. using IdBase::IdBase;
  225. };
  226. constexpr FacetTypeId FacetTypeId::None = FacetTypeId(NoneIndex);
  227. // The ID of an impl.
  228. struct ImplId : public IdBase<ImplId> {
  229. static constexpr llvm::StringLiteral Label = "impl";
  230. using ValueType = Impl;
  231. // An ID with no value.
  232. static const ImplId None;
  233. using IdBase::IdBase;
  234. };
  235. constexpr ImplId ImplId::None = ImplId(NoneIndex);
  236. // The ID of a generic.
  237. struct GenericId : public IdBase<GenericId> {
  238. static constexpr llvm::StringLiteral Label = "generic";
  239. using ValueType = Generic;
  240. // An ID with no value.
  241. static const GenericId None;
  242. using IdBase::IdBase;
  243. };
  244. constexpr GenericId GenericId::None = GenericId(NoneIndex);
  245. // The ID of a specific, which is the result of specifying the generic arguments
  246. // for a generic.
  247. struct SpecificId : public IdBase<SpecificId> {
  248. static constexpr llvm::StringLiteral Label = "specific";
  249. using ValueType = Specific;
  250. // An ID with no value. This is typically used to represent a non-generic
  251. // entity.
  252. static const SpecificId None;
  253. using IdBase::IdBase;
  254. };
  255. constexpr SpecificId SpecificId::None = SpecificId(NoneIndex);
  256. // The index of an instruction that depends on generic parameters within a
  257. // region of a generic. A corresponding specific version of the instruction can
  258. // be found in each specific corresponding to that generic. This is a pair of a
  259. // region and an index, stored in 32 bits.
  260. struct GenericInstIndex : public IndexBase<GenericInstIndex> {
  261. // Where the value is first used within the generic.
  262. enum Region : uint8_t {
  263. // In the declaration.
  264. Declaration,
  265. // In the definition.
  266. Definition,
  267. };
  268. // An index with no value.
  269. static const GenericInstIndex None;
  270. explicit constexpr GenericInstIndex(Region region, int32_t index)
  271. : IndexBase(region == Declaration ? index
  272. : FirstDefinitionIndex - index) {
  273. CARBON_CHECK(index >= 0);
  274. }
  275. // Returns the index of the instruction within the region.
  276. auto index() const -> int32_t {
  277. CARBON_CHECK(has_value());
  278. return IndexBase::index >= 0 ? IndexBase::index
  279. : FirstDefinitionIndex - IndexBase::index;
  280. }
  281. // Returns the region within which this instruction was first used.
  282. auto region() const -> Region {
  283. CARBON_CHECK(has_value());
  284. return IndexBase::index >= 0 ? Declaration : Definition;
  285. }
  286. auto Print(llvm::raw_ostream& out) const -> void;
  287. private:
  288. static constexpr auto MakeNone() -> GenericInstIndex {
  289. GenericInstIndex result(Declaration, 0);
  290. result.IndexBase::index = NoneIndex;
  291. return result;
  292. }
  293. static constexpr int32_t FirstDefinitionIndex = NoneIndex - 1;
  294. };
  295. constexpr GenericInstIndex GenericInstIndex::None =
  296. GenericInstIndex::MakeNone();
  297. // The ID of an IR within the set of imported IRs, both direct and indirect.
  298. struct ImportIRId : public IdBase<ImportIRId> {
  299. static constexpr llvm::StringLiteral Label = "ir";
  300. using ValueType = ImportIR;
  301. // An ID with no value.
  302. static const ImportIRId None;
  303. // The implicit `api` import, for an `impl` file. A null entry is added if
  304. // there is none, as in an `api`, in which case this ID should not show up in
  305. // instructions.
  306. static const ImportIRId ApiForImpl;
  307. using IdBase::IdBase;
  308. };
  309. constexpr ImportIRId ImportIRId::None = ImportIRId(NoneIndex);
  310. constexpr ImportIRId ImportIRId::ApiForImpl = ImportIRId(0);
  311. // A boolean value.
  312. struct BoolValue : public IdBase<BoolValue> {
  313. // Not used by `Print`, but for `IdKind`.
  314. static constexpr llvm::StringLiteral Label = "bool";
  315. static const BoolValue False;
  316. static const BoolValue True;
  317. // Returns the `BoolValue` corresponding to `b`.
  318. static constexpr auto From(bool b) -> BoolValue { return b ? True : False; }
  319. // Returns the `bool` corresponding to this `BoolValue`.
  320. constexpr auto ToBool() -> bool {
  321. CARBON_CHECK(*this == False || *this == True, "Invalid bool value {0}",
  322. index);
  323. return *this != False;
  324. }
  325. using IdBase::IdBase;
  326. auto Print(llvm::raw_ostream& out) const -> void;
  327. };
  328. constexpr BoolValue BoolValue::False = BoolValue(0);
  329. constexpr BoolValue BoolValue::True = BoolValue(1);
  330. // An integer kind value -- either "signed" or "unsigned".
  331. //
  332. // This might eventually capture any other properties of an integer type that
  333. // affect its semantics, such as overflow behavior.
  334. struct IntKind : public IdBase<IntKind> {
  335. // Not used by `Print`, but for `IdKind`.
  336. static constexpr llvm::StringLiteral Label = "int_kind";
  337. static const IntKind Unsigned;
  338. static const IntKind Signed;
  339. using IdBase::IdBase;
  340. // Returns whether this type is signed.
  341. constexpr auto is_signed() -> bool { return *this == Signed; }
  342. auto Print(llvm::raw_ostream& out) const -> void;
  343. };
  344. constexpr IntKind IntKind::Unsigned = IntKind(0);
  345. constexpr IntKind IntKind::Signed = IntKind(1);
  346. // A float kind value.
  347. struct FloatKind : public IdBase<FloatKind> {
  348. // Not used by `Print`, but for `IdKind`.
  349. static constexpr llvm::StringLiteral Label = "float_kind";
  350. using IdBase::IdBase;
  351. auto Print(llvm::raw_ostream& out) const -> void { out << "float"; }
  352. };
  353. // The ID of a name. A name is either a string or a special name such as
  354. // `self`, `Self`, or `base`.
  355. struct NameId : public IdBase<NameId> {
  356. static constexpr llvm::StringLiteral Label = "name";
  357. // names().GetFormatted() is used for diagnostics.
  358. using DiagnosticType = DiagnosticTypeInfo<std::string>;
  359. // An ID with no value.
  360. static const NameId None;
  361. // The name of `self`.
  362. static const NameId SelfValue;
  363. // The name of `Self`.
  364. static const NameId SelfType;
  365. // The name of `.Self`.
  366. static const NameId PeriodSelf;
  367. // The name of the return slot in a function.
  368. static const NameId ReturnSlot;
  369. // The name of `package`.
  370. static const NameId PackageNamespace;
  371. // The name of `base`.
  372. static const NameId Base;
  373. // The name of `vptr`.
  374. static const NameId Vptr;
  375. // The number of non-index (<0) that exist, and will need storage in name
  376. // lookup.
  377. static const int NonIndexValueCount;
  378. // Returns the NameId corresponding to a particular IdentifierId.
  379. static auto ForIdentifier(IdentifierId id) -> NameId;
  380. using IdBase::IdBase;
  381. // Returns the IdentifierId corresponding to this NameId, or `None` if this is
  382. // a special name.
  383. auto AsIdentifierId() const -> IdentifierId {
  384. return index >= 0 ? IdentifierId(index) : IdentifierId::None;
  385. }
  386. auto Print(llvm::raw_ostream& out) const -> void;
  387. };
  388. constexpr NameId NameId::None = NameId(NoneIndex);
  389. constexpr NameId NameId::SelfValue = NameId(NoneIndex - 1);
  390. constexpr NameId NameId::SelfType = NameId(NoneIndex - 2);
  391. constexpr NameId NameId::PeriodSelf = NameId(NoneIndex - 3);
  392. constexpr NameId NameId::ReturnSlot = NameId(NoneIndex - 4);
  393. constexpr NameId NameId::PackageNamespace = NameId(NoneIndex - 5);
  394. constexpr NameId NameId::Base = NameId(NoneIndex - 6);
  395. constexpr NameId NameId::Vptr = NameId(NoneIndex - 7);
  396. constexpr int NameId::NonIndexValueCount = 8;
  397. // Enforce the link between SpecialValueCount and the last special value.
  398. static_assert(NameId::NonIndexValueCount == -NameId::Vptr.index);
  399. // The ID of a name scope.
  400. struct NameScopeId : public IdBase<NameScopeId> {
  401. static constexpr llvm::StringLiteral Label = "name_scope";
  402. using ValueType = NameScope;
  403. // An ID with no value.
  404. static const NameScopeId None;
  405. // The package (or file) name scope, guaranteed to be the first added.
  406. static const NameScopeId Package;
  407. using IdBase::IdBase;
  408. };
  409. constexpr NameScopeId NameScopeId::None = NameScopeId(NoneIndex);
  410. constexpr NameScopeId NameScopeId::Package = NameScopeId(0);
  411. // The ID of an instruction block.
  412. struct InstBlockId : public IdBase<InstBlockId> {
  413. static constexpr llvm::StringLiteral Label = "inst_block";
  414. // Types for BlockValueStore<InstBlockId>.
  415. using ElementType = InstId;
  416. using ValueType = llvm::MutableArrayRef<ElementType>;
  417. // The canonical empty block, reused to avoid allocating empty vectors. Always
  418. // the 0-index block.
  419. static const InstBlockId Empty;
  420. // Exported instructions. Empty until the File is fully checked; intermediate
  421. // state is in the Check::Context.
  422. static const InstBlockId Exports;
  423. // ImportRef instructions. Empty until the File is fully checked; intermediate
  424. // state is in the Check::Context.
  425. static const InstBlockId ImportRefs;
  426. // Global declaration initialization instructions. Empty if none are present.
  427. // Otherwise, __global_init function will be generated and this block will
  428. // be inserted into it.
  429. static const InstBlockId GlobalInit;
  430. // An ID with no value.
  431. static const InstBlockId None;
  432. // An ID for unreachable code.
  433. static const InstBlockId Unreachable;
  434. using IdBase::IdBase;
  435. auto Print(llvm::raw_ostream& out) const -> void;
  436. };
  437. constexpr InstBlockId InstBlockId::Empty = InstBlockId(0);
  438. constexpr InstBlockId InstBlockId::Exports = InstBlockId(1);
  439. constexpr InstBlockId InstBlockId::ImportRefs = InstBlockId(2);
  440. constexpr InstBlockId InstBlockId::GlobalInit = InstBlockId(3);
  441. constexpr InstBlockId InstBlockId::None = InstBlockId(NoneIndex);
  442. constexpr InstBlockId InstBlockId::Unreachable = InstBlockId(NoneIndex - 1);
  443. // An ID of an instruction block that is referenced absolutely by an
  444. // instruction. This should only be used as the type of a field within a typed
  445. // instruction class. See AbsoluteInstId.
  446. class AbsoluteInstBlockId : public InstBlockId {
  447. public:
  448. // Support implicit conversion from InstBlockId so that InstBlockId and
  449. // AbsoluteInstBlockId have the same interface.
  450. // NOLINTNEXTLINE(google-explicit-constructor)
  451. constexpr AbsoluteInstBlockId(InstBlockId inst_block_id)
  452. : InstBlockId(inst_block_id) {}
  453. using InstBlockId::InstBlockId;
  454. };
  455. // An ID of an instruction block that is used as the declaration block within a
  456. // declaration instruction. This is a block that is nested within the
  457. // instruction, but doesn't contribute to its value. Such blocks are not
  458. // included in the fingerprint of the declaration. This should only be used as
  459. // the type of a field within a typed instruction class.
  460. class DeclInstBlockId : public InstBlockId {
  461. public:
  462. // Support implicit conversion from InstBlockId so that InstBlockId and
  463. // DeclInstBlockId have the same interface.
  464. // NOLINTNEXTLINE(google-explicit-constructor)
  465. constexpr DeclInstBlockId(InstBlockId inst_block_id)
  466. : InstBlockId(inst_block_id) {}
  467. using InstBlockId::InstBlockId;
  468. };
  469. // An ID of an instruction block that is used as a label in a branch instruction
  470. // or similar. This is a block that is not nested within the instruction, but
  471. // instead exists elsewhere in the enclosing executable region. This should
  472. // only be used as the type of a field within a typed instruction class.
  473. class LabelId : public InstBlockId {
  474. public:
  475. // Support implicit conversion from InstBlockId so that InstBlockId and
  476. // LabelId have the same interface.
  477. // NOLINTNEXTLINE(google-explicit-constructor)
  478. constexpr LabelId(InstBlockId inst_block_id) : InstBlockId(inst_block_id) {}
  479. using InstBlockId::InstBlockId;
  480. };
  481. // TODO: Move this out of sem_ir and into check, if we don't wind up using it
  482. // in the SemIR for expression patterns.
  483. struct ExprRegionId : public IdBase<ExprRegionId> {
  484. static constexpr llvm::StringLiteral Label = "region";
  485. using ValueType = ExprRegion;
  486. // An ID with no value.
  487. static const ExprRegionId None;
  488. using IdBase::IdBase;
  489. };
  490. constexpr ExprRegionId ExprRegionId::None = ExprRegionId(NoneIndex);
  491. // The ID of a struct type field block.
  492. struct StructTypeFieldsId : public IdBase<StructTypeFieldsId> {
  493. static constexpr llvm::StringLiteral Label = "struct_type_fields";
  494. // Types for BlockValueStore<StructTypeFieldsId>.
  495. using ElementType = StructTypeField;
  496. using ValueType = llvm::MutableArrayRef<StructTypeField>;
  497. // An ID with no value.
  498. static const StructTypeFieldsId None;
  499. // The canonical empty block, reused to avoid allocating empty vectors. Always
  500. // the 0-index block.
  501. static const StructTypeFieldsId Empty;
  502. using IdBase::IdBase;
  503. };
  504. constexpr StructTypeFieldsId StructTypeFieldsId::None =
  505. StructTypeFieldsId(NoneIndex);
  506. constexpr StructTypeFieldsId StructTypeFieldsId::Empty = StructTypeFieldsId(0);
  507. // The ID of a type.
  508. struct TypeId : public IdBase<TypeId> {
  509. static constexpr llvm::StringLiteral Label = "type";
  510. // `StringifyTypeExpr` is used for diagnostics. However, where possible, an
  511. // `InstId` describing how the type was written should be preferred, using
  512. // `InstIdAsType` or `TypeOfInstId` as the diagnostic argument type.
  513. using DiagnosticType = DiagnosticTypeInfo<std::string>;
  514. // An ID with no value.
  515. static const TypeId None;
  516. using IdBase::IdBase;
  517. // Returns the ID of the type corresponding to the constant `const_id`, which
  518. // must be of type `type`. As an exception, the type `Error` is of type
  519. // `Error`.
  520. static constexpr auto ForTypeConstant(ConstantId const_id) -> TypeId {
  521. return TypeId(const_id.index);
  522. }
  523. // Returns the constant ID that defines the type.
  524. auto AsConstantId() const -> ConstantId { return ConstantId(index); }
  525. auto Print(llvm::raw_ostream& out) const -> void;
  526. };
  527. constexpr TypeId TypeId::None = TypeId(NoneIndex);
  528. // The ID of a type block.
  529. struct TypeBlockId : public IdBase<TypeBlockId> {
  530. static constexpr llvm::StringLiteral Label = "type_block";
  531. // Types for BlockValueStore<TypeBlockId>.
  532. using ElementType = TypeId;
  533. using ValueType = llvm::MutableArrayRef<ElementType>;
  534. // An ID with no value.
  535. static const TypeBlockId None;
  536. // The canonical empty block, reused to avoid allocating empty vectors. Always
  537. // the 0-index block.
  538. static const TypeBlockId Empty;
  539. using IdBase::IdBase;
  540. };
  541. constexpr TypeBlockId TypeBlockId::None = TypeBlockId(NoneIndex);
  542. constexpr TypeBlockId TypeBlockId::Empty = TypeBlockId(0);
  543. // An index for element access, for structs, tuples, and classes.
  544. struct ElementIndex : public IndexBase<ElementIndex> {
  545. static constexpr llvm::StringLiteral Label = "element";
  546. using IndexBase::IndexBase;
  547. // An ID with no value.
  548. static const ElementIndex None;
  549. };
  550. constexpr ElementIndex ElementIndex::None = ElementIndex(NoneIndex);
  551. // The ID of a library name. This is either a string literal or `default`.
  552. struct LibraryNameId : public IdBase<LibraryNameId> {
  553. static constexpr llvm::StringLiteral Label = "library_name";
  554. using DiagnosticType = DiagnosticTypeInfo<std::string>;
  555. // An ID with no value.
  556. static const LibraryNameId None;
  557. // The name of `default`.
  558. static const LibraryNameId Default;
  559. // Track cases where the library name was set, but has been diagnosed and
  560. // shouldn't be used anymore.
  561. static const LibraryNameId Error;
  562. // Returns the LibraryNameId for a library name as a string literal.
  563. static auto ForStringLiteralValueId(StringLiteralValueId id) -> LibraryNameId;
  564. using IdBase::IdBase;
  565. // Converts a LibraryNameId back to a string literal.
  566. auto AsStringLiteralValueId() const -> StringLiteralValueId {
  567. CARBON_CHECK(index >= NoneIndex, "{0} must be handled directly", *this);
  568. return StringLiteralValueId(index);
  569. }
  570. auto Print(llvm::raw_ostream& out) const -> void;
  571. };
  572. constexpr LibraryNameId LibraryNameId::None = LibraryNameId(NoneIndex);
  573. constexpr LibraryNameId LibraryNameId::Default = LibraryNameId(NoneIndex - 1);
  574. constexpr LibraryNameId LibraryNameId::Error = LibraryNameId(NoneIndex - 2);
  575. // The ID of an ImportIRInst.
  576. struct ImportIRInstId : public IdBase<ImportIRInstId> {
  577. static constexpr llvm::StringLiteral Label = "import_ir_inst";
  578. using ValueType = ImportIRInst;
  579. // An ID with no value.
  580. static const ImportIRInstId None;
  581. using IdBase::IdBase;
  582. };
  583. constexpr ImportIRInstId ImportIRInstId::None = ImportIRInstId(NoneIndex);
  584. // A SemIR location used as the location of instructions.
  585. //
  586. // Contents:
  587. // - index > None: A Parse::NodeId in the current IR.
  588. // - index < None: An ImportIRInstId.
  589. // - index == None: Can be used for either.
  590. struct LocId : public IdBase<LocId> {
  591. static constexpr llvm::StringLiteral Label = "loc";
  592. // This bit, if set for a node ID location, indicates a location for
  593. // operations performed implicitly.
  594. static const int32_t ImplicitBit = 1 << 30;
  595. // An ID with no value.
  596. static const LocId None;
  597. using IdBase::IdBase;
  598. // NOLINTNEXTLINE(google-explicit-constructor)
  599. constexpr LocId(Parse::NoneNodeId /*none*/) : IdBase(NoneIndex) {}
  600. // NOLINTNEXTLINE(google-explicit-constructor)
  601. constexpr LocId(Parse::NodeId node_id) : IdBase(node_id.index) {
  602. CARBON_CHECK(node_id.has_value() == has_value());
  603. CARBON_CHECK(!is_implicit());
  604. }
  605. // NOLINTNEXTLINE(google-explicit-constructor)
  606. constexpr LocId(ImportIRInstId inst_id)
  607. : IdBase(NoneIndex + ImportIRInstId::NoneIndex - inst_id.index) {
  608. CARBON_CHECK(inst_id.has_value() == has_value());
  609. CARBON_CHECK(index & ImplicitBit);
  610. }
  611. // Forms an equivalent LocId for an implicit location.
  612. auto ToImplicit() const -> LocId {
  613. // For import IR locations and the `None` location, the implicit bit is
  614. // always set, so this is a no-op.
  615. return LocId(index | ImplicitBit);
  616. }
  617. auto is_node_id() const -> bool { return index > NoneIndex; }
  618. auto is_import_ir_inst_id() const -> bool { return index < NoneIndex; }
  619. auto is_implicit() const -> bool {
  620. return is_node_id() && (index & ImplicitBit) != 0;
  621. }
  622. // This is allowed to return `NodeId::None`, but should never be used for
  623. // `InstId` other than `InstId::None`.
  624. auto node_id() const -> Parse::NodeId {
  625. if (!has_value()) {
  626. return Parse::NodeId::None;
  627. }
  628. CARBON_CHECK(is_node_id());
  629. return Parse::NodeId(index & ~ImplicitBit);
  630. }
  631. // This is allowed to return `InstId::None`, but should never be used for
  632. // `NodeId` other than `NodeId::None`.
  633. auto import_ir_inst_id() const -> ImportIRInstId {
  634. CARBON_CHECK(is_import_ir_inst_id() || !has_value());
  635. return ImportIRInstId(NoneIndex + ImportIRInstId::NoneIndex - index);
  636. }
  637. auto Print(llvm::raw_ostream& out) const -> void;
  638. };
  639. constexpr LocId LocId::None = LocId(Parse::NodeId::None);
  640. // Polymorphic id for fields in `Any[...]` typed instruction category. Used for
  641. // fields where the specific instruction structs have different field types in
  642. // that position or do not have a field in that position at all. Allows
  643. // conversion with `Inst::As<>` from the specific typed instruction to the
  644. // `Any[...]` instruction category.
  645. //
  646. // This type participates in `Inst::FromRaw` in order to convert from specific
  647. // instructions to an `Any[...]` instruction category:
  648. // - In the case the specific instruction has a field of some `IdKind` in the
  649. // same position, the `Any[...]` type will hold its raw value in the
  650. // `AnyRawId` field.
  651. // - In the case the specific instruction has no field in the same position, the
  652. // `Any[...]` type will hold a default constructed `AnyRawId` with a `None`
  653. // value.
  654. struct AnyRawId : public AnyIdBase {
  655. // For IdKind.
  656. static constexpr llvm::StringLiteral Label = "any_raw";
  657. constexpr explicit AnyRawId() : AnyIdBase(AnyIdBase::NoneIndex) {}
  658. constexpr explicit AnyRawId(int32_t id) : AnyIdBase(id) {}
  659. };
  660. } // namespace Carbon::SemIR
  661. #endif // CARBON_TOOLCHAIN_SEM_IR_IDS_H_