node_kind.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. #include "toolchain/parse/node_kind.h"
  5. #include "common/check.h"
  6. #include "llvm/ADT/StringExtras.h"
  7. #include "toolchain/parse/typed_nodes.h"
  8. namespace Carbon::Parse {
  9. auto operator<<(llvm::raw_ostream& output, NodeCategory category)
  10. -> llvm::raw_ostream& {
  11. if (!category) {
  12. output << "<none>";
  13. } else {
  14. llvm::ListSeparator sep("|");
  15. #define CARBON_NODE_CATEGORY(Name) \
  16. if (!!(category & NodeCategory::Name)) { \
  17. output << sep << #Name; \
  18. }
  19. CARBON_NODE_CATEGORY(Decl);
  20. CARBON_NODE_CATEGORY(Expr);
  21. CARBON_NODE_CATEGORY(MemberName);
  22. CARBON_NODE_CATEGORY(Modifier);
  23. CARBON_NODE_CATEGORY(NameComponent);
  24. CARBON_NODE_CATEGORY(Pattern);
  25. CARBON_NODE_CATEGORY(Statement);
  26. #undef CARBON_NODE_CATEGORY
  27. }
  28. return output;
  29. }
  30. CARBON_DEFINE_ENUM_CLASS_NAMES(NodeKind) = {
  31. #define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CLASS_NAME_STRING(Name)
  32. #include "toolchain/parse/node_kind.def"
  33. };
  34. auto NodeKind::has_bracket() const -> bool {
  35. static constexpr bool HasBracket[] = {
  36. #define CARBON_PARSE_NODE_KIND_BRACKET(...) true,
  37. #define CARBON_PARSE_NODE_KIND_CHILD_COUNT(...) false,
  38. #include "toolchain/parse/node_kind.def"
  39. };
  40. return HasBracket[AsInt()];
  41. }
  42. auto NodeKind::bracket() const -> NodeKind {
  43. // Nodes are never self-bracketed, so we use that for nodes that instead set
  44. // child_count.
  45. static constexpr NodeKind Bracket[] = {
  46. #define CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, ...) \
  47. NodeKind::BracketName,
  48. #define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, ...) NodeKind::Name,
  49. #include "toolchain/parse/node_kind.def"
  50. };
  51. auto bracket = Bracket[AsInt()];
  52. CARBON_CHECK(bracket != *this) << *this;
  53. return bracket;
  54. }
  55. auto NodeKind::child_count() const -> int32_t {
  56. static constexpr int32_t ChildCount[] = {
  57. #define CARBON_PARSE_NODE_KIND_BRACKET(...) -1,
  58. #define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, Size, ...) Size,
  59. #include "toolchain/parse/node_kind.def"
  60. };
  61. auto child_count = ChildCount[AsInt()];
  62. CARBON_CHECK(child_count >= 0) << *this;
  63. return child_count;
  64. }
  65. auto NodeKind::CheckMatchesTokenKind(Lex::TokenKind token_kind, bool has_error)
  66. -> void {
  67. static constexpr Lex::TokenKind TokenIfValid[] = {
  68. #define CARBON_IF_VALID(LexTokenKind) LexTokenKind
  69. #define CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, LexTokenKind) \
  70. Lex::TokenKind::LexTokenKind,
  71. #define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, Size, LexTokenKind) \
  72. Lex::TokenKind::LexTokenKind,
  73. #include "toolchain/parse/node_kind.def"
  74. };
  75. static constexpr Lex::TokenKind TokenIfError[] = {
  76. #define CARBON_IF_VALID(LexTokenKind) Error
  77. #define CARBON_PARSE_NODE_KIND_BRACKET(Name, BracketName, LexTokenKind) \
  78. Lex::TokenKind::LexTokenKind,
  79. #define CARBON_PARSE_NODE_KIND_CHILD_COUNT(Name, Size, LexTokenKind) \
  80. Lex::TokenKind::LexTokenKind,
  81. #include "toolchain/parse/node_kind.def"
  82. };
  83. Lex::TokenKind expected_token_kind =
  84. has_error ? TokenIfError[AsInt()] : TokenIfValid[AsInt()];
  85. // Error indicates that the kind shouldn't be enforced.
  86. CARBON_CHECK(Lex::TokenKind::Error == expected_token_kind ||
  87. token_kind == expected_token_kind)
  88. << "Created parse node with NodeKind " << *this << " and has_error "
  89. << has_error << " for lexical token kind " << token_kind
  90. << ", but expected token kind " << expected_token_kind;
  91. }
  92. auto NodeKind::category() const -> NodeCategory {
  93. return definition().category();
  94. }
  95. auto NodeKind::definition() const -> const Definition& {
  96. static constexpr const Definition* Table[] = {
  97. #define CARBON_PARSE_NODE_KIND(Name) &Parse::Name::Kind,
  98. #include "toolchain/parse/node_kind.def"
  99. };
  100. return *Table[AsInt()];
  101. }
  102. } // namespace Carbon::Parse