declaration.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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 EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
  5. #define EXECUTABLE_SEMANTICS_AST_DECLARATION_H_
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "common/ostream.h"
  10. #include "executable_semantics/ast/ast_node.h"
  11. #include "executable_semantics/ast/generic_binding.h"
  12. #include "executable_semantics/ast/pattern.h"
  13. #include "executable_semantics/ast/return_term.h"
  14. #include "executable_semantics/ast/source_location.h"
  15. #include "executable_semantics/ast/statement.h"
  16. #include "executable_semantics/ast/static_scope.h"
  17. #include "executable_semantics/ast/value_category.h"
  18. #include "executable_semantics/common/nonnull.h"
  19. #include "llvm/ADT/ArrayRef.h"
  20. #include "llvm/Support/Compiler.h"
  21. namespace Carbon {
  22. // Abstract base class of all AST nodes representing patterns.
  23. //
  24. // Declaration and its derived classes support LLVM-style RTTI, including
  25. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  26. // class derived from Declaration must provide a `classof` operation, and
  27. // every concrete derived class must have a corresponding enumerator
  28. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  29. // details.
  30. class Declaration : public AstNode {
  31. public:
  32. ~Declaration() override = 0;
  33. Declaration(const Declaration&) = delete;
  34. auto operator=(const Declaration&) -> Declaration& = delete;
  35. void Print(llvm::raw_ostream& out) const override;
  36. static auto classof(const AstNode* node) -> bool {
  37. return InheritsFromDeclaration(node->kind());
  38. }
  39. // Returns the enumerator corresponding to the most-derived type of this
  40. // object.
  41. auto kind() const -> DeclarationKind {
  42. return static_cast<DeclarationKind>(root_kind());
  43. }
  44. // The static type of the declared entity. Cannot be called before
  45. // typechecking.
  46. auto static_type() const -> const Value& { return **static_type_; }
  47. // Sets the static type of the declared entity. Can only be called once,
  48. // during typechecking.
  49. void set_static_type(Nonnull<const Value*> type) {
  50. CHECK(!static_type_.has_value());
  51. static_type_ = type;
  52. }
  53. // Returns whether the static type has been set. Should only be called
  54. // during typechecking: before typechecking it's guaranteed to be false,
  55. // and after typechecking it's guaranteed to be true.
  56. auto has_static_type() const -> bool { return static_type_.has_value(); }
  57. protected:
  58. // Constructs a Declaration representing syntax at the given line number.
  59. // `kind` must be the enumerator corresponding to the most-derived type being
  60. // constructed.
  61. Declaration(AstNodeKind kind, SourceLocation source_loc)
  62. : AstNode(kind, source_loc) {}
  63. private:
  64. std::optional<Nonnull<const Value*>> static_type_;
  65. };
  66. class FunctionDeclaration : public Declaration {
  67. public:
  68. using ImplementsCarbonValueNode = void;
  69. FunctionDeclaration(SourceLocation source_loc, std::string name,
  70. std::vector<Nonnull<AstNode*>> deduced_params,
  71. std::optional<Nonnull<BindingPattern*>> me_pattern,
  72. Nonnull<TuplePattern*> param_pattern,
  73. ReturnTerm return_term,
  74. std::optional<Nonnull<Block*>> body)
  75. : Declaration(AstNodeKind::FunctionDeclaration, source_loc),
  76. name_(std::move(name)),
  77. me_pattern_(me_pattern),
  78. param_pattern_(param_pattern),
  79. return_term_(return_term),
  80. body_(body) {
  81. ResolveDeducedAndReceiver(deduced_params);
  82. }
  83. static auto classof(const AstNode* node) -> bool {
  84. return InheritsFromFunctionDeclaration(node->kind());
  85. }
  86. void PrintDepth(int depth, llvm::raw_ostream& out) const;
  87. auto name() const -> const std::string& { return name_; }
  88. auto deduced_parameters() const
  89. -> llvm::ArrayRef<Nonnull<const GenericBinding*>> {
  90. return deduced_parameters_;
  91. }
  92. auto deduced_parameters() -> llvm::ArrayRef<Nonnull<GenericBinding*>> {
  93. return deduced_parameters_;
  94. }
  95. auto me_pattern() const -> const BindingPattern& { return **me_pattern_; }
  96. auto me_pattern() -> BindingPattern& { return **me_pattern_; }
  97. auto param_pattern() const -> const TuplePattern& { return *param_pattern_; }
  98. auto param_pattern() -> TuplePattern& { return *param_pattern_; }
  99. auto return_term() const -> const ReturnTerm& { return return_term_; }
  100. auto return_term() -> ReturnTerm& { return return_term_; }
  101. auto body() const -> std::optional<Nonnull<const Block*>> { return body_; }
  102. auto body() -> std::optional<Nonnull<Block*>> { return body_; }
  103. auto value_category() const -> ValueCategory { return ValueCategory::Let; }
  104. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  105. return constant_value_;
  106. }
  107. // Sets the value returned by constant_value(). Can only be called once,
  108. // during typechecking.
  109. void set_constant_value(Nonnull<const Value*> value) {
  110. CHECK(!constant_value_.has_value());
  111. constant_value_ = value;
  112. }
  113. bool is_method() const { return me_pattern_.has_value(); }
  114. private:
  115. void ResolveDeducedAndReceiver(const std::vector<Nonnull<AstNode*>>&);
  116. std::string name_;
  117. std::vector<Nonnull<GenericBinding*>> deduced_parameters_;
  118. std::optional<Nonnull<BindingPattern*>> me_pattern_;
  119. Nonnull<TuplePattern*> param_pattern_;
  120. ReturnTerm return_term_;
  121. std::optional<Nonnull<Block*>> body_;
  122. std::optional<Nonnull<const Value*>> constant_value_;
  123. };
  124. class ClassDeclaration : public Declaration {
  125. public:
  126. using ImplementsCarbonValueNode = void;
  127. ClassDeclaration(SourceLocation source_loc, std::string name,
  128. std::vector<Nonnull<Declaration*>> members)
  129. : Declaration(AstNodeKind::ClassDeclaration, source_loc),
  130. name_(std::move(name)),
  131. members_(std::move(members)) {}
  132. static auto classof(const AstNode* node) -> bool {
  133. return InheritsFromClassDeclaration(node->kind());
  134. }
  135. auto name() const -> const std::string& { return name_; }
  136. auto members() const -> llvm::ArrayRef<Nonnull<Declaration*>> {
  137. return members_;
  138. }
  139. auto value_category() const -> ValueCategory { return ValueCategory::Let; }
  140. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  141. return constant_value_;
  142. }
  143. // Sets the value returned by constant_value(). Can only be called once,
  144. // during typechecking.
  145. void set_constant_value(Nonnull<const Value*> value) {
  146. CHECK(!constant_value_.has_value());
  147. constant_value_ = value;
  148. }
  149. private:
  150. std::string name_;
  151. std::vector<Nonnull<Declaration*>> members_;
  152. std::optional<Nonnull<const Value*>> constant_value_;
  153. };
  154. class AlternativeSignature : public AstNode {
  155. public:
  156. AlternativeSignature(SourceLocation source_loc, std::string name,
  157. Nonnull<Expression*> signature)
  158. : AstNode(AstNodeKind::AlternativeSignature, source_loc),
  159. name_(std::move(name)),
  160. signature_(signature) {}
  161. void Print(llvm::raw_ostream& out) const override;
  162. static auto classof(const AstNode* node) -> bool {
  163. return InheritsFromAlternativeSignature(node->kind());
  164. }
  165. auto name() const -> const std::string& { return name_; }
  166. auto signature() const -> const Expression& { return *signature_; }
  167. auto signature() -> Expression& { return *signature_; }
  168. private:
  169. std::string name_;
  170. Nonnull<Expression*> signature_;
  171. };
  172. class ChoiceDeclaration : public Declaration {
  173. public:
  174. using ImplementsCarbonValueNode = void;
  175. ChoiceDeclaration(SourceLocation source_loc, std::string name,
  176. std::vector<Nonnull<AlternativeSignature*>> alternatives)
  177. : Declaration(AstNodeKind::ChoiceDeclaration, source_loc),
  178. name_(std::move(name)),
  179. alternatives_(std::move(alternatives)) {}
  180. static auto classof(const AstNode* node) -> bool {
  181. return InheritsFromChoiceDeclaration(node->kind());
  182. }
  183. auto name() const -> const std::string& { return name_; }
  184. auto alternatives() const
  185. -> llvm::ArrayRef<Nonnull<const AlternativeSignature*>> {
  186. return alternatives_;
  187. }
  188. auto alternatives() -> llvm::ArrayRef<Nonnull<AlternativeSignature*>> {
  189. return alternatives_;
  190. }
  191. auto value_category() const -> ValueCategory { return ValueCategory::Let; }
  192. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  193. return constant_value_;
  194. }
  195. // Sets the value returned by constant_value(). Can only be called once,
  196. // during typechecking.
  197. void set_constant_value(Nonnull<const Value*> value) {
  198. CHECK(!constant_value_.has_value());
  199. constant_value_ = value;
  200. }
  201. private:
  202. std::string name_;
  203. std::vector<Nonnull<AlternativeSignature*>> alternatives_;
  204. std::optional<Nonnull<const Value*>> constant_value_;
  205. };
  206. // Global variable definition implements the Declaration concept.
  207. class VariableDeclaration : public Declaration {
  208. public:
  209. VariableDeclaration(SourceLocation source_loc,
  210. Nonnull<BindingPattern*> binding,
  211. std::optional<Nonnull<Expression*>> initializer)
  212. : Declaration(AstNodeKind::VariableDeclaration, source_loc),
  213. binding_(binding),
  214. initializer_(initializer) {}
  215. static auto classof(const AstNode* node) -> bool {
  216. return InheritsFromVariableDeclaration(node->kind());
  217. }
  218. auto binding() const -> const BindingPattern& { return *binding_; }
  219. auto binding() -> BindingPattern& { return *binding_; }
  220. auto initializer() const -> const Expression& { return **initializer_; }
  221. auto initializer() -> Expression& { return **initializer_; }
  222. bool has_initializer() const { return initializer_.has_value(); }
  223. private:
  224. // TODO: split this into a non-optional name and a type, initialized by
  225. // a constructor that takes a BindingPattern and handles errors like a
  226. // missing name.
  227. Nonnull<BindingPattern*> binding_;
  228. std::optional<Nonnull<Expression*>> initializer_;
  229. };
  230. class InterfaceDeclaration : public Declaration {
  231. public:
  232. using ImplementsCarbonValueNode = void;
  233. InterfaceDeclaration(SourceLocation source_loc, std::string name,
  234. Nonnull<GenericBinding*> self,
  235. std::vector<Nonnull<Declaration*>> members)
  236. : Declaration(AstNodeKind::InterfaceDeclaration, source_loc),
  237. name_(std::move(name)),
  238. members_(std::move(members)),
  239. self_(self) {}
  240. static auto classof(const AstNode* node) -> bool {
  241. return InheritsFromInterfaceDeclaration(node->kind());
  242. }
  243. auto name() const -> const std::string& { return name_; }
  244. auto members() const -> llvm::ArrayRef<Nonnull<Declaration*>> {
  245. return members_;
  246. }
  247. auto self() const -> Nonnull<const GenericBinding*> { return self_; }
  248. auto self() -> Nonnull<GenericBinding*> { return self_; }
  249. auto value_category() const -> ValueCategory { return ValueCategory::Let; }
  250. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  251. return constant_value_;
  252. }
  253. // Sets the value returned by constant_value(). Can only be called once,
  254. // during typechecking.
  255. void set_constant_value(Nonnull<const Value*> value) {
  256. CHECK(!constant_value_.has_value());
  257. constant_value_ = value;
  258. }
  259. private:
  260. std::string name_;
  261. std::vector<Nonnull<Declaration*>> members_;
  262. std::optional<Nonnull<const Value*>> constant_value_;
  263. Nonnull<GenericBinding*> self_;
  264. };
  265. enum class ImplKind { InternalImpl, ExternalImpl };
  266. class ImplDeclaration : public Declaration {
  267. public:
  268. using ImplementsCarbonValueNode = void;
  269. ImplDeclaration(SourceLocation source_loc, ImplKind kind,
  270. Nonnull<Expression*> impl_type,
  271. Nonnull<Expression*> interface,
  272. std::vector<Nonnull<Declaration*>> members)
  273. : Declaration(AstNodeKind::ImplDeclaration, source_loc),
  274. kind_(kind),
  275. impl_type_(impl_type),
  276. interface_(interface),
  277. members_(members) {}
  278. static auto classof(const AstNode* node) -> bool {
  279. return InheritsFromImplDeclaration(node->kind());
  280. }
  281. // Return whether this is an external or internal impl.
  282. auto kind() const -> ImplKind { return kind_; }
  283. // Return the type that is doing the implementing.
  284. auto impl_type() const -> Nonnull<Expression*> { return impl_type_; }
  285. // Return the interface that is being implemented.
  286. auto interface() const -> const Expression& { return *interface_; }
  287. auto interface() -> Expression& { return *interface_; }
  288. void set_interface_type(Nonnull<const Value*> iface_type) {
  289. interface_type_ = iface_type;
  290. }
  291. auto interface_type() const -> Nonnull<const Value*> {
  292. return *interface_type_;
  293. }
  294. auto members() const -> llvm::ArrayRef<Nonnull<Declaration*>> {
  295. return members_;
  296. }
  297. // Return the witness table for this impl.
  298. auto constant_value() const -> std::optional<Nonnull<const Value*>> {
  299. return constant_value_;
  300. }
  301. void set_constant_value(Nonnull<const Value*> value) {
  302. CHECK(!constant_value_.has_value());
  303. constant_value_ = value;
  304. }
  305. auto value_category() const -> ValueCategory { return ValueCategory::Let; }
  306. private:
  307. ImplKind kind_;
  308. Nonnull<Expression*> impl_type_; // TODO: make this optional
  309. Nonnull<Expression*> interface_;
  310. std::optional<Nonnull<const Value*>> interface_type_;
  311. std::vector<Nonnull<Declaration*>> members_;
  312. std::optional<Nonnull<const Value*>> constant_value_;
  313. };
  314. // Return the name of a declaration, if it has one.
  315. auto GetName(const Declaration&) -> std::optional<std::string>;
  316. } // namespace Carbon
  317. #endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_