node_category.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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(NonExprName) \
  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. enum RawEnumType : uint32_t {
  45. #define CARBON_NODE_CATEGORY_FOR_BIT_MASK(Name) \
  46. Name = 1 << static_cast<uint8_t>(BitShift::Name),
  47. CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_BIT_MASK)
  48. #undef CARBON_NODE_CATEGORY_FOR_BIT_MASK
  49. // If you add a new category here, also add it to the Print function.
  50. None = 0,
  51. LLVM_MARK_AS_BITMASK_ENUM(
  52. /*LargestValue=*/1
  53. << (static_cast<uint8_t>(BitShift::LargestValueMarker) - 1))
  54. };
  55. // Support implicit conversion so that the difference with the member enum is
  56. // opaque.
  57. // NOLINTNEXTLINE(google-explicit-constructor)
  58. constexpr NodeCategory(RawEnumType value) : value_(value) {}
  59. // Returns true if there's a non-empty set intersection.
  60. constexpr auto HasAnyOf(NodeCategory other) const -> bool {
  61. return value_ & other.value_;
  62. }
  63. // Returns the set inverse.
  64. constexpr auto operator~() const -> NodeCategory { return ~value_; }
  65. friend auto operator==(NodeCategory lhs, NodeCategory rhs) -> bool {
  66. return lhs.value_ == rhs.value_;
  67. }
  68. auto Print(llvm::raw_ostream& out) const -> void;
  69. private:
  70. RawEnumType value_;
  71. };
  72. } // namespace Carbon::Parse
  73. #endif // CARBON_TOOLCHAIN_PARSE_NODE_CATEGORY_H_