ids.h 37 KB

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