impl.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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_IMPL_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_IMPL_H_
  6. #include "llvm/ADT/DenseMap.h"
  7. #include "toolchain/sem_ir/ids.h"
  8. namespace Carbon::SemIR {
  9. // An implementation of a constraint.
  10. struct Impl : public Printable<Impl> {
  11. auto Print(llvm::raw_ostream& out) const -> void {
  12. out << "{self: " << self_id << ", constraint: " << constraint_id << "}";
  13. }
  14. // Determines whether this impl has been fully defined. This is false until we
  15. // reach the `}` of the impl definition.
  16. auto is_defined() const -> bool { return witness_id.is_valid(); }
  17. // Determines whether this impl's definition has begun but not yet ended.
  18. auto is_being_defined() const -> bool {
  19. return definition_id.is_valid() && !is_defined();
  20. }
  21. // The following members always have values, and do not change throughout the
  22. // lifetime of the interface.
  23. // TODO: Track the generic parameters for `impl forall`.
  24. // The type for which the impl is implementing a constraint.
  25. TypeId self_id;
  26. // The constraint that the impl implements.
  27. TypeId constraint_id;
  28. // The following members are set at the `{` of the impl definition.
  29. // The definition of the impl. This is an ImplDecl.
  30. InstId definition_id = InstId::Invalid;
  31. // The impl scope.
  32. NameScopeId scope_id = NameScopeId::Invalid;
  33. // The first block of the impl body.
  34. // TODO: Handle control flow in the impl body, such as if-expressions.
  35. InstBlockId body_block_id = InstBlockId::Invalid;
  36. // The following members are set at the `}` of the impl definition.
  37. // The witness for the impl. This can be `BuiltinError`.
  38. InstId witness_id = InstId::Invalid;
  39. };
  40. // A collection of `Impl`s, which can be accessed by the self type and
  41. // constraint implemented.
  42. class ImplStore {
  43. public:
  44. // Looks up the impl with this self type and constraint, or creates a new
  45. // `Impl` if none exists.
  46. // TODO: Handle parameters.
  47. auto LookupOrAdd(TypeId self_id, TypeId constraint_id) -> ImplId {
  48. auto [it, added] =
  49. lookup_.insert({{self_id, constraint_id}, ImplId::Invalid});
  50. if (added) {
  51. it->second =
  52. values_.Add({.self_id = self_id, .constraint_id = constraint_id});
  53. }
  54. return it->second;
  55. }
  56. // Returns a mutable value for an ID.
  57. auto Get(ImplId id) -> Impl& { return values_.Get(id); }
  58. // Returns the value for an ID.
  59. auto Get(ImplId id) const -> const Impl& { return values_.Get(id); }
  60. auto OutputYaml() const -> Yaml::OutputMapping {
  61. return values_.OutputYaml();
  62. }
  63. auto array_ref() const -> llvm::ArrayRef<Impl> { return values_.array_ref(); }
  64. auto size() const -> size_t { return values_.size(); }
  65. private:
  66. ValueStore<ImplId> values_;
  67. llvm::DenseMap<std::pair<TypeId, TypeId>, ImplId> lookup_;
  68. };
  69. } // namespace Carbon::SemIR
  70. #endif // CARBON_TOOLCHAIN_SEM_IR_IMPL_H_