node_category.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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_CATEGORY_H_
  5. #define CARBON_TOOLCHAIN_PARSE_NODE_CATEGORY_H_
  6. #include "common/ostream.h"
  7. #include "llvm/ADT/BitmaskEnum.h"
  8. namespace Carbon::Parse {
  9. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
  10. // An X-macro for node categories. Uses should look like:
  11. //
  12. // #define CARBON_NODE_CATEGORY_FOR_XYZ(Name) ...
  13. // CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_XYZ)
  14. // #undef CARBON_NODE_CATEGORY_FOR_XYZ
  15. #define CARBON_NODE_CATEGORY(X) \
  16. X(Decl) \
  17. X(Expr) \
  18. X(ImplAs) \
  19. X(IntConst) \
  20. X(MemberExpr) \
  21. X(MemberName) \
  22. X(Modifier) \
  23. X(NonExprIdentifierName) \
  24. X(PackageName) \
  25. X(Pattern) \
  26. X(Requirement) \
  27. X(Statement)
  28. // Represents a set of keyword modifiers, using a separate bit per modifier.
  29. class NodeCategory : public Printable<NodeCategory> {
  30. private:
  31. // Use an enum to get incremental bit shifts.
  32. enum class BitShift : uint8_t {
  33. #define CARBON_NODE_CATEGORY_FOR_BIT_SHIFT(Name) Name,
  34. CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_BIT_SHIFT)
  35. #undef CARBON_NODE_CATEGORY_FOR_BIT_SHIFT
  36. // For `LLVM_MARK_AS_BITMASK_ENUM`.
  37. LargestValueMarker,
  38. };
  39. public:
  40. // Provide values as an enum. This doesn't expose these as NodeCategory
  41. // instances just due to the duplication of declarations that would cause.
  42. //
  43. // We expect this to grow, so are using a bigger size than needed.
  44. // NOLINTNEXTLINE(performance-enum-size)
  45. enum RawEnumType : uint32_t {
  46. #define CARBON_NODE_CATEGORY_FOR_BIT_MASK(Name) \
  47. Name = 1 << static_cast<uint8_t>(BitShift::Name),
  48. CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_BIT_MASK)
  49. #undef CARBON_NODE_CATEGORY_FOR_BIT_MASK
  50. // If you add a new category here, also add it to the Print function.
  51. None = 0,
  52. LLVM_MARK_AS_BITMASK_ENUM(
  53. /*LargestValue=*/1
  54. << (static_cast<uint8_t>(BitShift::LargestValueMarker) - 1))
  55. };
  56. // Support implicit conversion so that the difference with the member enum is
  57. // opaque.
  58. // NOLINTNEXTLINE(google-explicit-constructor)
  59. constexpr NodeCategory(RawEnumType value) : value_(value) {}
  60. // Returns true if there's a non-empty set intersection.
  61. constexpr auto HasAnyOf(NodeCategory other) const -> bool {
  62. return value_ & other.value_;
  63. }
  64. // Returns the set inverse.
  65. constexpr auto operator~() const -> NodeCategory { return ~value_; }
  66. friend auto operator==(NodeCategory lhs, NodeCategory rhs) -> bool {
  67. return lhs.value_ == rhs.value_;
  68. }
  69. auto Print(llvm::raw_ostream& out) const -> void;
  70. private:
  71. RawEnumType value_;
  72. };
  73. } // namespace Carbon::Parse
  74. #endif // CARBON_TOOLCHAIN_PARSE_NODE_CATEGORY_H_