mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
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:
@@ -23,6 +23,9 @@
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
CARBON_DEFINE_ENUM_MASK_NAMES(DependentInstKind) = {
|
||||
CARBON_DEPENDENT_INST_KIND(CARBON_ENUM_MASK_NAME_STRING)};
|
||||
|
||||
static auto MakeSelfSpecificId(Context& context, SemIR::GenericId generic_id)
|
||||
-> SemIR::SpecificId;
|
||||
|
||||
@@ -302,14 +305,14 @@ auto AttachDependentInstToCurrentGeneric(Context& context,
|
||||
if (context.generic_region_stack().Empty()) {
|
||||
// This should only happen for `*Decl` instructions, never for template
|
||||
// actions.
|
||||
CARBON_CHECK((dep_kind & DependentInst::Template) == DependentInst::None);
|
||||
CARBON_CHECK(!dep_kind.HasAnyOf(DependentInstKind::Template));
|
||||
return;
|
||||
}
|
||||
|
||||
context.generic_region_stack().AddDependentInst(dependent_inst.inst_id);
|
||||
|
||||
// If the type is symbolic, replace it with a type specific to this generic.
|
||||
if ((dep_kind & DependentInst::SymbolicType) != DependentInst::None) {
|
||||
if (dep_kind.HasAnyOf(DependentInstKind::SymbolicType)) {
|
||||
auto inst = context.insts().Get(inst_id);
|
||||
auto type_id = AddGenericTypeToEvalBlock(context, SemIR::LocId(inst_id),
|
||||
inst.type_id());
|
||||
@@ -327,7 +330,7 @@ auto AttachDependentInstToCurrentGeneric(Context& context,
|
||||
// we'll need to evaluate this instruction when forming the specific. Update
|
||||
// the constant value of the instruction to refer to the result of that
|
||||
// eventual evaluation.
|
||||
if ((dep_kind & DependentInst::SymbolicConstant) != DependentInst::None) {
|
||||
if (dep_kind.HasAnyOf(DependentInstKind::SymbolicConstant)) {
|
||||
// Update the constant value to refer to this generic.
|
||||
context.constant_values().Set(
|
||||
inst_id, AddGenericConstantToEvalBlock(context, inst_id));
|
||||
@@ -335,7 +338,7 @@ auto AttachDependentInstToCurrentGeneric(Context& context,
|
||||
|
||||
// If the instruction is a template action, add it directly to this position
|
||||
// in the eval block.
|
||||
if ((dep_kind & DependentInst::Template) != DependentInst::None) {
|
||||
if (dep_kind.HasAnyOf(DependentInstKind::Template)) {
|
||||
AddTemplateActionToEvalBlock(context, inst_id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user