return_term.h 3.5 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_EXPLORER_AST_RETURN_TERM_H_
  5. #define CARBON_EXPLORER_AST_RETURN_TERM_H_
  6. #include <optional>
  7. #include <utility>
  8. #include "common/check.h"
  9. #include "common/ostream.h"
  10. #include "explorer/ast/clone_context.h"
  11. #include "explorer/ast/expression.h"
  12. #include "explorer/base/nonnull.h"
  13. #include "explorer/base/source_location.h"
  14. namespace Carbon {
  15. class Value;
  16. // The syntactic representation of a function declaration's return type.
  17. // This syntax can take one of three forms:
  18. // - An _explicit_ term consists of `->` followed by a type expression.
  19. // - An _auto_ term consists of `-> auto`.
  20. // - An _omitted_ term consists of no tokens at all.
  21. // Each of these forms has a corresponding factory function.
  22. class ReturnTerm : public Printable<ReturnTerm> {
  23. public:
  24. explicit ReturnTerm(CloneContext& context, const ReturnTerm& other)
  25. : kind_(other.kind_),
  26. type_expression_(context.Clone(other.type_expression_)),
  27. static_type_(context.Clone(other.static_type_)),
  28. source_loc_(other.source_loc_) {}
  29. ReturnTerm(const ReturnTerm&) = default;
  30. auto operator=(const ReturnTerm&) -> ReturnTerm& = default;
  31. // Represents an omitted return term at `source_loc`.
  32. static auto Omitted(SourceLocation source_loc) -> ReturnTerm {
  33. return ReturnTerm(ReturnKind::Omitted, source_loc);
  34. }
  35. // Represents an auto return term at `source_loc`.
  36. static auto Auto(SourceLocation source_loc) -> ReturnTerm {
  37. return ReturnTerm(ReturnKind::Auto, source_loc);
  38. }
  39. // Represents an explicit return term with the given type expression.
  40. static auto Explicit(Nonnull<Expression*> type_expression) -> ReturnTerm {
  41. return ReturnTerm(type_expression);
  42. }
  43. // Returns true if this represents an omitted return term.
  44. auto is_omitted() const -> bool { return kind_ == ReturnKind::Omitted; }
  45. // Returns true if this represents an auto return term.
  46. auto is_auto() const -> bool { return kind_ == ReturnKind::Auto; }
  47. // If this represents an explicit return term, returns the type expression.
  48. // Otherwise, returns nullopt.
  49. auto type_expression() const -> std::optional<Nonnull<const Expression*>> {
  50. return type_expression_;
  51. }
  52. auto type_expression() -> std::optional<Nonnull<Expression*>> {
  53. return type_expression_;
  54. }
  55. // The static return type this term resolves to. Cannot be called before
  56. // typechecking.
  57. auto static_type() const -> const Value& { return **static_type_; }
  58. // Sets the value of static_type(). Can only be called once, during
  59. // typechecking.
  60. void set_static_type(Nonnull<const Value*> type) {
  61. CARBON_CHECK(!static_type_.has_value());
  62. static_type_ = type;
  63. }
  64. auto source_loc() const -> SourceLocation { return source_loc_; }
  65. void Print(llvm::raw_ostream& out) const;
  66. private:
  67. enum class ReturnKind { Omitted, Auto, Expression };
  68. explicit ReturnTerm(ReturnKind kind, SourceLocation source_loc)
  69. : kind_(kind), source_loc_(source_loc) {
  70. CARBON_CHECK(kind != ReturnKind::Expression);
  71. }
  72. explicit ReturnTerm(Nonnull<Expression*> type_expression)
  73. : kind_(ReturnKind::Expression),
  74. type_expression_(type_expression),
  75. source_loc_(type_expression->source_loc()) {}
  76. ReturnKind kind_;
  77. std::optional<Nonnull<Expression*>> type_expression_;
  78. std::optional<Nonnull<const Value*>> static_type_;
  79. SourceLocation source_loc_;
  80. };
  81. } // namespace Carbon
  82. #endif // CARBON_EXPLORER_AST_RETURN_TERM_H_