type.h 3.6 KB

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