element.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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_EXPLORER_AST_ELEMENT_H_
  5. #define CARBON_EXPLORER_AST_ELEMENT_H_
  6. #include <optional>
  7. #include <string>
  8. #include <string_view>
  9. #include "common/ostream.h"
  10. #include "explorer/ast/ast_rtti.h"
  11. #include "explorer/common/nonnull.h"
  12. #include "llvm/ADT/PointerUnion.h"
  13. namespace Carbon {
  14. class Declaration;
  15. class Value;
  16. // A NamedValue represents a value with a name, such as a single struct field.
  17. struct NamedValue {
  18. NamedValue(std::string name, Nonnull<const Value*> value)
  19. : name(std::move(name)), value(value) {}
  20. template <typename F>
  21. auto Decompose(F f) const {
  22. return f(name, value);
  23. }
  24. // The field name.
  25. std::string name;
  26. // The field's value.
  27. Nonnull<const Value*> value;
  28. };
  29. // A generic member of a type.
  30. //
  31. // This is can be a named, positional or other type of member.
  32. class Element {
  33. protected:
  34. explicit Element(ElementKind kind) : kind_(kind) {}
  35. public:
  36. virtual ~Element() = default;
  37. // Call `f` on this value, cast to its most-derived type. `R` specifies the
  38. // expected return type of `f`.
  39. template <typename R, typename F>
  40. auto Visit(F f) const -> R;
  41. // Prints the Member
  42. virtual void Print(llvm::raw_ostream& out) const = 0;
  43. // Return whether the member's name matches `name`.
  44. virtual auto IsNamed(std::string_view name) const -> bool = 0;
  45. // Returns the enumerator corresponding to the most-derived type of this
  46. // object.
  47. auto kind() const -> ElementKind { return kind_; }
  48. // The declared type of the member, which might include type variables.
  49. virtual auto type() const -> const Value& = 0;
  50. private:
  51. const ElementKind kind_;
  52. };
  53. // A named element of a type.
  54. //
  55. // This is either a declared member of a class, interface, or similar, or a
  56. // member of a struct with no declaration.
  57. class NamedElement : public Element {
  58. public:
  59. explicit NamedElement(Nonnull<const Declaration*> declaration);
  60. explicit NamedElement(Nonnull<const NamedValue*> struct_member);
  61. template <typename F>
  62. auto Decompose(F f) const {
  63. if (auto decl = declaration()) {
  64. return f(*decl);
  65. } else {
  66. return f(*struct_member());
  67. }
  68. }
  69. // Prints the element's name
  70. void Print(llvm::raw_ostream& out) const override;
  71. auto IsNamed(std::string_view name) const -> bool override;
  72. static auto classof(const Element* member) -> bool {
  73. return InheritsFromNamedElement(member->kind());
  74. }
  75. auto type() const -> const Value& override;
  76. // The name of the member.
  77. auto name() const -> std::string_view;
  78. // A declaration of the member, if any exists.
  79. auto declaration() const -> std::optional<Nonnull<const Declaration*>>;
  80. // A name and type pair, if this is a struct member.
  81. auto struct_member() const -> std::optional<Nonnull<const NamedValue*>>;
  82. private:
  83. const llvm::PointerUnion<Nonnull<const Declaration*>,
  84. Nonnull<const NamedValue*>>
  85. element_;
  86. };
  87. // A positional element of a type.
  88. //
  89. // This is a positional tuple element, or other index-based value.
  90. class PositionalElement : public Element {
  91. public:
  92. explicit PositionalElement(int index, Nonnull<const Value*> type)
  93. : Element(ElementKind::PositionalElement), index_(index), type_(type) {}
  94. template <typename F>
  95. auto Decompose(F f) const {
  96. return f(index_, type_);
  97. }
  98. // Prints the element
  99. void Print(llvm::raw_ostream& out) const override;
  100. // Return whether the member's name matches `name`.
  101. auto IsNamed(std::string_view name) const -> bool override;
  102. static auto classof(const Element* member) -> bool {
  103. return InheritsFromPositionalElement(member->kind());
  104. }
  105. auto index() const -> int { return index_; }
  106. auto type() const -> const Value& override { return *type_; }
  107. private:
  108. const int index_;
  109. const Nonnull<const Value*> type_;
  110. };
  111. // A base class object.
  112. //
  113. // This is the base class object of a class value.
  114. class BaseElement : public Element {
  115. public:
  116. explicit BaseElement(Nonnull<const Value*> type)
  117. : Element(ElementKind::BaseElement), type_(type) {}
  118. template <typename F>
  119. auto Decompose(F f) const {
  120. return f(type_);
  121. }
  122. // Prints the Member
  123. void Print(llvm::raw_ostream& out) const override;
  124. // Return whether the member's name matches `name`.
  125. auto IsNamed(std::string_view name) const -> bool override;
  126. static auto classof(const Element* member) -> bool {
  127. return InheritsFromBaseElement(member->kind());
  128. }
  129. auto type() const -> const Value& override { return *type_; }
  130. private:
  131. const Nonnull<const Value*> type_;
  132. };
  133. template <typename R, typename F>
  134. auto Element::Visit(F f) const -> R {
  135. switch (kind()) {
  136. case ElementKind::NamedElement:
  137. return f(static_cast<const NamedElement*>(this));
  138. case ElementKind::PositionalElement:
  139. return f(static_cast<const PositionalElement*>(this));
  140. case ElementKind::BaseElement:
  141. return f(static_cast<const BaseElement*>(this));
  142. }
  143. }
  144. } // namespace Carbon
  145. #endif // CARBON_EXPLORER_AST_ELEMENT_H_