type.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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_TYPE_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_TYPE_H_
  6. #include "toolchain/base/value_store.h"
  7. #include "toolchain/sem_ir/ids.h"
  8. #include "toolchain/sem_ir/inst.h"
  9. #include "toolchain/sem_ir/type_info.h"
  10. namespace Carbon::SemIR {
  11. // Provides a ValueStore wrapper with an API specific to types.
  12. class TypeStore : public ValueStore<TypeId> {
  13. public:
  14. explicit TypeStore(InstStore* insts) : insts_(insts) {}
  15. // Returns the ID of the constant used to define the specified type.
  16. auto GetConstantId(TypeId type_id) const -> ConstantId {
  17. if (type_id == TypeId::TypeType) {
  18. return ConstantId::ForTemplateConstant(InstId::BuiltinTypeType);
  19. } else if (type_id == TypeId::Error) {
  20. return ConstantId::Error;
  21. } else if (!type_id.is_valid()) {
  22. // TODO: Can we CHECK-fail on this?
  23. return ConstantId::NotConstant;
  24. } else {
  25. return Get(type_id).constant_id;
  26. }
  27. }
  28. // Returns the ID of the instruction used to define the specified type.
  29. auto GetInstId(TypeId type_id) const -> InstId {
  30. return GetConstantId(type_id).inst_id();
  31. }
  32. // Returns the instruction used to define the specified type.
  33. auto GetAsInst(TypeId type_id) const -> Inst {
  34. return insts_->Get(GetInstId(type_id));
  35. }
  36. // Returns whether the specified kind of instruction was used to define the
  37. // type.
  38. template <typename InstT>
  39. auto Is(TypeId type_id) const -> bool {
  40. return GetAsInst(type_id).Is<InstT>();
  41. }
  42. // Returns the instruction used to define the specified type, which is known
  43. // to be a particular kind of instruction.
  44. template <typename InstT>
  45. auto GetAs(TypeId type_id) const -> InstT {
  46. if constexpr (std::is_same_v<InstT, Builtin>) {
  47. return GetAsInst(type_id).As<InstT>();
  48. } else {
  49. // The type is not a builtin, so no need to check for special values.
  50. return insts_->Get(Get(type_id).constant_id.inst_id()).As<InstT>();
  51. }
  52. }
  53. // Returns the instruction used to define the specified type, if it is of a
  54. // particular kind.
  55. template <typename InstT>
  56. auto TryGetAs(TypeId type_id) const -> std::optional<InstT> {
  57. return GetAsInst(type_id).TryAs<InstT>();
  58. }
  59. // Gets the value representation to use for a type. This returns an
  60. // invalid type if the given type is not complete.
  61. auto GetValueRepr(TypeId type_id) const -> ValueRepr {
  62. if (type_id.index < 0) {
  63. // TypeType and InvalidType are their own value representation.
  64. return {.kind = ValueRepr::Copy, .type_id = type_id};
  65. }
  66. return Get(type_id).value_repr;
  67. }
  68. // Determines whether the given type is known to be complete. This does not
  69. // determine whether the type could be completed, only whether it has been.
  70. auto IsComplete(TypeId type_id) const -> bool {
  71. return GetValueRepr(type_id).kind != ValueRepr::Unknown;
  72. }
  73. // Determines whether the given type is a signed integer type.
  74. auto IsSignedInt(TypeId int_type_id) const -> bool {
  75. return GetInstId(int_type_id) == InstId::BuiltinIntType;
  76. }
  77. private:
  78. InstStore* insts_;
  79. };
  80. } // namespace Carbon::SemIR
  81. #endif // CARBON_TOOLCHAIN_SEM_IR_TYPE_H_