ids.h 37 KB

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