Add an EnumMaskBase type (#6053)

This is a bit of an experiment to see if there's a reasonable way to
write a shared enum type, rather than writing per-case wrappers for
things like `HasTypeQualifiers` or the printing. I think it's a bit
borderline complexity right now, but I'm not sure I can reduce it much
further.

This changes from things like `Internal::EnumClassName##RawEnum` to
`Internal::EnumClassName##Data::RawEnum` so that the enum entries can
have back references to bit shifts without needing to know the
containing type name. Because I'm trying to reduce duplication between
mask and non-mask enums, I did this to non-mask enums too.

This was motivated by #6035 adding another enum mask (which will grow
more entries, and is intended to switch if this is accepted), but I'm
not using that PR as a base here because I didn't want the merge
dependency.
This commit is contained in:
Jon Ross-Perkins
2025-09-12 18:04:10 +00:00
committed by GitHub
parent 508a88e2a9
commit 6cc5d7ed2a
17 changed files with 368 additions and 229 deletions
+4 -4
View File
@@ -773,7 +773,7 @@ static auto CanUseValueOfInitializer(const SemIR::File& sem_ir,
// of an expression of the given category.
static auto CanAddQualifiers(SemIR::TypeQualifiers quals,
SemIR::ExprCategory cat) -> bool {
if (HasTypeQualifier(quals, SemIR::TypeQualifiers::MaybeUnformed) &&
if (quals.HasAnyOf(SemIR::TypeQualifiers::MaybeUnformed) &&
!SemIR::IsRefCategory(cat)) {
// `MaybeUnformed(T)` may have a different value representation or
// initializing representation from `T`, so only allow it to be added for a
@@ -794,13 +794,13 @@ static auto CanAddQualifiers(SemIR::TypeQualifiers quals,
static auto CanRemoveQualifiers(SemIR::TypeQualifiers quals,
SemIR::ExprCategory cat, bool allow_unsafe)
-> bool {
if (HasTypeQualifier(quals, SemIR::TypeQualifiers::Const) && !allow_unsafe &&
if (quals.HasAnyOf(SemIR::TypeQualifiers::Const) && !allow_unsafe &&
SemIR::IsRefCategory(cat)) {
// Removing `const` is an unsafe conversion for a reference expression.
return false;
}
if (HasTypeQualifier(quals, SemIR::TypeQualifiers::Partial) &&
if (quals.HasAnyOf(SemIR::TypeQualifiers::Partial) &&
(!allow_unsafe || cat == SemIR::ExprCategory::Initializing)) {
// TODO: Allow removing `partial` for initializing expressions as a safe
// conversion. `PerformBuiltinConversion` will need to initialize the vptr
@@ -808,7 +808,7 @@ static auto CanRemoveQualifiers(SemIR::TypeQualifiers quals,
return false;
}
if (HasTypeQualifier(quals, SemIR::TypeQualifiers::MaybeUnformed) &&
if (quals.HasAnyOf(SemIR::TypeQualifiers::MaybeUnformed) &&
(!allow_unsafe || cat == SemIR::ExprCategory::Initializing)) {
// As an unsafe conversion, `MaybeUnformed` can be removed from a value or
// reference expression.