ast_node.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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_AST_NODE_H_
  5. #define CARBON_EXPLORER_AST_AST_NODE_H_
  6. #include "explorer/ast/ast_rtti.h"
  7. #include "explorer/common/source_location.h"
  8. #include "llvm/Support/Casting.h"
  9. namespace Carbon {
  10. class CloneContext;
  11. // Base class for all nodes in the AST.
  12. //
  13. // Every class derived from this class must be listed in ast_rtti.txt. See
  14. // the documentation of gen_rtti.py for details about the format. As a result,
  15. // every abstract class `Foo` will have a `FooKind` enumerated type, whose
  16. // enumerators correspond to the subclasses of `Foo`.
  17. //
  18. // AstNode and its derived classes support LLVM-style RTTI, including
  19. // llvm::isa, llvm::cast, and llvm::dyn_cast. To support this, every
  20. // class derived from Declaration must provide a `classof` operation, with
  21. // the following form, where `Foo` is the name of the derived class:
  22. //
  23. // static auto classof(const AstNode* node) -> bool {
  24. // return InheritsFromFoo(node->kind());
  25. // }
  26. //
  27. // Furthermore, if the class is abstract, it must provide a `kind()` operation,
  28. // with the following form:
  29. //
  30. // auto kind() const -> FooKind { return static_cast<FooKind>(root_kind()); }
  31. //
  32. // The definitions of `InheritsFromFoo` and `FooKind` are generated from
  33. // ast_rtti.txt, and are implicitly provided by this header.
  34. //
  35. // Every AST node is expected to provide a cloning constructor:
  36. //
  37. // explicit MyAstNode(CloneContext& context, const MyAstNode& other);
  38. //
  39. // The cloning constructor should behave like a copy constructor, but pointers
  40. // to other AST nodes should be passed through context.Clone to clone the
  41. // referenced object.
  42. //
  43. // TODO: To support generic traversal, add children() method, and ensure that
  44. // all AstNodes are reachable from a root AstNode.
  45. class AstNode {
  46. public:
  47. AstNode(AstNode&&) = delete;
  48. auto operator=(AstNode&&) -> AstNode& = delete;
  49. virtual ~AstNode() = 0;
  50. // Print the AST rooted at the node.
  51. virtual void Print(llvm::raw_ostream& out) const = 0;
  52. // Print identifying information about the node, such as its name.
  53. virtual void PrintID(llvm::raw_ostream& out) const = 0;
  54. LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
  55. // Returns an enumerator specifying the concrete type of this node.
  56. //
  57. // Abstract subclasses of AstNode will provide their own `kind()` method
  58. // which hides this one, and provides a narrower return type.
  59. auto kind() const -> AstNodeKind { return kind_; }
  60. // The location of the code described by this node.
  61. auto source_loc() const -> SourceLocation { return source_loc_; }
  62. protected:
  63. // Constructs an AstNode representing code at the given location. `kind`
  64. // must be the enumerator that exactly matches the concrete type being
  65. // constructed.
  66. explicit AstNode(AstNodeKind kind, SourceLocation source_loc)
  67. : kind_(kind), source_loc_(source_loc) {}
  68. // Clone this AstNode.
  69. explicit AstNode(CloneContext& /*context*/, const AstNode& other)
  70. : kind_(other.kind_), source_loc_(other.source_loc_) {}
  71. // Equivalent to kind(), but will not be hidden by `kind()` methods of
  72. // derived classes.
  73. auto root_kind() const -> AstNodeKind { return kind_; }
  74. private:
  75. AstNodeKind kind_;
  76. SourceLocation source_loc_;
  77. };
  78. } // namespace Carbon
  79. #endif // CARBON_EXPLORER_AST_AST_NODE_H_