| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #ifndef CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_
- #define CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_
- #include <optional>
- #include "llvm/ADT/BitmaskEnum.h"
- #include "toolchain/sem_ir/name_scope.h"
- namespace Carbon::Check {
- LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
- // The order of modifiers. Each of these corresponds to a group on
- // KeywordModifierSet, and can be used as an array index.
- enum class ModifierOrder : int8_t { Access, Extern, Extend, Decl, Last = Decl };
- // Represents a set of keyword modifiers, using a separate bit per modifier.
- class KeywordModifierSet {
- public:
- // Provide values as an enum. This doesn't expose these as KeywordModifierSet
- // instances just due to the duplication of declarations that would cause.
- //
- // We expect this to grow, so are using a bigger size than needed.
- enum RawEnumType : uint32_t {
- // At most one of these access modifiers allowed for a given declaration,
- // and if present it must be first:
- Private = 1 << 0,
- Protected = 1 << 1,
- // Extern is standalone.
- Extern = 1 << 2,
- // Extend can be combined with Final, but no others in the group below.
- Extend = 1 << 3,
- // At most one of these declaration modifiers allowed for a given
- // declaration:
- Abstract = 1 << 4,
- Base = 1 << 5,
- Default = 1 << 6,
- Export = 1 << 7,
- Final = 1 << 8,
- Impl = 1 << 9,
- Virtual = 1 << 10,
- Returned = 1 << 11,
- // Sets of modifiers:
- Access = Private | Protected,
- Class = Abstract | Base,
- Method = Abstract | Impl | Virtual,
- ImplDecl = Extend | Final,
- Interface = Default | Final,
- Decl = Class | Method | Interface | Export | Returned,
- None = 0,
- LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Returned)
- };
- // Default construct to empty.
- explicit KeywordModifierSet() : set_(None) {}
- // Support implicit conversion so that the difference with the member enum is
- // opaque.
- explicit(false) constexpr KeywordModifierSet(RawEnumType set) : set_(set) {}
- // Adds entries to the set.
- auto Add(KeywordModifierSet set) -> void { set_ |= set.set_; }
- // Removes entries from the set.
- auto Remove(KeywordModifierSet set) -> void { set_ &= ~set.set_; }
- // Returns true if there's a non-empty set intersection.
- constexpr auto HasAnyOf(KeywordModifierSet other) const -> bool {
- return set_ & other.set_;
- }
- // Return a builder that returns the new enumeration type once a series of
- // mapping `Case`s and a final `Default` are provided. For example:
- // ```
- // auto e = set.ToEnum<SomeEnum>()
- // .Case(KeywordModifierSet::A, SomeEnum::A)
- // .Case(KeywordModifierSet::B, SomeEnum::B)
- // .Default(SomeEnum::DefaultValue);
- // ```
- template <typename T>
- auto ToEnum() const -> auto {
- class Converter {
- public:
- explicit Converter(const KeywordModifierSet& set) : set_(set) {}
- auto Case(RawEnumType raw_enumerator, T result) -> Converter& {
- if (set_.HasAnyOf(raw_enumerator)) {
- result_ = result;
- }
- return *this;
- }
- auto Default(T default_value) -> T {
- if (result_) {
- return *result_;
- }
- return default_value;
- }
- private:
- const KeywordModifierSet& set_;
- std::optional<T> result_;
- };
- return Converter(*this);
- }
- // Returns the access kind from modifiers.
- auto GetAccessKind() const -> SemIR::AccessKind {
- if (HasAnyOf(KeywordModifierSet::Protected)) {
- return SemIR::AccessKind::Protected;
- }
- if (HasAnyOf(KeywordModifierSet::Private)) {
- return SemIR::AccessKind::Private;
- }
- return SemIR::AccessKind::Public;
- }
- // Returns true if empty.
- constexpr auto empty() const -> bool { return !set_; }
- // Returns the set intersection.
- constexpr auto operator&(KeywordModifierSet other) const
- -> KeywordModifierSet {
- return set_ & other.set_;
- }
- // Returns the set inverse.
- auto operator~() const -> KeywordModifierSet { return ~set_; }
- private:
- RawEnumType set_;
- };
- static_assert(!KeywordModifierSet(KeywordModifierSet::Access)
- .HasAnyOf(KeywordModifierSet::Extern) &&
- !KeywordModifierSet(KeywordModifierSet::Access |
- KeywordModifierSet::Extern |
- KeywordModifierSet::Extend)
- .HasAnyOf(KeywordModifierSet::Decl),
- "Order-related sets must not overlap");
- static_assert(~KeywordModifierSet::None ==
- (KeywordModifierSet::Access | KeywordModifierSet::Extern |
- KeywordModifierSet::Extend | KeywordModifierSet::Decl),
- "Modifier missing from all modifier sets");
- } // namespace Carbon::Check
- #endif // CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_
|