ids.h 29 KB

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