ids.h 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  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 <limits>
  7. #include "common/check.h"
  8. #include "common/ostream.h"
  9. #include "toolchain/base/index_base.h"
  10. #include "toolchain/base/value_ids.h"
  11. #include "toolchain/diagnostics/diagnostic_emitter.h"
  12. #include "toolchain/parse/node_ids.h"
  13. // NOLINTNEXTLINE(readability-identifier-naming)
  14. namespace clang {
  15. // Forward declare indexed types, for integration with ValueStore.
  16. class SourceLocation;
  17. } // namespace clang
  18. namespace Carbon::SemIR {
  19. // Forward declare indexed types, for integration with ValueStore.
  20. class File;
  21. class ImportIRInst;
  22. class Inst;
  23. class NameScope;
  24. struct AssociatedConstant;
  25. struct Class;
  26. struct EntityName;
  27. struct ExprRegion;
  28. struct FacetTypeInfo;
  29. struct Function;
  30. struct Generic;
  31. struct IdentifiedFacetType;
  32. struct Specific;
  33. struct SpecificInterface;
  34. struct ImportCpp;
  35. struct ImportIR;
  36. struct Impl;
  37. struct Interface;
  38. struct StructTypeField;
  39. struct TypeInfo;
  40. // The ID of an instruction.
  41. struct InstId : public IdBase<InstId> {
  42. static constexpr llvm::StringLiteral Label = "inst";
  43. using ValueType = Inst;
  44. // The maximum ID, inclusive.
  45. static constexpr int Max = std::numeric_limits<int32_t>::max();
  46. // Represents the result of a name lookup that is temporarily disallowed
  47. // because the name is currently being initialized.
  48. static const InstId InitTombstone;
  49. using IdBase::IdBase;
  50. auto Print(llvm::raw_ostream& out) const -> void;
  51. };
  52. constexpr InstId InstId::InitTombstone = InstId(NoneIndex - 1);
  53. // And InstId whose value is a type. The fact it's a type is CHECKed on
  54. // construction, and this allows that check to be represented in the type
  55. // system.
  56. struct TypeInstId : public InstId {
  57. static const TypeInstId None;
  58. using InstId::InstId;
  59. static constexpr auto UnsafeMake(InstId id) -> TypeInstId {
  60. return TypeInstId(UnsafeCtor(), id);
  61. }
  62. private:
  63. struct UnsafeCtor {};
  64. explicit constexpr TypeInstId(UnsafeCtor /*unsafe*/, InstId id)
  65. : InstId(id) {}
  66. };
  67. constexpr TypeInstId TypeInstId::None = TypeInstId::UnsafeMake(InstId::None);
  68. // An ID of an instruction that is referenced absolutely by another instruction.
  69. // This should only be used as the type of a field within a typed instruction
  70. // class.
  71. //
  72. // When a typed instruction has a field of this type, that field represents an
  73. // absolute reference to another instruction that typically resides in a
  74. // different entity. This behaves in most respects like an InstId field, but
  75. // substitution into the typed instruction leaves the field unchanged rather
  76. // than substituting into it.
  77. class AbsoluteInstId : public InstId {
  78. public:
  79. // Support implicit conversion from InstId so that InstId and AbsoluteInstId
  80. // have the same interface.
  81. // NOLINTNEXTLINE(google-explicit-constructor)
  82. constexpr AbsoluteInstId(InstId inst_id) : InstId(inst_id) {}
  83. using InstId::InstId;
  84. };
  85. // An ID of an instruction that is used as the destination of an initializing
  86. // expression. This should only be used as the type of a field within a typed
  87. // instruction class.
  88. //
  89. // This behaves in most respects like an InstId field, but constant evaluation
  90. // of an instruction with a destination field will not evaluate this field, and
  91. // substitution will not substitute into it.
  92. //
  93. // TODO: Decide on how substitution should handle this. Multiple instructions
  94. // can refer to the same destination, so these don't have the tree structure
  95. // that substitution expects, but we might need to substitute into the result of
  96. // an instruction.
  97. class DestInstId : public InstId {
  98. public:
  99. // Support implicit conversion from InstId so that InstId and DestInstId
  100. // have the same interface.
  101. // NOLINTNEXTLINE(google-explicit-constructor)
  102. constexpr DestInstId(InstId inst_id) : InstId(inst_id) {}
  103. using InstId::InstId;
  104. };
  105. // An ID of an instruction that is referenced as a meta-operand of an action.
  106. // This should only be used as the type of a field within a typed instruction
  107. // class.
  108. //
  109. // This is used to model cases where an action's operand is not the value
  110. // produced by another instruction, but is the other instruction itself. This is
  111. // common for actions representing template instantiation.
  112. //
  113. // This behaves in most respects like an InstId field, but evaluation of the
  114. // instruction that has this field will not fail if the instruction does not
  115. // have a constant value. If the instruction has a constant value, it will still
  116. // be replaced by its constant value during evaluation like normal, but if it
  117. // has a non-constant value, the field is left unchanged by evaluation.
  118. class MetaInstId : public InstId {
  119. public:
  120. // Support implicit conversion from InstId so that InstId and MetaInstId
  121. // have the same interface.
  122. // NOLINTNEXTLINE(google-explicit-constructor)
  123. constexpr MetaInstId(InstId inst_id) : InstId(inst_id) {}
  124. using InstId::InstId;
  125. };
  126. // The ID of a constant value of an expression. An expression is either:
  127. //
  128. // - a concrete constant, whose value does not depend on any generic parameters,
  129. // such as `42` or `i32*` or `("hello", "world")`, or
  130. // - a symbolic constant, whose value includes a generic parameter, such as
  131. // `Vector(T*)`, or
  132. // - a runtime expression, such as `Print("hello")`.
  133. //
  134. // Concrete constants are a thin wrapper around the instruction ID of the
  135. // constant instruction that defines the constant. Symbolic constants are an
  136. // index into a separate table of `SymbolicConstant`s maintained by the constant
  137. // value store.
  138. struct ConstantId : public IdBase<ConstantId> {
  139. static constexpr llvm::StringLiteral Label = "constant";
  140. // An ID for an expression that is not constant.
  141. static const ConstantId NotConstant;
  142. // Returns the constant ID corresponding to a concrete constant, which should
  143. // either be in the `constants` block in the file or should be known to be
  144. // unique.
  145. static constexpr auto ForConcreteConstant(InstId const_id) -> ConstantId {
  146. return ConstantId(const_id.index);
  147. }
  148. // Returns the constant ID corresponding to a symbolic constant index.
  149. static constexpr auto ForSymbolicConstantIndex(int32_t symbolic_index)
  150. -> ConstantId {
  151. return ConstantId(FirstSymbolicIndex - symbolic_index);
  152. }
  153. using IdBase::IdBase;
  154. // Returns whether this represents a constant. Requires has_value.
  155. constexpr auto is_constant() const -> bool {
  156. CARBON_DCHECK(has_value());
  157. return *this != ConstantId::NotConstant;
  158. }
  159. // Returns whether this represents a symbolic constant. Requires has_value.
  160. constexpr auto is_symbolic() const -> bool {
  161. CARBON_DCHECK(has_value());
  162. return index <= FirstSymbolicIndex;
  163. }
  164. // Returns whether this represents a concrete constant. Requires has_value.
  165. constexpr auto is_concrete() const -> bool {
  166. CARBON_DCHECK(has_value());
  167. return index >= 0;
  168. }
  169. // Prints this ID to the given output stream. `disambiguate` indicates whether
  170. // concrete constants should be wrapped with "concrete_constant(...)" so that
  171. // they aren't printed the same as an InstId. This can be set to false if
  172. // there is no risk of ambiguity.
  173. auto Print(llvm::raw_ostream& out, bool disambiguate = true) const -> void;
  174. private:
  175. friend class ConstantValueStore;
  176. // TODO: C++23 makes std::abs constexpr, but until then we mirror std::abs
  177. // logic here. LLVM should still optimize this.
  178. static constexpr auto Abs(int32_t i) -> int32_t { return i > 0 ? i : -i; }
  179. // Returns the instruction that describes this concrete constant value.
  180. // Requires `is_concrete()`. Use `ConstantValueStore::GetInstId` to get the
  181. // instruction ID of a `ConstantId`.
  182. constexpr auto concrete_inst_id() const -> InstId {
  183. CARBON_DCHECK(is_concrete());
  184. return InstId(index);
  185. }
  186. // Returns the symbolic constant index that describes this symbolic constant
  187. // value. Requires `is_symbolic()`.
  188. constexpr auto symbolic_index() const -> int32_t {
  189. CARBON_DCHECK(is_symbolic());
  190. return FirstSymbolicIndex - index;
  191. }
  192. static constexpr int32_t NotConstantIndex = NoneIndex - 1;
  193. static constexpr int32_t FirstSymbolicIndex = NoneIndex - 2;
  194. };
  195. constexpr ConstantId ConstantId::NotConstant = ConstantId(NotConstantIndex);
  196. // The ID of a EntityName.
  197. struct EntityNameId : public IdBase<EntityNameId> {
  198. static constexpr llvm::StringLiteral Label = "entity_name";
  199. using ValueType = EntityName;
  200. using IdBase::IdBase;
  201. };
  202. // The index of a compile-time binding. This is the de Bruijn level for the
  203. // binding -- that is, this is the number of other compile time bindings whose
  204. // scope encloses this binding.
  205. struct CompileTimeBindIndex : public IndexBase<CompileTimeBindIndex> {
  206. static constexpr llvm::StringLiteral Label = "comp_time_bind";
  207. using IndexBase::IndexBase;
  208. };
  209. // The index of a `Call` parameter in a function. These are allocated
  210. // sequentially, left-to-right, to the function parameters that will have
  211. // arguments passed to them at runtime. In a `Call` instruction, a runtime
  212. // argument will have the position in the argument list corresponding to its
  213. // `Call` parameter index.
  214. struct CallParamIndex : public IndexBase<CallParamIndex> {
  215. static constexpr llvm::StringLiteral Label = "call_param";
  216. using IndexBase::IndexBase;
  217. };
  218. // The ID of a function.
  219. struct FunctionId : public IdBase<FunctionId> {
  220. static constexpr llvm::StringLiteral Label = "function";
  221. using ValueType = Function;
  222. using IdBase::IdBase;
  223. };
  224. // The ID of an IR within the set of all IRs being evaluated in the current
  225. // check execution.
  226. struct CheckIRId : public IdBase<CheckIRId> {
  227. static constexpr llvm::StringLiteral Label = "check_ir";
  228. // Used when referring to the imported C++.
  229. static const CheckIRId Cpp;
  230. using IdBase::IdBase;
  231. };
  232. constexpr CheckIRId CheckIRId::Cpp = CheckIRId(NoneIndex - 1);
  233. // The ID of a class.
  234. struct ClassId : public IdBase<ClassId> {
  235. static constexpr llvm::StringLiteral Label = "class";
  236. using ValueType = Class;
  237. using IdBase::IdBase;
  238. };
  239. // The ID of an interface.
  240. struct InterfaceId : public IdBase<InterfaceId> {
  241. static constexpr llvm::StringLiteral Label = "interface";
  242. using ValueType = Interface;
  243. using IdBase::IdBase;
  244. };
  245. // The ID of an associated constant.
  246. struct AssociatedConstantId : public IdBase<AssociatedConstantId> {
  247. static constexpr llvm::StringLiteral Label = "assoc_const";
  248. using ValueType = AssociatedConstant;
  249. using IdBase::IdBase;
  250. };
  251. // The ID of an facet type value.
  252. struct FacetTypeId : public IdBase<FacetTypeId> {
  253. static constexpr llvm::StringLiteral Label = "facet_type";
  254. using ValueType = FacetTypeInfo;
  255. using IdBase::IdBase;
  256. };
  257. // The ID of an resolved facet type value.
  258. struct IdentifiedFacetTypeId : public IdBase<IdentifiedFacetTypeId> {
  259. static constexpr llvm::StringLiteral Label = "identified_facet_type";
  260. using ValueType = IdentifiedFacetType;
  261. using IdBase::IdBase;
  262. };
  263. // The ID of an impl.
  264. struct ImplId : public IdBase<ImplId> {
  265. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  266. static constexpr llvm::StringLiteral Label = "impl";
  267. using ValueType = Impl;
  268. using IdBase::IdBase;
  269. };
  270. // The ID of a generic.
  271. struct GenericId : public IdBase<GenericId> {
  272. static constexpr llvm::StringLiteral Label = "generic";
  273. using ValueType = Generic;
  274. using IdBase::IdBase;
  275. };
  276. // The ID of a specific, which is the result of specifying the generic arguments
  277. // for a generic.
  278. struct SpecificId : public IdBase<SpecificId> {
  279. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  280. static constexpr llvm::StringLiteral Label = "specific";
  281. using ValueType = Specific;
  282. using IdBase::IdBase;
  283. };
  284. // The ID of a SpecificInterface, which is an interface and a specific pair.
  285. struct SpecificInterfaceId : public IdBase<SpecificInterfaceId> {
  286. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  287. static constexpr llvm::StringLiteral Label = "specific_interface";
  288. using ValueType = SpecificInterface;
  289. using IdBase::IdBase;
  290. };
  291. // The index of an instruction that depends on generic parameters within a
  292. // region of a generic. A corresponding specific version of the instruction can
  293. // be found in each specific corresponding to that generic. This is a pair of a
  294. // region and an index, stored in 32 bits.
  295. struct GenericInstIndex : public IndexBase<GenericInstIndex> {
  296. // Where the value is first used within the generic.
  297. enum Region : uint8_t {
  298. // In the declaration.
  299. Declaration,
  300. // In the definition.
  301. Definition,
  302. };
  303. // An index with no value.
  304. static const GenericInstIndex None;
  305. explicit constexpr GenericInstIndex(Region region, int32_t index)
  306. : IndexBase(region == Declaration ? index
  307. : FirstDefinitionIndex - index) {
  308. CARBON_CHECK(index >= 0);
  309. }
  310. // Returns the index of the instruction within the region.
  311. auto index() const -> int32_t {
  312. CARBON_CHECK(has_value());
  313. return IndexBase::index >= 0 ? IndexBase::index
  314. : FirstDefinitionIndex - IndexBase::index;
  315. }
  316. // Returns the region within which this instruction was first used.
  317. auto region() const -> Region {
  318. CARBON_CHECK(has_value());
  319. return IndexBase::index >= 0 ? Declaration : Definition;
  320. }
  321. auto Print(llvm::raw_ostream& out) const -> void;
  322. private:
  323. static constexpr auto MakeNone() -> GenericInstIndex {
  324. GenericInstIndex result(Declaration, 0);
  325. result.IndexBase::index = NoneIndex;
  326. return result;
  327. }
  328. static constexpr int32_t FirstDefinitionIndex = NoneIndex - 1;
  329. };
  330. constexpr GenericInstIndex GenericInstIndex::None =
  331. GenericInstIndex::MakeNone();
  332. struct ImportCppId : public IdBase<ImportCppId> {
  333. static constexpr llvm::StringLiteral Label = "import_cpp";
  334. using ValueType = ImportCpp;
  335. using IdBase::IdBase;
  336. };
  337. // The ID of an IR within the set of imported IRs, both direct and indirect.
  338. struct ImportIRId : public IdBase<ImportIRId> {
  339. static constexpr llvm::StringLiteral Label = "ir";
  340. using ValueType = ImportIR;
  341. // The implicit `api` import, for an `impl` file. A null entry is added if
  342. // there is none, as in an `api`, in which case this ID should not show up in
  343. // instructions.
  344. static const ImportIRId ApiForImpl;
  345. // The `Cpp` import. A null entry is added if there is none, in which case
  346. // this ID should not show up in instructions.
  347. static const ImportIRId Cpp;
  348. using IdBase::IdBase;
  349. };
  350. constexpr ImportIRId ImportIRId::ApiForImpl = ImportIRId(0);
  351. constexpr ImportIRId ImportIRId::Cpp = ImportIRId(ApiForImpl.index + 1);
  352. // A boolean value.
  353. struct BoolValue : public IdBase<BoolValue> {
  354. // Not used by `Print`, but for `IdKind`.
  355. static constexpr llvm::StringLiteral Label = "bool";
  356. static const BoolValue False;
  357. static const BoolValue True;
  358. // Returns the `BoolValue` corresponding to `b`.
  359. static constexpr auto From(bool b) -> BoolValue { return b ? True : False; }
  360. // Returns the `bool` corresponding to this `BoolValue`.
  361. constexpr auto ToBool() -> bool {
  362. CARBON_CHECK(*this == False || *this == True, "Invalid bool value {0}",
  363. index);
  364. return *this != False;
  365. }
  366. using IdBase::IdBase;
  367. auto Print(llvm::raw_ostream& out) const -> void;
  368. };
  369. constexpr BoolValue BoolValue::False = BoolValue(0);
  370. constexpr BoolValue BoolValue::True = BoolValue(1);
  371. // An integer kind value -- either "signed" or "unsigned".
  372. //
  373. // This might eventually capture any other properties of an integer type that
  374. // affect its semantics, such as overflow behavior.
  375. struct IntKind : public IdBase<IntKind> {
  376. // Not used by `Print`, but for `IdKind`.
  377. static constexpr llvm::StringLiteral Label = "int_kind";
  378. static const IntKind Unsigned;
  379. static const IntKind Signed;
  380. using IdBase::IdBase;
  381. // Returns whether this type is signed.
  382. constexpr auto is_signed() -> bool { return *this == Signed; }
  383. auto Print(llvm::raw_ostream& out) const -> void;
  384. };
  385. constexpr IntKind IntKind::Unsigned = IntKind(0);
  386. constexpr IntKind IntKind::Signed = IntKind(1);
  387. // A float kind value.
  388. struct FloatKind : public IdBase<FloatKind> {
  389. // Not used by `Print`, but for `IdKind`.
  390. static constexpr llvm::StringLiteral Label = "float_kind";
  391. using IdBase::IdBase;
  392. auto Print(llvm::raw_ostream& out) const -> void { out << "float"; }
  393. };
  394. // An X-macro for special names. Uses should look like:
  395. //
  396. // #define CARBON_SPECIAL_NAME_ID_FOR_XYZ(Name) ...
  397. // CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_XYZ)
  398. // #undef CARBON_SPECIAL_NAME_ID_FOR_XYZ
  399. #define CARBON_SPECIAL_NAME_ID(X) \
  400. /* The name of `base`. */ \
  401. X(Base) \
  402. /* The name of the discriminant field (if any) in a choice. */ \
  403. X(ChoiceDiscriminant) \
  404. /* The name of the package `Core`. */ \
  405. X(Core) \
  406. /* The name of `destroy`. */ \
  407. X(Destroy) \
  408. /* The name of `package`. */ \
  409. X(PackageNamespace) \
  410. /* The name of `.Self`. */ \
  411. X(PeriodSelf) \
  412. /* The name of the return slot in a function. */ \
  413. X(ReturnSlot) \
  414. /* The name of `Self`. */ \
  415. X(SelfType) \
  416. /* The name of `self`. */ \
  417. X(SelfValue) \
  418. /* The name of `_`. */ \
  419. X(Underscore) \
  420. /* The name of `vptr`. */ \
  421. X(Vptr)
  422. // The ID of a name. A name is either a string or a special name such as
  423. // `self`, `Self`, or `base`.
  424. struct NameId : public IdBase<NameId> {
  425. static constexpr llvm::StringLiteral Label = "name";
  426. // names().GetFormatted() is used for diagnostics.
  427. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  428. // An enum of special names.
  429. enum class SpecialNameId : uint8_t {
  430. #define CARBON_SPECIAL_NAME_ID_FOR_ENUM(Name) Name,
  431. CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_ENUM)
  432. #undef CARBON_SPECIAL_NAME_ID_FOR_ENUM
  433. };
  434. // For each SpecialNameId, provide a matching `NameId` instance for
  435. // convenience.
  436. #define CARBON_SPECIAL_NAME_ID_FOR_DECL(Name) static const NameId Name;
  437. CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_DECL)
  438. #undef CARBON_SPECIAL_NAME_ID_FOR_DECL
  439. // The number of non-index (<0) that exist, and will need storage in name
  440. // lookup.
  441. static const int NonIndexValueCount;
  442. // Returns the NameId corresponding to a particular IdentifierId.
  443. static auto ForIdentifier(IdentifierId id) -> NameId;
  444. // Returns the NameId corresponding to a particular PackageNameId. This is the
  445. // name that is declared when the package is imported.
  446. static auto ForPackageName(PackageNameId id) -> NameId;
  447. using IdBase::IdBase;
  448. // Returns the IdentifierId corresponding to this NameId, or `None` if this is
  449. // a special name.
  450. auto AsIdentifierId() const -> IdentifierId {
  451. return index >= 0 ? IdentifierId(index) : IdentifierId::None;
  452. }
  453. // Expose special names for `switch`.
  454. constexpr auto AsSpecialNameId() const -> std::optional<SpecialNameId> {
  455. if (index >= NoneIndex) {
  456. return std::nullopt;
  457. }
  458. return static_cast<SpecialNameId>(NoneIndex - 1 - index);
  459. }
  460. auto Print(llvm::raw_ostream& out) const -> void;
  461. };
  462. // Define the special `static const NameId` values.
  463. #define CARBON_SPECIAL_NAME_ID_FOR_DEF(Name) \
  464. constexpr NameId NameId::Name = \
  465. NameId(NoneIndex - 1 - static_cast<int>(NameId::SpecialNameId::Name));
  466. CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_DEF)
  467. #undef CARBON_SPECIAL_NAME_ID_FOR_DEF
  468. // Count non-index values, including `None` and special names.
  469. #define CARBON_SPECIAL_NAME_ID_FOR_COUNT(...) +1
  470. constexpr int NameId::NonIndexValueCount =
  471. 1 CARBON_SPECIAL_NAME_ID(CARBON_SPECIAL_NAME_ID_FOR_COUNT);
  472. #undef CARBON_SPECIAL_NAME_ID_FOR_COUNT
  473. // The ID of a name scope.
  474. struct NameScopeId : public IdBase<NameScopeId> {
  475. static constexpr llvm::StringLiteral Label = "name_scope";
  476. using ValueType = NameScope;
  477. // The package (or file) name scope, guaranteed to be the first added.
  478. static const NameScopeId Package;
  479. using IdBase::IdBase;
  480. };
  481. constexpr NameScopeId NameScopeId::Package = NameScopeId(0);
  482. // The ID of an instruction block.
  483. struct InstBlockId : public IdBase<InstBlockId> {
  484. static constexpr llvm::StringLiteral Label = "inst_block";
  485. // Types for BlockValueStore<InstBlockId>.
  486. using ElementType = InstId;
  487. using ValueType = llvm::MutableArrayRef<ElementType>;
  488. // The canonical empty block, reused to avoid allocating empty vectors. Always
  489. // the 0-index block.
  490. static const InstBlockId Empty;
  491. // Exported instructions. Empty until the File is fully checked; intermediate
  492. // state is in the Check::Context.
  493. static const InstBlockId Exports;
  494. // ImportRef instructions. Empty until the File is fully checked; intermediate
  495. // state is in the Check::Context.
  496. static const InstBlockId ImportRefs;
  497. // Global declaration initialization instructions. Empty if none are present.
  498. // Otherwise, __global_init function will be generated and this block will
  499. // be inserted into it.
  500. static const InstBlockId GlobalInit;
  501. // An ID for unreachable code.
  502. static const InstBlockId Unreachable;
  503. using IdBase::IdBase;
  504. auto Print(llvm::raw_ostream& out) const -> void;
  505. };
  506. constexpr InstBlockId InstBlockId::Empty = InstBlockId(0);
  507. constexpr InstBlockId InstBlockId::Exports = InstBlockId(1);
  508. constexpr InstBlockId InstBlockId::ImportRefs = InstBlockId(2);
  509. constexpr InstBlockId InstBlockId::GlobalInit = InstBlockId(3);
  510. constexpr InstBlockId InstBlockId::Unreachable = InstBlockId(NoneIndex - 1);
  511. // Contains either an `InstBlockId` value, an error value, or
  512. // `InstBlockId::None`.
  513. //
  514. // Error values are treated as values, though they are not representable as an
  515. // `InstBlockId` (unlike for the singleton error `InstId`).
  516. class InstBlockIdOrError {
  517. public:
  518. // NOLINTNEXTLINE(google-explicit-constructor)
  519. InstBlockIdOrError(InstBlockId inst_block_id)
  520. : InstBlockIdOrError(inst_block_id, false) {}
  521. static auto MakeError() -> InstBlockIdOrError {
  522. return {InstBlockId::None, true};
  523. }
  524. // Returns whether this class contains either an InstBlockId (other than
  525. // `None`) or an error.
  526. //
  527. // An error is treated as a value (as same for the singleton error `InstId`),
  528. // but it can not actually be materialized as an error value outside of this
  529. // class.
  530. auto has_value() const -> bool {
  531. return has_error_value() || inst_block_id_.has_value();
  532. }
  533. // Returns whether this class contains an error value.
  534. auto has_error_value() const -> bool { return error_; }
  535. // Returns the id of a non-empty inst block, or `None` if `has_value()` is
  536. // false.
  537. //
  538. // Only valid to call if `has_error_value()` is false.
  539. auto inst_block_id() const -> InstBlockId {
  540. CARBON_CHECK(!has_error_value());
  541. return inst_block_id_;
  542. }
  543. private:
  544. InstBlockIdOrError(InstBlockId inst_block_id, bool error)
  545. : inst_block_id_(inst_block_id), error_(error) {}
  546. InstBlockId inst_block_id_;
  547. bool error_;
  548. };
  549. // An ID of an instruction block that is referenced absolutely by an
  550. // instruction. This should only be used as the type of a field within a typed
  551. // instruction class. See AbsoluteInstId.
  552. class AbsoluteInstBlockId : public InstBlockId {
  553. public:
  554. // Support implicit conversion from InstBlockId so that InstBlockId and
  555. // AbsoluteInstBlockId have the same interface.
  556. // NOLINTNEXTLINE(google-explicit-constructor)
  557. constexpr AbsoluteInstBlockId(InstBlockId inst_block_id)
  558. : InstBlockId(inst_block_id) {}
  559. using InstBlockId::InstBlockId;
  560. };
  561. // An ID of an instruction block that is used as the declaration block within a
  562. // declaration instruction. This is a block that is nested within the
  563. // instruction, but doesn't contribute to its value. Such blocks are not
  564. // included in the fingerprint of the declaration. This should only be used as
  565. // the type of a field within a typed instruction class.
  566. class DeclInstBlockId : public InstBlockId {
  567. public:
  568. // Support implicit conversion from InstBlockId so that InstBlockId and
  569. // DeclInstBlockId have the same interface.
  570. // NOLINTNEXTLINE(google-explicit-constructor)
  571. constexpr DeclInstBlockId(InstBlockId inst_block_id)
  572. : InstBlockId(inst_block_id) {}
  573. using InstBlockId::InstBlockId;
  574. };
  575. // An ID of an instruction block that is used as a label in a branch instruction
  576. // or similar. This is a block that is not nested within the instruction, but
  577. // instead exists elsewhere in the enclosing executable region. This should
  578. // only be used as the type of a field within a typed instruction class.
  579. class LabelId : public InstBlockId {
  580. public:
  581. // Support implicit conversion from InstBlockId so that InstBlockId and
  582. // LabelId have the same interface.
  583. // NOLINTNEXTLINE(google-explicit-constructor)
  584. constexpr LabelId(InstBlockId inst_block_id) : InstBlockId(inst_block_id) {}
  585. using InstBlockId::InstBlockId;
  586. };
  587. // TODO: Move this out of sem_ir and into check, if we don't wind up using it
  588. // in the SemIR for expression patterns.
  589. struct ExprRegionId : public IdBase<ExprRegionId> {
  590. static constexpr llvm::StringLiteral Label = "region";
  591. using ValueType = ExprRegion;
  592. using IdBase::IdBase;
  593. };
  594. // The ID of a struct type field block.
  595. struct StructTypeFieldsId : public IdBase<StructTypeFieldsId> {
  596. static constexpr llvm::StringLiteral Label = "struct_type_fields";
  597. // Types for BlockValueStore<StructTypeFieldsId>.
  598. using ElementType = StructTypeField;
  599. using ValueType = llvm::MutableArrayRef<StructTypeField>;
  600. // The canonical empty block, reused to avoid allocating empty vectors. Always
  601. // the 0-index block.
  602. static const StructTypeFieldsId Empty;
  603. using IdBase::IdBase;
  604. };
  605. constexpr StructTypeFieldsId StructTypeFieldsId::Empty = StructTypeFieldsId(0);
  606. // The ID of a type.
  607. struct TypeId : public IdBase<TypeId> {
  608. static constexpr llvm::StringLiteral Label = "type";
  609. // `StringifyConstantInst` is used for diagnostics. However, where possible,
  610. // an `InstId` describing how the type was written should be preferred, using
  611. // `InstIdAsType` or `TypeOfInstId` as the diagnostic argument type.
  612. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  613. using IdBase::IdBase;
  614. // Returns the ID of the type corresponding to the constant `const_id`, which
  615. // must be of type `type`. As an exception, the type `Error` is of type
  616. // `Error`.
  617. static constexpr auto ForTypeConstant(ConstantId const_id) -> TypeId {
  618. return TypeId(const_id.index);
  619. }
  620. // Returns the constant ID that defines the type.
  621. auto AsConstantId() const -> ConstantId { return ConstantId(index); }
  622. // Returns whether this represents a symbolic type. Requires has_value.
  623. auto is_symbolic() const -> bool { return AsConstantId().is_symbolic(); }
  624. // Returns whether this represents a concrete type. Requires has_value.
  625. auto is_concrete() const -> bool { return AsConstantId().is_concrete(); }
  626. auto Print(llvm::raw_ostream& out) const -> void;
  627. };
  628. // The ID of a Clang Source Location.
  629. struct ClangSourceLocId : public IdBase<ClangSourceLocId> {
  630. static constexpr llvm::StringLiteral Label = "clang_source_loc";
  631. using ValueType = clang::SourceLocation;
  632. using IdBase::IdBase;
  633. };
  634. // An index for element access, for structs, tuples, and classes.
  635. struct ElementIndex : public IndexBase<ElementIndex> {
  636. static constexpr llvm::StringLiteral Label = "element";
  637. using IndexBase::IndexBase;
  638. };
  639. // The ID of a library name. This is either a string literal or `default`.
  640. struct LibraryNameId : public IdBase<LibraryNameId> {
  641. static constexpr llvm::StringLiteral Label = "library_name";
  642. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  643. // The name of `default`.
  644. static const LibraryNameId Default;
  645. // Track cases where the library name was set, but has been diagnosed and
  646. // shouldn't be used anymore.
  647. static const LibraryNameId Error;
  648. // Returns the LibraryNameId for a library name as a string literal.
  649. static auto ForStringLiteralValueId(StringLiteralValueId id) -> LibraryNameId;
  650. using IdBase::IdBase;
  651. // Converts a LibraryNameId back to a string literal.
  652. auto AsStringLiteralValueId() const -> StringLiteralValueId {
  653. CARBON_CHECK(index >= NoneIndex, "{0} must be handled directly", *this);
  654. return StringLiteralValueId(index);
  655. }
  656. auto Print(llvm::raw_ostream& out) const -> void;
  657. };
  658. constexpr LibraryNameId LibraryNameId::Default = LibraryNameId(NoneIndex - 1);
  659. constexpr LibraryNameId LibraryNameId::Error = LibraryNameId(NoneIndex - 2);
  660. // The ID of an ImportIRInst.
  661. struct ImportIRInstId : public IdBase<ImportIRInstId> {
  662. static constexpr llvm::StringLiteral Label = "import_ir_inst";
  663. using ValueType = ImportIRInst;
  664. // ImportIRInstId is restricted so that it can fit into LocId.
  665. static constexpr int32_t BitsWithNodeId = 29;
  666. // The maximum ID, non-inclusive.
  667. static constexpr int Max = (1 << BitsWithNodeId) - Parse::NodeId::Max - 2;
  668. constexpr explicit ImportIRInstId(int32_t index) : IdBase(index) {
  669. CARBON_DCHECK(index < Max, "Index out of range: {0}", index);
  670. }
  671. };
  672. // A SemIR location used as the location of instructions. This contains either a
  673. // InstId, NodeId, ImportIRInstId, or None. The intent is that any of these can
  674. // indicate the source of an instruction, and also be used to associate a line
  675. // in diagnostics.
  676. //
  677. // The structure is:
  678. // - None: The standard NoneIndex for all Id types, -1.
  679. // - InstId: positive values including zero; a full 31 bits.
  680. // - [0, 1 << 31)
  681. // - NodeId: negative values starting after None; the 24 bit NodeId range.
  682. // - [-2, -2 - (1 << 24))
  683. // - ImportIRInstId: remaining negative values; after NodeId, fills out negative
  684. // values to 29 bits.
  685. // - [-2 - (1 << 24), -(1 << 29))
  686. //
  687. // In addition, two bits are used for flags: `ImplicitBit` and `TokenOnlyBit`.
  688. // Note that these can only be used with negative, non-`InstId` values.
  689. //
  690. // Use `InstStore::GetCanonicalLocId()` to get a canonical `LocId` which will
  691. // not be backed by an `InstId`. Note that the canonical `LocId` may be `None`
  692. // even when the original `LocId` was not, so this operation needs to be done
  693. // before checking `has_value()`. Only canonical locations can be converted with
  694. // `ToImplicit()` or `ToTokenOnly()`.
  695. struct LocId : public IdBase<LocId> {
  696. // The contained index kind.
  697. enum class Kind {
  698. None,
  699. ImportIRInstId,
  700. InstId,
  701. NodeId,
  702. };
  703. static constexpr llvm::StringLiteral Label = "loc";
  704. using IdBase::IdBase;
  705. // NOLINTNEXTLINE(google-explicit-constructor)
  706. constexpr LocId(ImportIRInstId import_ir_inst_id)
  707. : IdBase(import_ir_inst_id.has_value()
  708. ? FirstImportIRInstId - import_ir_inst_id.index
  709. : NoneIndex) {}
  710. explicit constexpr LocId(InstId inst_id) : IdBase(inst_id.index) {}
  711. // NOLINTNEXTLINE(google-explicit-constructor)
  712. constexpr LocId(Parse::NoneNodeId /*none*/) : IdBase(NoneIndex) {}
  713. // NOLINTNEXTLINE(google-explicit-constructor)
  714. constexpr LocId(Parse::NodeId node_id)
  715. : IdBase(FirstNodeId - node_id.index) {}
  716. // Forms an equivalent LocId for a desugared location. Requires a
  717. // canonical location. See `InstStore::GetCanonicalLocId()`.
  718. //
  719. // TODO: Rename to something like `ToDesugared`.
  720. auto ToImplicit() const -> LocId {
  721. // This should only be called for NodeId or ImportIRInstId (i.e. canonical
  722. // locations), but we only set the flag for NodeId.
  723. CARBON_CHECK(kind() != Kind::InstId);
  724. if (kind() == Kind::NodeId) {
  725. return LocId(index & ~ImplicitBit);
  726. }
  727. return *this;
  728. }
  729. // Forms an equivalent `LocId` for a token-only diagnostic location. Requires
  730. // a canonical location. See `InstStore::GetCanonicalLocId()`.
  731. //
  732. // TODO: Consider making this a part of check/ diagnostics instead, as a free
  733. // function operation on `LocIdForDiagnostics`?
  734. // https://github.com/carbon-language/carbon-lang/pull/5355#discussion_r2064113186
  735. auto ToTokenOnly() const -> LocId {
  736. CARBON_CHECK(kind() != Kind::InstId);
  737. if (has_value()) {
  738. return LocId(index & ~TokenOnlyBit);
  739. }
  740. return *this;
  741. }
  742. // Returns the kind of the `LocId`.
  743. auto kind() const -> Kind {
  744. if (!has_value()) {
  745. return Kind::None;
  746. }
  747. if (index >= 0) {
  748. return Kind::InstId;
  749. }
  750. if (index_without_flags() <= FirstImportIRInstId) {
  751. return Kind::ImportIRInstId;
  752. }
  753. return Kind::NodeId;
  754. }
  755. // Returns true if the location corresponds to desugared instructions.
  756. // Requires a non-`InstId` location.
  757. auto is_implicit() const -> bool {
  758. return (kind() == Kind::NodeId) && (index & ImplicitBit) == 0;
  759. }
  760. // Returns true if the location is token-only for diagnostics.
  761. //
  762. // This means the displayed location will include only the location's specific
  763. // parse node, instead of also including its descendants. As such, this can
  764. // only be true for locations backed by a `NodeId`.
  765. auto is_token_only() const -> bool {
  766. return kind() != Kind::InstId && (index & TokenOnlyBit) == 0;
  767. }
  768. // Returns the equivalent `ImportIRInstId` when `kind()` matches or is `None`.
  769. // Note that the returned `ImportIRInstId` only identifies a location; it is
  770. // not correct to interpret it as the instruction from which another
  771. // instruction was imported. Use `InstStore::GetImportSource` for that.
  772. auto import_ir_inst_id() const -> ImportIRInstId {
  773. if (!has_value()) {
  774. return ImportIRInstId::None;
  775. }
  776. CARBON_CHECK(kind() == Kind::ImportIRInstId, "{0}", index);
  777. return ImportIRInstId(FirstImportIRInstId - index_without_flags());
  778. }
  779. // Returns the equivalent `InstId` when `kind()` matches or is `None`.
  780. auto inst_id() const -> InstId {
  781. CARBON_CHECK(kind() == Kind::None || kind() == Kind::InstId, "{0}", index);
  782. return InstId(index);
  783. }
  784. // Returns the equivalent `NodeId` when `kind()` matches or is `None`.
  785. auto node_id() const -> Parse::NodeId {
  786. if (!has_value()) {
  787. return Parse::NodeId::None;
  788. }
  789. CARBON_CHECK(kind() == Kind::NodeId, "{0}", index);
  790. return Parse::NodeId(FirstNodeId - index_without_flags());
  791. }
  792. auto Print(llvm::raw_ostream& out) const -> void;
  793. private:
  794. // Whether a location corresponds to desugared instructions. This only applies
  795. // for `NodeId`.
  796. static constexpr int32_t ImplicitBit = 1 << 30;
  797. // See `is_token_only` for the use. This only applies for canonical locations
  798. // (i.e. those containing `NodeId` or `ImportIRInstId`).
  799. static constexpr int32_t TokenOnlyBit = 1 << 29;
  800. // The value of the 0 index for each of `NodeId` and `ImportIRInstId`.
  801. static constexpr int32_t FirstNodeId = NoneIndex - 1;
  802. static constexpr int32_t FirstImportIRInstId =
  803. FirstNodeId - Parse::NodeId::Max;
  804. auto index_without_flags() const -> int32_t {
  805. CARBON_DCHECK(index < NoneIndex, "Only for NodeId and ImportIRInstId");
  806. return index | ImplicitBit | TokenOnlyBit;
  807. }
  808. };
  809. // Polymorphic id for fields in `Any[...]` typed instruction category. Used for
  810. // fields where the specific instruction structs have different field types in
  811. // that position or do not have a field in that position at all. Allows
  812. // conversion with `Inst::As<>` from the specific typed instruction to the
  813. // `Any[...]` instruction category.
  814. //
  815. // This type participates in `Inst::FromRaw` in order to convert from specific
  816. // instructions to an `Any[...]` instruction category:
  817. // - In the case the specific instruction has a field of some `IdKind` in the
  818. // same position, the `Any[...]` type will hold its raw value in the
  819. // `AnyRawId` field.
  820. // - In the case the specific instruction has no field in the same position, the
  821. // `Any[...]` type will hold a default constructed `AnyRawId` with a `None`
  822. // value.
  823. struct AnyRawId : public AnyIdBase {
  824. // For IdKind.
  825. static constexpr llvm::StringLiteral Label = "any_raw";
  826. constexpr explicit AnyRawId() : AnyIdBase(AnyIdBase::NoneIndex) {}
  827. constexpr explicit AnyRawId(int32_t id) : AnyIdBase(id) {}
  828. };
  829. // A pair of an interface and a specific for that interface.
  830. struct SpecificInterface {
  831. using DiagnosticType = Diagnostics::TypeInfo<std::string>;
  832. InterfaceId interface_id;
  833. SpecificId specific_id;
  834. static const SpecificInterface None;
  835. friend auto operator==(const SpecificInterface& lhs,
  836. const SpecificInterface& rhs) -> bool = default;
  837. };
  838. constexpr SpecificInterface SpecificInterface::None = {
  839. .interface_id = InterfaceId::None, .specific_id = SpecificId::None};
  840. } // namespace Carbon::SemIR
  841. #endif // CARBON_TOOLCHAIN_SEM_IR_IDS_H_