ids.h 26 KB

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