Repository: carbon-language/carbon-lang
File: toolchain/check/keyword_modifier_set.h (C/C++)

Code before:
// 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, 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.
  // NOLINTNEXTLINE(performance-enum-size)
  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,

    // At most one of these declaration modifiers allowed for a given
    // declaration:
    Abstract = 1 << 3,
    Base = 1 << 4,
    Default = 1 << 5,
    Export = 1 << 6,
    Extend = 1 << 7,

Review comment (suggestion):
If we want to keep the number of modifier groups down, we could put `extern` and `extend` in the same group, since they're mutually exclusive. There's at least a vague semantic connection between them (they both control how the inner declaration adds names to the outer context) -- perhaps enough to justify grouping them? I don't think I have a strong preference either way though.

Code after:
// 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.
  // NOLINTNEXTLINE(performance-enum-size)
  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,