node_kind.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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_TOOLCHAIN_PARSE_NODE_KIND_H_
  5. #define CARBON_TOOLCHAIN_PARSE_NODE_KIND_H_
  6. #include <cstdint>
  7. #include "common/enum_base.h"
  8. #include "llvm/ADT/BitmaskEnum.h"
  9. #include "toolchain/lex/token_kind.h"
  10. namespace Carbon::Parse {
  11. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
  12. // Represents a set of keyword modifiers, using a separate bit per modifier.
  13. //
  14. // We expect this to grow, so are using a bigger size than needed.
  15. // NOLINTNEXTLINE(performance-enum-size)
  16. enum class NodeCategory : uint32_t {
  17. Decl = 1 << 0,
  18. Expr = 1 << 1,
  19. MemberName = 1 << 2,
  20. Modifier = 1 << 3,
  21. NameComponent = 1 << 4,
  22. Pattern = 1 << 5,
  23. Statement = 1 << 6,
  24. None = 0,
  25. LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Statement)
  26. };
  27. inline auto operator!(NodeCategory k) -> bool {
  28. return !static_cast<uint32_t>(k);
  29. }
  30. auto operator<<(llvm::raw_ostream& output, NodeCategory category)
  31. -> llvm::raw_ostream&;
  32. CARBON_DEFINE_RAW_ENUM_CLASS(NodeKind, uint8_t) {
  33. #define CARBON_PARSE_NODE_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name)
  34. #include "toolchain/parse/node_kind.def"
  35. };
  36. // A class wrapping an enumeration of the different kinds of nodes in the parse
  37. // tree.
  38. class NodeKind : public CARBON_ENUM_BASE(NodeKind) {
  39. public:
  40. #define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CONSTANT_DECL(Name)
  41. #include "toolchain/parse/node_kind.def"
  42. // Validates that a `parse_node_kind` parser node can be generated for a
  43. // `lex_token_kind` lexer token.
  44. auto CheckMatchesTokenKind(Lex::TokenKind lex_token_kind, bool has_error)
  45. -> void;
  46. // Returns true if the node is bracketed; otherwise, child_count is used.
  47. auto has_bracket() const -> bool;
  48. // Returns the bracketing node kind for the current node kind. Requires that
  49. // has_bracket is true.
  50. auto bracket() const -> NodeKind;
  51. // Returns the number of children that the node must have, often 0. Requires
  52. // that has_bracket is false.
  53. auto child_count() const -> int32_t;
  54. // Returns which categories this node kind is in.
  55. auto category() const -> NodeCategory;
  56. using EnumBase::Create;
  57. class Definition;
  58. // Provides a definition for this parse node kind. Should only be called
  59. // once, to construct the kind as part of defining it in `typed_nodes.h`.
  60. constexpr auto Define(NodeCategory category = NodeCategory::None) const
  61. -> Definition;
  62. private:
  63. // Looks up the definition for this instruction kind.
  64. auto definition() const -> const Definition&;
  65. };
  66. #define CARBON_PARSE_NODE_KIND(Name) \
  67. CARBON_ENUM_CONSTANT_DEFINITION(NodeKind, Name)
  68. #include "toolchain/parse/node_kind.def"
  69. // We expect the parse node kind to fit compactly into 8 bits.
  70. static_assert(sizeof(NodeKind) == 1, "Kind objects include padding!");
  71. // A definition of a parse node kind. This is a NodeKind value, plus
  72. // ancillary data such as the name to use for the node kind in LLVM IR. These
  73. // are not copyable, and only one instance of this type is expected to exist per
  74. // parse node kind, specifically `TypedNode::Kind`. Use `NodeKind` instead as a
  75. // thin wrapper around a parse node kind index.
  76. class NodeKind::Definition : public NodeKind {
  77. public:
  78. // Not copyable.
  79. Definition(const Definition&) = delete;
  80. auto operator=(const Definition&) -> Definition& = delete;
  81. // Returns which categories this node kind is in.
  82. constexpr auto category() const -> NodeCategory { return category_; }
  83. private:
  84. friend class NodeKind;
  85. constexpr Definition(NodeKind kind, NodeCategory category)
  86. : NodeKind(kind), category_(category) {}
  87. NodeCategory category_;
  88. };
  89. constexpr auto NodeKind::Define(NodeCategory category) const -> Definition {
  90. return Definition(*this, category);
  91. }
  92. // HasKindMember<T> is true if T has a `static const NodeKind::Definition Kind`
  93. // member.
  94. template <typename T, typename KindType = const NodeKind::Definition*>
  95. inline constexpr bool HasKindMember = false;
  96. template <typename T>
  97. inline constexpr bool HasKindMember<T, decltype(&T::Kind)> = true;
  98. } // namespace Carbon::Parse
  99. #endif // CARBON_TOOLCHAIN_PARSE_NODE_KIND_H_