ids.h 39 KB

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