| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- // 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 "common/enum_mask_base.h"
- #include "toolchain/sem_ir/name_scope.h"
- namespace Carbon::Check {
- // 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 };
- // A single X-macro to cover modifier groups. These are split out to make groups
- // clearer.
- #define CARBON_KEYWORD_MODIFIER_SET(X) \
- /* At most one of these access modifiers allowed for a given declaration, \
- * and if present it must be first. */ \
- X(Private) \
- X(Protected) \
- \
- /* Extern is standalone. */ \
- X(Extern) \
- \
- /* Extend can be combined with Final, but no others in the group below. */ \
- X(Extend) \
- \
- /* At most one of these declaration modifiers allowed for a given \
- * declaration. */ \
- X(Abstract) \
- X(Base) \
- X(Default) \
- X(Export) \
- X(Final) \
- X(Impl) \
- X(Override) \
- X(Returned) \
- X(Virtual)
- // We expect this to grow, so are using a bigger size than needed.
- CARBON_DEFINE_RAW_ENUM_MASK(KeywordModifierSet, uint32_t) {
- CARBON_KEYWORD_MODIFIER_SET(CARBON_RAW_ENUM_MASK_ENUMERATOR)
- };
- // Represents a set of keyword modifiers, using a separate bit per modifier.
- class KeywordModifierSet : public CARBON_ENUM_MASK_BASE(KeywordModifierSet) {
- public:
- CARBON_KEYWORD_MODIFIER_SET(CARBON_ENUM_MASK_CONSTANT_DECL)
- // Sets of modifiers.
- static const KeywordModifierSet Access;
- static const KeywordModifierSet Class;
- static const KeywordModifierSet Method;
- static const KeywordModifierSet ImplDecl;
- static const KeywordModifierSet Interface;
- static const KeywordModifierSet Decl;
- // 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(KeywordModifierSet other, T result) -> Converter& {
- if (set_.HasAnyOf(other)) {
- 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;
- }
- };
- #define CARBON_KEYWORD_MODIFIER_SET_WITH_TYPE(X) \
- CARBON_ENUM_MASK_CONSTANT_DEFINITION(KeywordModifierSet, X)
- CARBON_KEYWORD_MODIFIER_SET(CARBON_KEYWORD_MODIFIER_SET_WITH_TYPE)
- #undef CARBON_KEYWORD_MODIFIER_SET_WITH_TYPE
- inline constexpr KeywordModifierSet KeywordModifierSet::Access(Private |
- Protected);
- inline constexpr KeywordModifierSet KeywordModifierSet::Class(Abstract | Base);
- inline constexpr KeywordModifierSet KeywordModifierSet::Method(Abstract |
- Override |
- Virtual);
- inline constexpr KeywordModifierSet KeywordModifierSet::ImplDecl(Extend |
- Final);
- inline constexpr KeywordModifierSet KeywordModifierSet::Interface(Default |
- Final);
- inline constexpr KeywordModifierSet KeywordModifierSet::Decl(Class | Method |
- Impl | Interface |
- Export | Returned);
- static_assert(
- !KeywordModifierSet::Access.HasAnyOf(KeywordModifierSet::Extern) &&
- !(KeywordModifierSet::Access | KeywordModifierSet::Extern |
- KeywordModifierSet::Extend)
- .HasAnyOf(KeywordModifierSet::Decl),
- "Order-related sets must not overlap");
- #define CARBON_KEYWORD_MODIFIER_SET_IN_GROUP(Modifier) \
- static_assert((KeywordModifierSet::Access | KeywordModifierSet::Extern | \
- KeywordModifierSet::Extend | KeywordModifierSet::Decl) \
- .HasAnyOf(KeywordModifierSet::Modifier), \
- "Modifier missing from all modifier sets: " #Modifier);
- CARBON_KEYWORD_MODIFIER_SET(CARBON_KEYWORD_MODIFIER_SET_IN_GROUP)
- #undef CARBON_KEYWORD_MODIFIER_SET_IN_GROUP
- } // namespace Carbon::Check
- #endif // CARBON_TOOLCHAIN_CHECK_KEYWORD_MODIFIER_SET_H_
|