@@ -88,21 +88,75 @@ class ActorIsolation {
8888 // / Set to true if this was parsed from SIL.
8989 unsigned silParsed : 1 ;
9090
91- unsigned parameterIndex : 27 ;
91+ // / The opaque value of an EncodedParameterIndex.
92+ // / Only meaningful for ActorInstance.
93+ unsigned encodedParameterIndex : 27 ;
94+
95+ class EncodedParameterIndex {
96+ enum : unsigned {
97+ SpecialIndex_Capture,
98+ SpecialIndex_Self,
99+ NumSpecialIndexes
100+ };
101+
102+ // / Either a special index or (parameter index + NumSpecialIndexes).
103+ unsigned value;
104+
105+ constexpr EncodedParameterIndex (unsigned value) : value(value) {}
106+
107+ public:
108+ static constexpr EncodedParameterIndex parameter (unsigned index) {
109+ return EncodedParameterIndex (NumSpecialIndexes + index);
110+ }
111+ static constexpr EncodedParameterIndex self () {
112+ return EncodedParameterIndex (SpecialIndex_Self);
113+ }
114+ static constexpr EncodedParameterIndex capture () {
115+ return EncodedParameterIndex (SpecialIndex_Capture);
116+ }
117+
118+ unsigned getParameterIndex () const {
119+ assert (value >= NumSpecialIndexes);
120+ return value - NumSpecialIndexes;
121+ }
122+ bool isSelf () const {
123+ return value == SpecialIndex_Self;
124+ }
125+ bool isCapture () const {
126+ return value == SpecialIndex_Capture;
127+ }
92128
93- ActorIsolation (Kind kind, NominalTypeDecl *actor, unsigned parameterIndex);
129+ static EncodedParameterIndex fromOpaqueValue (unsigned value) {
130+ return EncodedParameterIndex (value);
131+ }
132+ unsigned getOpaqueValue () const {
133+ return value;
134+ }
135+ };
94136
95- ActorIsolation (Kind kind, VarDecl *actor, unsigned parameterIndex);
137+ ActorIsolation (Kind kind, NominalTypeDecl *actor,
138+ EncodedParameterIndex parameterIndex);
96139
97- ActorIsolation (Kind kind, Expr *actor, unsigned parameterIndex);
140+ ActorIsolation (Kind kind, VarDecl *actor,
141+ EncodedParameterIndex parameterIndex);
142+
143+ ActorIsolation (Kind kind, Expr *actor,
144+ EncodedParameterIndex parameterIndex);
98145
99146 ActorIsolation (Kind kind, Type globalActor);
100147
148+ EncodedParameterIndex getEncodedParameterIndex () const {
149+ return EncodedParameterIndex::fromOpaqueValue (encodedParameterIndex);
150+ }
151+
101152public:
102153 // No-argument constructor needed for DenseMap use in PostfixCompletion.cpp
103154 explicit ActorIsolation (Kind kind = Unspecified, bool isSILParsed = false )
104155 : pointer(nullptr ), kind(kind), isolatedByPreconcurrency(false ),
105- silParsed(isSILParsed), parameterIndex(0 ) {}
156+ silParsed(isSILParsed), encodedParameterIndex(0 ) {
157+ // SIL's use of this has weaker invariants for now.
158+ assert (kind != ActorInstance || isSILParsed);
159+ }
106160
107161 static ActorIsolation forUnspecified () {
108162 return ActorIsolation (Unspecified);
@@ -125,19 +179,22 @@ class ActorIsolation {
125179
126180 static ActorIsolation forActorInstanceParameter (NominalTypeDecl *actor,
127181 unsigned parameterIndex) {
128- return ActorIsolation (ActorInstance, actor, parameterIndex + 1 );
182+ return ActorIsolation (ActorInstance, actor,
183+ EncodedParameterIndex::parameter (parameterIndex));
129184 }
130185
131186 static ActorIsolation forActorInstanceParameter (VarDecl *actor,
132187 unsigned parameterIndex) {
133- return ActorIsolation (ActorInstance, actor, parameterIndex + 1 );
188+ return ActorIsolation (ActorInstance, actor,
189+ EncodedParameterIndex::parameter (parameterIndex));
134190 }
135191
136192 static ActorIsolation forActorInstanceParameter (Expr *actor,
137193 unsigned parameterIndex);
138194
139195 static ActorIsolation forActorInstanceCapture (VarDecl *capturedActor) {
140- return ActorIsolation (ActorInstance, capturedActor, 0 );
196+ return ActorIsolation (ActorInstance, capturedActor,
197+ EncodedParameterIndex::capture ());
141198 }
142199
143200 static ActorIsolation forGlobalActor (Type globalActor) {
@@ -153,21 +210,14 @@ class ActorIsolation {
153210 static std::optional<ActorIsolation> forSILString (StringRef string) {
154211 auto kind =
155212 llvm::StringSwitch<std::optional<ActorIsolation::Kind>>(string)
156- .Case (" unspecified" ,
157- std::optional<ActorIsolation>(ActorIsolation::Unspecified))
158- .Case (" actor_instance" ,
159- std::optional<ActorIsolation>(ActorIsolation::ActorInstance))
160- .Case (" nonisolated" ,
161- std::optional<ActorIsolation>(ActorIsolation::Nonisolated))
162- .Case (" nonisolated_unsafe" , std::optional<ActorIsolation>(
163- ActorIsolation::NonisolatedUnsafe))
164- .Case (" global_actor" ,
165- std::optional<ActorIsolation>(ActorIsolation::GlobalActor))
166- .Case (" global_actor_unsafe" ,
167- std::optional<ActorIsolation>(ActorIsolation::GlobalActor))
213+ .Case (" unspecified" , ActorIsolation::Unspecified)
214+ .Case (" actor_instance" , ActorIsolation::ActorInstance)
215+ .Case (" nonisolated" , ActorIsolation::Nonisolated)
216+ .Case (" nonisolated_unsafe" , ActorIsolation::NonisolatedUnsafe)
217+ .Case (" global_actor" , ActorIsolation::GlobalActor)
218+ .Case (" global_actor_unsafe" , ActorIsolation::GlobalActor)
168219 .Case (" caller_isolation_inheriting" ,
169- std::optional<ActorIsolation>(
170- ActorIsolation::CallerIsolationInheriting))
220+ ActorIsolation::CallerIsolationInheriting)
171221 .Default (std::nullopt );
172222 if (kind == std::nullopt )
173223 return std::nullopt ;
@@ -187,17 +237,22 @@ class ActorIsolation {
187237 bool isNonisolatedUnsafe () const { return kind == NonisolatedUnsafe; }
188238
189239 // / Retrieve the parameter to which actor-instance isolation applies.
190- // /
191- // / Parameter 0 is `self`.
192- unsigned getActorInstanceParameter () const {
240+ unsigned getActorInstanceParameterIndex () const {
193241 assert (getKind () == ActorInstance);
194- return parameterIndex;
242+ return getEncodedParameterIndex ().getParameterIndex ();
243+ }
244+
245+ // / Given that this is actor instance isolation, is it a capture?
246+ bool isActorInstanceForCapture () const {
247+ assert (getKind () == ActorInstance);
248+ return getEncodedParameterIndex ().isCapture ();
195249 }
196250
197251 // / Returns true if this is an actor-instance isolation that additionally
198252 // / applies to the self parameter of a method.
199253 bool isActorInstanceForSelfParameter () const {
200- return getActorInstanceParameter () == 0 ;
254+ assert (getKind () == ActorInstance);
255+ return getEncodedParameterIndex ().isSelf ();
201256 }
202257
203258 bool isSILParsed () const { return silParsed; }
@@ -285,13 +340,13 @@ class ActorIsolation {
285340 id.AddPointer (pointer);
286341 id.AddBoolean (isolatedByPreconcurrency);
287342 id.AddBoolean (silParsed);
288- id.AddInteger (parameterIndex );
343+ id.AddInteger (encodedParameterIndex );
289344 }
290345
291346 friend llvm::hash_code hash_value (const ActorIsolation &state) {
292347 return llvm::hash_combine (state.kind , state.pointer ,
293348 state.isolatedByPreconcurrency , state.silParsed ,
294- state.parameterIndex );
349+ state.encodedParameterIndex );
295350 }
296351
297352 void print (llvm::raw_ostream &os) const ;
0 commit comments