[NFC] Encapsulate the parameter index of an ActorIsolation

This commit is contained in:
John McCall
2025-06-20 14:58:16 +09:00
parent 39e011e083
commit 2eee30dfbe
7 changed files with 116 additions and 46 deletions

View File

@@ -88,21 +88,74 @@ private:
/// Set to true if this was parsed from SIL.
unsigned silParsed : 1;
unsigned parameterIndex : 27;
/// The opaque value of an EncodedParameterIndex.
/// Only meaningful for ActorInstance.
unsigned encodedParameterIndex : 27;
ActorIsolation(Kind kind, NominalTypeDecl *actor, unsigned parameterIndex);
class EncodedParameterIndex {
enum : unsigned {
SpecialIndex_Capture,
SpecialIndex_Self,
NumSpecialIndexes
};
ActorIsolation(Kind kind, VarDecl *actor, unsigned parameterIndex);
/// Either a special index or (parameter index + NumSpecialIndexes).
unsigned value;
ActorIsolation(Kind kind, Expr *actor, unsigned parameterIndex);
constexpr EncodedParameterIndex(unsigned value) : value(value) {}
public:
static constexpr EncodedParameterIndex parameter(unsigned index) {
return EncodedParameterIndex(NumSpecialIndexes + index);
}
static constexpr EncodedParameterIndex self() {
return EncodedParameterIndex(SpecialIndex_Self);
}
static constexpr EncodedParameterIndex capture() {
return EncodedParameterIndex(SpecialIndex_Capture);
}
unsigned getParameterIndex() const {
assert(value >= NumSpecialIndexes);
return value - NumSpecialIndexes;
}
bool isSelf() const {
return value == SpecialIndex_Self;
}
bool isCapture() const {
return value == SpecialIndex_Capture;
}
static EncodedParameterIndex fromOpaqueValue(unsigned value) {
return EncodedParameterIndex(value);
}
unsigned getOpaqueValue() const {
return value;
}
};
ActorIsolation(Kind kind, NominalTypeDecl *actor,
EncodedParameterIndex parameterIndex);
ActorIsolation(Kind kind, VarDecl *actor,
EncodedParameterIndex parameterIndex);
ActorIsolation(Kind kind, Expr *actor,
EncodedParameterIndex parameterIndex);
ActorIsolation(Kind kind, Type globalActor);
EncodedParameterIndex getEncodedParameterIndex() const {
return EncodedParameterIndex::fromOpaqueValue(encodedParameterIndex);
}
public:
// No-argument constructor needed for DenseMap use in PostfixCompletion.cpp
explicit ActorIsolation(Kind kind = Unspecified, bool isSILParsed = false)
: pointer(nullptr), kind(kind), isolatedByPreconcurrency(false),
silParsed(isSILParsed), parameterIndex(0) {}
silParsed(isSILParsed), encodedParameterIndex(0) {
assert(kind != ActorInstance);
}
static ActorIsolation forUnspecified() {
return ActorIsolation(Unspecified);
@@ -125,19 +178,22 @@ public:
static ActorIsolation forActorInstanceParameter(NominalTypeDecl *actor,
unsigned parameterIndex) {
return ActorIsolation(ActorInstance, actor, parameterIndex + 1);
return ActorIsolation(ActorInstance, actor,
EncodedParameterIndex::parameter(parameterIndex));
}
static ActorIsolation forActorInstanceParameter(VarDecl *actor,
unsigned parameterIndex) {
return ActorIsolation(ActorInstance, actor, parameterIndex + 1);
return ActorIsolation(ActorInstance, actor,
EncodedParameterIndex::parameter(parameterIndex));
}
static ActorIsolation forActorInstanceParameter(Expr *actor,
unsigned parameterIndex);
static ActorIsolation forActorInstanceCapture(VarDecl *capturedActor) {
return ActorIsolation(ActorInstance, capturedActor, 0);
return ActorIsolation(ActorInstance, capturedActor,
EncodedParameterIndex::capture());
}
static ActorIsolation forGlobalActor(Type globalActor) {
@@ -187,17 +243,22 @@ public:
bool isNonisolatedUnsafe() const { return kind == NonisolatedUnsafe; }
/// Retrieve the parameter to which actor-instance isolation applies.
///
/// Parameter 0 is `self`.
unsigned getActorInstanceParameter() const {
unsigned getActorInstanceParameterIndex() const {
assert(getKind() == ActorInstance);
return parameterIndex;
return getEncodedParameterIndex().getParameterIndex();
}
/// Given that this is actor instance isolation, is it a capture?
bool isActorInstanceForCapture() const {
assert(getKind() == ActorInstance);
return getEncodedParameterIndex().isCapture();
}
/// Returns true if this is an actor-instance isolation that additionally
/// applies to the self parameter of a method.
bool isActorInstanceForSelfParameter() const {
return getActorInstanceParameter() == 0;
assert(getKind() == ActorInstance);
return getEncodedParameterIndex().isSelf();
}
bool isSILParsed() const { return silParsed; }
@@ -285,13 +346,13 @@ public:
id.AddPointer(pointer);
id.AddBoolean(isolatedByPreconcurrency);
id.AddBoolean(silParsed);
id.AddInteger(parameterIndex);
id.AddInteger(encodedParameterIndex);
}
friend llvm::hash_code hash_value(const ActorIsolation &state) {
return llvm::hash_combine(state.kind, state.pointer,
state.isolatedByPreconcurrency, state.silParsed,
state.parameterIndex);
state.encodedParameterIndex);
}
void print(llvm::raw_ostream &os) const;