keyword_modifier_set.h 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. #ifndef CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_
  5. #define CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_
  6. #include "llvm/ADT/BitmaskEnum.h"
  7. #include "toolchain/sem_ir/name_scope.h"
  8. namespace Carbon::Check {
  9. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
  10. // The order of modifiers. Each of these corresponds to a group on
  11. // KeywordModifierSet, and can be used as an array index.
  12. enum class ModifierOrder : int8_t { Access, Extern, Decl, Last = Decl };
  13. // Represents a set of keyword modifiers, using a separate bit per modifier.
  14. class KeywordModifierSet {
  15. public:
  16. // Provide values as an enum. This doesn't expose these as KeywordModifierSet
  17. // instances just due to the duplication of declarations that would cause.
  18. //
  19. // We expect this to grow, so are using a bigger size than needed.
  20. // NOLINTNEXTLINE(performance-enum-size)
  21. enum RawEnumType : uint32_t {
  22. // At most one of these access modifiers allowed for a given declaration,
  23. // and if present it must be first:
  24. Private = 1 << 0,
  25. Protected = 1 << 1,
  26. // Extern is standalone.
  27. Extern = 1 << 2,
  28. // At most one of these declaration modifiers allowed for a given
  29. // declaration:
  30. Abstract = 1 << 3,
  31. Base = 1 << 4,
  32. Default = 1 << 5,
  33. Export = 1 << 6,
  34. Extend = 1 << 7,
  35. Final = 1 << 8,
  36. Impl = 1 << 9,
  37. Virtual = 1 << 10,
  38. // Sets of modifiers:
  39. Access = Private | Protected,
  40. Class = Abstract | Base,
  41. Method = Abstract | Impl | Virtual,
  42. ImplDecl = Extend | Final,
  43. Interface = Default | Final,
  44. Decl = Class | Method | ImplDecl | Interface | Export,
  45. None = 0,
  46. LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Virtual)
  47. };
  48. // Default construct to empty.
  49. explicit KeywordModifierSet() : set_(None) {}
  50. // Support implicit conversion so that the difference with the member enum is
  51. // opaque.
  52. // NOLINTNEXTLINE(google-explicit-constructor)
  53. constexpr KeywordModifierSet(RawEnumType set) : set_(set) {}
  54. // Adds entries to the set.
  55. auto Add(KeywordModifierSet set) -> void { set_ |= set.set_; }
  56. // Removes entries from the set.
  57. auto Remove(KeywordModifierSet set) -> void { set_ &= ~set.set_; }
  58. // Returns true if there's a non-empty set intersection.
  59. constexpr auto HasAnyOf(KeywordModifierSet other) -> bool {
  60. return set_ & other.set_;
  61. }
  62. // Returns the access kind from modifiers.
  63. auto GetAccessKind() -> SemIR::AccessKind {
  64. if (HasAnyOf(KeywordModifierSet::Protected)) {
  65. return SemIR::AccessKind::Protected;
  66. }
  67. if (HasAnyOf(KeywordModifierSet::Private)) {
  68. return SemIR::AccessKind::Private;
  69. }
  70. return SemIR::AccessKind::Public;
  71. }
  72. // Returns true if empty.
  73. constexpr auto empty() -> bool { return !set_; }
  74. // Returns the set intersection.
  75. constexpr auto operator&(KeywordModifierSet other) -> KeywordModifierSet {
  76. return set_ & other.set_;
  77. }
  78. // Returns the set inverse.
  79. auto operator~() -> KeywordModifierSet { return ~set_; }
  80. private:
  81. RawEnumType set_;
  82. };
  83. static_assert(!KeywordModifierSet(KeywordModifierSet::Access)
  84. .HasAnyOf(KeywordModifierSet::Extern) &&
  85. !KeywordModifierSet(KeywordModifierSet::Access |
  86. KeywordModifierSet::Extern)
  87. .HasAnyOf(KeywordModifierSet::Decl),
  88. "Order-related sets must not overlap");
  89. static_assert(~KeywordModifierSet::None ==
  90. (KeywordModifierSet::Access | KeywordModifierSet::Extern |
  91. KeywordModifierSet::Decl),
  92. "Modifier missing from all modifier sets");
  93. } // namespace Carbon::Check
  94. #endif // CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_