ids.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  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 EntityName;
  18. struct Class;
  19. struct FacetTypeInfo;
  20. struct Function;
  21. struct Generic;
  22. struct Specific;
  23. struct ImportIR;
  24. struct ImportIRInst;
  25. struct Impl;
  26. struct Interface;
  27. struct StructTypeField;
  28. struct ExprRegion;
  29. struct TypeInfo;
  30. // The ID of an instruction.
  31. struct InstId : public IdBase<InstId> {
  32. static constexpr llvm::StringLiteral Label = "inst";
  33. using ValueType = Inst;
  34. // An explicitly invalid ID.
  35. static const InstId Invalid;
  36. // Represents that the name in this scope was poisoned by using it without
  37. // qualifications.
  38. static const InstId PoisonedName;
  39. using IdBase::IdBase;
  40. constexpr auto is_poisoned() const -> bool { return *this == PoisonedName; }
  41. auto Print(llvm::raw_ostream& out) const -> void;
  42. };
  43. constexpr InstId InstId::Invalid = InstId(InvalidIndex);
  44. constexpr InstId InstId::PoisonedName = InstId(InvalidIndex - 1);
  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 explicitly invalid ID.
  79. static const ConstantId Invalid;
  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 is_valid.
  93. auto is_constant() const -> bool {
  94. CARBON_DCHECK(is_valid());
  95. return *this != ConstantId::NotConstant;
  96. }
  97. // Returns whether this represents a symbolic constant. Requires is_valid.
  98. auto is_symbolic() const -> bool {
  99. CARBON_DCHECK(is_valid());
  100. return index <= FirstSymbolicIndex;
  101. }
  102. // Returns whether this represents a template constant. Requires is_valid.
  103. auto is_template() const -> bool {
  104. CARBON_DCHECK(is_valid());
  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 = InvalidIndex - 1;
  131. static constexpr int32_t FirstSymbolicIndex = InvalidIndex - 2;
  132. };
  133. constexpr ConstantId ConstantId::NotConstant = ConstantId(NotConstantIndex);
  134. constexpr ConstantId ConstantId::Invalid = ConstantId(InvalidIndex);
  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 explicitly invalid ID.
  140. static const EntityNameId Invalid;
  141. using IdBase::IdBase;
  142. };
  143. constexpr EntityNameId EntityNameId::Invalid = EntityNameId(InvalidIndex);
  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 explicitly invalid index.
  150. static const CompileTimeBindIndex Invalid;
  151. using IndexBase::IndexBase;
  152. };
  153. constexpr CompileTimeBindIndex CompileTimeBindIndex::Invalid =
  154. CompileTimeBindIndex(InvalidIndex);
  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 explicitly invalid index.
  165. static const RuntimeParamIndex Invalid;
  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::Invalid =
  172. RuntimeParamIndex(InvalidIndex);
  173. constexpr RuntimeParamIndex RuntimeParamIndex::Unknown =
  174. RuntimeParamIndex(InvalidIndex - 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 explicitly invalid ID.
  180. static const FunctionId Invalid;
  181. using IdBase::IdBase;
  182. };
  183. constexpr FunctionId FunctionId::Invalid = FunctionId(InvalidIndex);
  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 explicitly invalid ID.
  195. static const ClassId Invalid;
  196. using IdBase::IdBase;
  197. };
  198. constexpr ClassId ClassId::Invalid = ClassId(InvalidIndex);
  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 explicitly invalid ID.
  204. static const InterfaceId Invalid;
  205. using IdBase::IdBase;
  206. };
  207. constexpr InterfaceId InterfaceId::Invalid = InterfaceId(InvalidIndex);
  208. // The ID of an faceet type value.
  209. struct FacetTypeId : public IdBase<FacetTypeId> {
  210. static constexpr llvm::StringLiteral Label = "facet_type";
  211. using ValueType = FacetTypeInfo;
  212. // An explicitly invalid ID.
  213. static const FacetTypeId Invalid;
  214. using IdBase::IdBase;
  215. };
  216. constexpr FacetTypeId FacetTypeId::Invalid = FacetTypeId(InvalidIndex);
  217. // The ID of an impl.
  218. struct ImplId : public IdBase<ImplId> {
  219. static constexpr llvm::StringLiteral Label = "impl";
  220. using ValueType = Impl;
  221. // An explicitly invalid ID.
  222. static const ImplId Invalid;
  223. using IdBase::IdBase;
  224. };
  225. constexpr ImplId ImplId::Invalid = ImplId(InvalidIndex);
  226. // The ID of a generic.
  227. struct GenericId : public IdBase<GenericId> {
  228. static constexpr llvm::StringLiteral Label = "generic";
  229. using ValueType = Generic;
  230. // An explicitly invalid ID.
  231. static const GenericId Invalid;
  232. using IdBase::IdBase;
  233. };
  234. constexpr GenericId GenericId::Invalid = GenericId(InvalidIndex);
  235. // The ID of a specific, which is the result of specifying the generic arguments
  236. // for a generic.
  237. struct SpecificId : public IdBase<SpecificId> {
  238. static constexpr llvm::StringLiteral Label = "specific";
  239. using ValueType = Specific;
  240. // An explicitly invalid ID. This is typically used to represent a non-generic
  241. // entity.
  242. static const SpecificId Invalid;
  243. using IdBase::IdBase;
  244. };
  245. constexpr SpecificId SpecificId::Invalid = SpecificId(InvalidIndex);
  246. // The index of an instruction that depends on generic parameters within a
  247. // region of a generic. A corresponding specific version of the instruction can
  248. // be found in each specific corresponding to that generic. This is a pair of a
  249. // region and an index, stored in 32 bits.
  250. struct GenericInstIndex : public IndexBase<GenericInstIndex> {
  251. // Where the value is first used within the generic.
  252. enum Region : uint8_t {
  253. // In the declaration.
  254. Declaration,
  255. // In the definition.
  256. Definition,
  257. };
  258. // An explicitly invalid index.
  259. static const GenericInstIndex Invalid;
  260. explicit constexpr GenericInstIndex(Region region, int32_t index)
  261. : IndexBase(region == Declaration ? index
  262. : FirstDefinitionIndex - index) {
  263. CARBON_CHECK(index >= 0);
  264. }
  265. // Returns the index of the instruction within the region.
  266. auto index() const -> int32_t {
  267. CARBON_CHECK(is_valid());
  268. return IndexBase::index >= 0 ? IndexBase::index
  269. : FirstDefinitionIndex - IndexBase::index;
  270. }
  271. // Returns the region within which this instruction was first used.
  272. auto region() const -> Region {
  273. CARBON_CHECK(is_valid());
  274. return IndexBase::index >= 0 ? Declaration : Definition;
  275. }
  276. auto Print(llvm::raw_ostream& out) const -> void;
  277. private:
  278. static constexpr auto MakeInvalid() -> GenericInstIndex {
  279. GenericInstIndex result(Declaration, 0);
  280. result.IndexBase::index = InvalidIndex;
  281. return result;
  282. }
  283. static constexpr int32_t FirstDefinitionIndex = InvalidIndex - 1;
  284. };
  285. constexpr GenericInstIndex GenericInstIndex::Invalid =
  286. GenericInstIndex::MakeInvalid();
  287. // The ID of an IR within the set of imported IRs, both direct and indirect.
  288. struct ImportIRId : public IdBase<ImportIRId> {
  289. static constexpr llvm::StringLiteral Label = "ir";
  290. using ValueType = ImportIR;
  291. // An explicitly invalid ID.
  292. static const ImportIRId Invalid;
  293. // The implicit `api` import, for an `impl` file. A null entry is added if
  294. // there is none, as in an `api`, in which case this ID should not show up in
  295. // instructions.
  296. static const ImportIRId ApiForImpl;
  297. using IdBase::IdBase;
  298. };
  299. constexpr ImportIRId ImportIRId::Invalid = ImportIRId(InvalidIndex);
  300. constexpr ImportIRId ImportIRId::ApiForImpl = ImportIRId(0);
  301. // A boolean value.
  302. struct BoolValue : public IdBase<BoolValue> {
  303. // Not used by `Print`, but for `IdKind`.
  304. static constexpr llvm::StringLiteral Label = "bool";
  305. static const BoolValue False;
  306. static const BoolValue True;
  307. // Returns the `BoolValue` corresponding to `b`.
  308. static constexpr auto From(bool b) -> BoolValue { return b ? True : False; }
  309. // Returns the `bool` corresponding to this `BoolValue`.
  310. constexpr auto ToBool() -> bool {
  311. CARBON_CHECK(*this == False || *this == True, "Invalid bool value {0}",
  312. index);
  313. return *this != False;
  314. }
  315. using IdBase::IdBase;
  316. auto Print(llvm::raw_ostream& out) const -> void;
  317. };
  318. constexpr BoolValue BoolValue::False = BoolValue(0);
  319. constexpr BoolValue BoolValue::True = BoolValue(1);
  320. // An integer kind value -- either "signed" or "unsigned".
  321. //
  322. // This might eventually capture any other properties of an integer type that
  323. // affect its semantics, such as overflow behavior.
  324. struct IntKind : public IdBase<IntKind> {
  325. // Not used by `Print`, but for `IdKind`.
  326. static constexpr llvm::StringLiteral Label = "int_kind";
  327. static const IntKind Unsigned;
  328. static const IntKind Signed;
  329. using IdBase::IdBase;
  330. // Returns whether this type is signed.
  331. constexpr auto is_signed() -> bool { return *this == Signed; }
  332. auto Print(llvm::raw_ostream& out) const -> void;
  333. };
  334. constexpr IntKind IntKind::Unsigned = IntKind(0);
  335. constexpr IntKind IntKind::Signed = IntKind(1);
  336. // A float kind value.
  337. struct FloatKind : public IdBase<FloatKind> {
  338. // Not used by `Print`, but for `IdKind`.
  339. static constexpr llvm::StringLiteral Label = "float_kind";
  340. using IdBase::IdBase;
  341. auto Print(llvm::raw_ostream& out) const -> void { out << "float"; }
  342. };
  343. // The ID of a name. A name is either a string or a special name such as
  344. // `self`, `Self`, or `base`.
  345. struct NameId : public IdBase<NameId> {
  346. static constexpr llvm::StringLiteral Label = "name";
  347. // names().GetFormatted() is used for diagnostics.
  348. using DiagnosticType = DiagnosticTypeInfo<std::string>;
  349. // An explicitly invalid ID.
  350. static const NameId Invalid;
  351. // The name of `self`.
  352. static const NameId SelfValue;
  353. // The name of `Self`.
  354. static const NameId SelfType;
  355. // The name of `.Self`.
  356. static const NameId PeriodSelf;
  357. // The name of the return slot in a function.
  358. static const NameId ReturnSlot;
  359. // The name of `package`.
  360. static const NameId PackageNamespace;
  361. // The name of `base`.
  362. static const NameId Base;
  363. // The name of `vptr`.
  364. static const NameId Vptr;
  365. // The number of non-index (<0) that exist, and will need storage in name
  366. // lookup.
  367. static const int NonIndexValueCount;
  368. // Returns the NameId corresponding to a particular IdentifierId.
  369. static auto ForIdentifier(IdentifierId id) -> NameId;
  370. using IdBase::IdBase;
  371. // Returns the IdentifierId corresponding to this NameId, or an invalid
  372. // IdentifierId if this is a special name.
  373. auto AsIdentifierId() const -> IdentifierId {
  374. return index >= 0 ? IdentifierId(index) : IdentifierId::Invalid;
  375. }
  376. auto Print(llvm::raw_ostream& out) const -> void;
  377. };
  378. constexpr NameId NameId::Invalid = NameId(InvalidIndex);
  379. constexpr NameId NameId::SelfValue = NameId(InvalidIndex - 1);
  380. constexpr NameId NameId::SelfType = NameId(InvalidIndex - 2);
  381. constexpr NameId NameId::PeriodSelf = NameId(InvalidIndex - 3);
  382. constexpr NameId NameId::ReturnSlot = NameId(InvalidIndex - 4);
  383. constexpr NameId NameId::PackageNamespace = NameId(InvalidIndex - 5);
  384. constexpr NameId NameId::Base = NameId(InvalidIndex - 6);
  385. constexpr NameId NameId::Vptr = NameId(InvalidIndex - 7);
  386. constexpr int NameId::NonIndexValueCount = 8;
  387. // Enforce the link between SpecialValueCount and the last special value.
  388. static_assert(NameId::NonIndexValueCount == -NameId::Vptr.index);
  389. // The ID of a name scope.
  390. struct NameScopeId : public IdBase<NameScopeId> {
  391. static constexpr llvm::StringLiteral Label = "name_scope";
  392. using ValueType = NameScope;
  393. // An explicitly invalid ID.
  394. static const NameScopeId Invalid;
  395. // The package (or file) name scope, guaranteed to be the first added.
  396. static const NameScopeId Package;
  397. using IdBase::IdBase;
  398. };
  399. constexpr NameScopeId NameScopeId::Invalid = NameScopeId(InvalidIndex);
  400. constexpr NameScopeId NameScopeId::Package = NameScopeId(0);
  401. // The ID of an instruction block.
  402. struct InstBlockId : public IdBase<InstBlockId> {
  403. static constexpr llvm::StringLiteral Label = "inst_block";
  404. // Types for BlockValueStore<InstBlockId>.
  405. using ElementType = InstId;
  406. using ValueType = llvm::MutableArrayRef<ElementType>;
  407. // The canonical empty block, reused to avoid allocating empty vectors. Always
  408. // the 0-index block.
  409. static const InstBlockId Empty;
  410. // Exported instructions. Empty until the File is fully checked; intermediate
  411. // state is in the Check::Context.
  412. static const InstBlockId Exports;
  413. // ImportRef instructions. Empty until the File is fully checked; intermediate
  414. // state is in the Check::Context.
  415. static const InstBlockId ImportRefs;
  416. // Global declaration initialization instructions. Empty if none are present.
  417. // Otherwise, __global_init function will be generated and this block will
  418. // be inserted into it.
  419. static const InstBlockId GlobalInit;
  420. // An explicitly invalid ID.
  421. static const InstBlockId Invalid;
  422. // An ID for unreachable code.
  423. static const InstBlockId Unreachable;
  424. using IdBase::IdBase;
  425. auto Print(llvm::raw_ostream& out) const -> void;
  426. };
  427. constexpr InstBlockId InstBlockId::Empty = InstBlockId(0);
  428. constexpr InstBlockId InstBlockId::Exports = InstBlockId(1);
  429. constexpr InstBlockId InstBlockId::ImportRefs = InstBlockId(2);
  430. constexpr InstBlockId InstBlockId::GlobalInit = InstBlockId(3);
  431. constexpr InstBlockId InstBlockId::Invalid = InstBlockId(InvalidIndex);
  432. constexpr InstBlockId InstBlockId::Unreachable = InstBlockId(InvalidIndex - 1);
  433. // TODO: Move this out of sem_ir and into check, if we don't wind up using it
  434. // in the SemIR for expression patterns.
  435. struct ExprRegionId : public IdBase<ExprRegionId> {
  436. static constexpr llvm::StringLiteral Label = "region";
  437. using ValueType = ExprRegion;
  438. // An explicitly invalid ID.
  439. static const ExprRegionId Invalid;
  440. using IdBase::IdBase;
  441. };
  442. constexpr ExprRegionId ExprRegionId::Invalid = ExprRegionId(InvalidIndex);
  443. // The ID of a struct type field block.
  444. struct StructTypeFieldsId : public IdBase<StructTypeFieldsId> {
  445. static constexpr llvm::StringLiteral Label = "struct_type_fields";
  446. // Types for BlockValueStore<StructTypeFieldsId>.
  447. using ElementType = StructTypeField;
  448. using ValueType = llvm::MutableArrayRef<StructTypeField>;
  449. // An explicitly invalid ID.
  450. static const StructTypeFieldsId Invalid;
  451. // The canonical empty block, reused to avoid allocating empty vectors. Always
  452. // the 0-index block.
  453. static const StructTypeFieldsId Empty;
  454. using IdBase::IdBase;
  455. };
  456. constexpr StructTypeFieldsId StructTypeFieldsId::Invalid =
  457. StructTypeFieldsId(InvalidIndex);
  458. constexpr StructTypeFieldsId StructTypeFieldsId::Empty = StructTypeFieldsId(0);
  459. // The ID of a type.
  460. struct TypeId : public IdBase<TypeId> {
  461. static constexpr llvm::StringLiteral Label = "type";
  462. // `StringifyTypeExpr` is used for diagnostics. However, where possible, an
  463. // `InstId` describing how the type was written should be preferred, using
  464. // `InstIdAsType` or `TypeOfInstId` as the diagnostic argument type.
  465. using DiagnosticType = DiagnosticTypeInfo<std::string>;
  466. // An explicitly invalid ID.
  467. static const TypeId Invalid;
  468. using IdBase::IdBase;
  469. // Returns the ID of the type corresponding to the constant `const_id`, which
  470. // must be of type `type`. As an exception, the type `Error` is of type
  471. // `Error`.
  472. static constexpr auto ForTypeConstant(ConstantId const_id) -> TypeId {
  473. return TypeId(const_id.index);
  474. }
  475. // Returns the constant ID that defines the type.
  476. auto AsConstantId() const -> ConstantId { return ConstantId(index); }
  477. auto Print(llvm::raw_ostream& out) const -> void;
  478. };
  479. constexpr TypeId TypeId::Invalid = TypeId(InvalidIndex);
  480. // The ID of a type block.
  481. struct TypeBlockId : public IdBase<TypeBlockId> {
  482. static constexpr llvm::StringLiteral Label = "type_block";
  483. // Types for BlockValueStore<TypeBlockId>.
  484. using ElementType = TypeId;
  485. using ValueType = llvm::MutableArrayRef<ElementType>;
  486. // An explicitly invalid ID.
  487. static const TypeBlockId Invalid;
  488. // The canonical empty block, reused to avoid allocating empty vectors. Always
  489. // the 0-index block.
  490. static const TypeBlockId Empty;
  491. using IdBase::IdBase;
  492. };
  493. constexpr TypeBlockId TypeBlockId::Invalid = TypeBlockId(InvalidIndex);
  494. constexpr TypeBlockId TypeBlockId::Empty = TypeBlockId(0);
  495. // An index for element access, for structs, tuples, and classes.
  496. struct ElementIndex : public IndexBase<ElementIndex> {
  497. static constexpr llvm::StringLiteral Label = "element";
  498. using IndexBase::IndexBase;
  499. // An explicitly invalid ID.
  500. static const ElementIndex Invalid;
  501. };
  502. constexpr ElementIndex ElementIndex::Invalid = ElementIndex(InvalidIndex);
  503. // The ID of a library name. This is either a string literal or `default`.
  504. struct LibraryNameId : public IdBase<LibraryNameId> {
  505. static constexpr llvm::StringLiteral Label = "library_name";
  506. using DiagnosticType = DiagnosticTypeInfo<std::string>;
  507. // An explicitly invalid ID.
  508. static const LibraryNameId Invalid;
  509. // The name of `default`.
  510. static const LibraryNameId Default;
  511. // Track cases where the library name was set, but has been diagnosed and
  512. // shouldn't be used anymore.
  513. static const LibraryNameId Error;
  514. // Returns the LibraryNameId for a library name as a string literal.
  515. static auto ForStringLiteralValueId(StringLiteralValueId id) -> LibraryNameId;
  516. using IdBase::IdBase;
  517. // Converts a LibraryNameId back to a string literal.
  518. auto AsStringLiteralValueId() const -> StringLiteralValueId {
  519. CARBON_CHECK(index >= InvalidIndex, "{0} must be handled directly", *this);
  520. return StringLiteralValueId(index);
  521. }
  522. auto Print(llvm::raw_ostream& out) const -> void;
  523. };
  524. constexpr LibraryNameId LibraryNameId::Invalid = LibraryNameId(InvalidIndex);
  525. constexpr LibraryNameId LibraryNameId::Default =
  526. LibraryNameId(InvalidIndex - 1);
  527. constexpr LibraryNameId LibraryNameId::Error = LibraryNameId(InvalidIndex - 2);
  528. // The ID of an ImportIRInst.
  529. struct ImportIRInstId : public IdBase<ImportIRInstId> {
  530. static constexpr llvm::StringLiteral Label = "import_ir_inst";
  531. using ValueType = ImportIRInst;
  532. // An explicitly invalid ID.
  533. static const ImportIRInstId Invalid;
  534. using IdBase::IdBase;
  535. };
  536. constexpr ImportIRInstId ImportIRInstId::Invalid = ImportIRInstId(InvalidIndex);
  537. // A SemIR location used as the location of instructions.
  538. //
  539. // Contents:
  540. // - index > Invalid: A Parse::NodeId in the current IR.
  541. // - index < Invalid: An ImportIRInstId.
  542. // - index == Invalid: Can be used for either.
  543. struct LocId : public IdBase<LocId> {
  544. static constexpr llvm::StringLiteral Label = "loc";
  545. // This bit, if set for a node ID location, indicates a location for
  546. // operations performed implicitly.
  547. static const int32_t ImplicitBit = 1 << 30;
  548. // An explicitly invalid ID.
  549. static const LocId Invalid;
  550. using IdBase::IdBase;
  551. // NOLINTNEXTLINE(google-explicit-constructor)
  552. constexpr LocId(Parse::InvalidNodeId /*invalid*/) : IdBase(InvalidIndex) {}
  553. // NOLINTNEXTLINE(google-explicit-constructor)
  554. constexpr LocId(Parse::NodeId node_id) : IdBase(node_id.index) {
  555. CARBON_CHECK(node_id.is_valid() == is_valid());
  556. CARBON_CHECK(!is_implicit());
  557. }
  558. // NOLINTNEXTLINE(google-explicit-constructor)
  559. constexpr LocId(ImportIRInstId inst_id)
  560. : IdBase(InvalidIndex + ImportIRInstId::InvalidIndex - inst_id.index) {
  561. CARBON_CHECK(inst_id.is_valid() == is_valid());
  562. CARBON_CHECK(index & ImplicitBit);
  563. }
  564. // Forms an equivalent LocId for an implicit location.
  565. auto ToImplicit() const -> LocId {
  566. // For import IR locations and the invalid location, the implicit bit is
  567. // always set, so this is a no-op.
  568. return LocId(index | ImplicitBit);
  569. }
  570. auto is_node_id() const -> bool { return index > InvalidIndex; }
  571. auto is_import_ir_inst_id() const -> bool { return index < InvalidIndex; }
  572. auto is_implicit() const -> bool {
  573. return is_node_id() && (index & ImplicitBit) != 0;
  574. }
  575. // This is allowed to return an invalid NodeId, but should never be used for a
  576. // valid InstId.
  577. auto node_id() const -> Parse::NodeId {
  578. if (!is_valid()) {
  579. return Parse::NodeId::Invalid;
  580. }
  581. CARBON_CHECK(is_node_id());
  582. return Parse::NodeId(index & ~ImplicitBit);
  583. }
  584. // This is allowed to return an invalid InstId, but should never be used for a
  585. // valid NodeId.
  586. auto import_ir_inst_id() const -> ImportIRInstId {
  587. CARBON_CHECK(is_import_ir_inst_id() || !is_valid());
  588. return ImportIRInstId(InvalidIndex + ImportIRInstId::InvalidIndex - index);
  589. }
  590. auto Print(llvm::raw_ostream& out) const -> void;
  591. };
  592. constexpr LocId LocId::Invalid = LocId(Parse::NodeId::Invalid);
  593. // Polymorphic id for fields in `Any[...]` typed instruction category. Used for
  594. // fields where the specific instruction structs have different field types in
  595. // that position or do not have a field in that position at all. Allows
  596. // conversion with `Inst::As<>` from the specific typed instruction to the
  597. // `Any[...]` instruction category.
  598. //
  599. // This type participates in `Inst::FromRaw` in order to convert from specific
  600. // instructions to an `Any[...]` instruction category:
  601. // - In the case the specific instruction has a field of some `IdKind` in the
  602. // same position, the `Any[...]` type will hold its raw value in the
  603. // `AnyRawId` field.
  604. // - In the case the specific instruction has no field in the same position, the
  605. // `Any[...]` type will hold a default constructed `AnyRawId` with an invalid
  606. // value.
  607. struct AnyRawId : public AnyIdBase {
  608. // For IdKind.
  609. static constexpr llvm::StringLiteral Label = "any_raw";
  610. constexpr explicit AnyRawId() : AnyIdBase(AnyIdBase::InvalidIndex) {}
  611. constexpr explicit AnyRawId(int32_t id) : AnyIdBase(id) {}
  612. };
  613. } // namespace Carbon::SemIR
  614. #endif // CARBON_TOOLCHAIN_SEM_IR_IDS_H_