declaration.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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 <list>
  7. #include <string>
  8. #include "common/ostream.h"
  9. #include "executable_semantics/ast/class_definition.h"
  10. #include "executable_semantics/ast/function_definition.h"
  11. #include "executable_semantics/ast/member.h"
  12. #include "executable_semantics/ast/pattern.h"
  13. #include "llvm/Support/Compiler.h"
  14. namespace Carbon {
  15. // Abstract base class of all AST nodes representing patterns.
  16. //
  17. // Declaration and its derived classes support LLVM-style RTTI, including
  18. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  19. // class derived from Declaration must provide a `classof` operation, and
  20. // every concrete derived class must have a corresponding enumerator
  21. // in `Kind`; see https://llvm.org/docs/HowToSetUpLLVMStyleRTTI.html for
  22. // details.
  23. class Declaration {
  24. public:
  25. enum class Kind {
  26. FunctionDeclaration,
  27. ClassDeclaration,
  28. ChoiceDeclaration,
  29. VariableDeclaration,
  30. };
  31. Declaration(const Member&) = delete;
  32. Declaration& operator=(const Member&) = delete;
  33. // Returns the enumerator corresponding to the most-derived type of this
  34. // object.
  35. auto Tag() const -> Kind { return tag; }
  36. auto LineNumber() const -> int { return line_num; }
  37. void Print(llvm::raw_ostream& out) const;
  38. protected:
  39. // Constructs a Declaration representing syntax at the given line number.
  40. // `tag` must be the enumerator corresponding to the most-derived type being
  41. // constructed.
  42. Declaration(Kind tag, int line_num) : tag(tag), line_num(line_num) {}
  43. private:
  44. const Kind tag;
  45. int line_num;
  46. };
  47. class FunctionDeclaration : public Declaration {
  48. public:
  49. FunctionDeclaration(const FunctionDefinition* definition)
  50. : Declaration(Kind::FunctionDeclaration, definition->line_num),
  51. definition(definition) {}
  52. static auto classof(const Declaration* decl) -> bool {
  53. return decl->Tag() == Kind::FunctionDeclaration;
  54. }
  55. auto Definition() const -> const FunctionDefinition& { return *definition; }
  56. private:
  57. const FunctionDefinition* definition;
  58. };
  59. class ClassDeclaration : public Declaration {
  60. public:
  61. ClassDeclaration(int line_num, std::string name, std::list<Member*> members)
  62. : Declaration(Kind::ClassDeclaration, line_num),
  63. definition({.line_num = line_num,
  64. .name = std::move(name),
  65. .members = std::move(members)}) {}
  66. static auto classof(const Declaration* decl) -> bool {
  67. return decl->Tag() == Kind::ClassDeclaration;
  68. }
  69. auto Definition() const -> const ClassDefinition& { return definition; }
  70. private:
  71. ClassDefinition definition;
  72. };
  73. class ChoiceDeclaration : public Declaration {
  74. public:
  75. ChoiceDeclaration(
  76. int line_num, std::string name,
  77. std::list<std::pair<std::string, const Expression*>> alternatives)
  78. : Declaration(Kind::ChoiceDeclaration, line_num),
  79. name(std::move(name)),
  80. alternatives(std::move(alternatives)) {}
  81. static auto classof(const Declaration* decl) -> bool {
  82. return decl->Tag() == Kind::ChoiceDeclaration;
  83. }
  84. auto Name() const -> const std::string& { return name; }
  85. auto Alternatives() const
  86. -> const std::list<std::pair<std::string, const Expression*>>& {
  87. return alternatives;
  88. }
  89. private:
  90. std::string name;
  91. std::list<std::pair<std::string, const Expression*>> alternatives;
  92. };
  93. // Global variable definition implements the Declaration concept.
  94. class VariableDeclaration : public Declaration {
  95. public:
  96. VariableDeclaration(int line_num, const BindingPattern* binding,
  97. const Expression* initializer)
  98. : Declaration(Kind::VariableDeclaration, line_num),
  99. binding(binding),
  100. initializer(initializer) {}
  101. static auto classof(const Declaration* decl) -> bool {
  102. return decl->Tag() == Kind::VariableDeclaration;
  103. }
  104. auto Binding() const -> const BindingPattern* { return binding; }
  105. auto Initializer() const -> const Expression* { return initializer; }
  106. private:
  107. // TODO: split this into a non-optional name and a type, initialized by
  108. // a constructor that takes a BindingPattern and handles errors like a
  109. // missing name.
  110. const BindingPattern* binding;
  111. const Expression* initializer;
  112. };
  113. } // namespace Carbon
  114. #endif // EXECUTABLE_SEMANTICS_AST_DECLARATION_H_