@@ -88,21 +88,75 @@ class ActorIsolation {
88
88
// / Set to true if this was parsed from SIL.
89
89
unsigned silParsed : 1 ;
90
90
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
+ }
92
128
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
+ };
94
136
95
- ActorIsolation (Kind kind, VarDecl *actor, unsigned parameterIndex);
137
+ ActorIsolation (Kind kind, NominalTypeDecl *actor,
138
+ EncodedParameterIndex parameterIndex);
96
139
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);
98
145
99
146
ActorIsolation (Kind kind, Type globalActor);
100
147
148
+ EncodedParameterIndex getEncodedParameterIndex () const {
149
+ return EncodedParameterIndex::fromOpaqueValue (encodedParameterIndex);
150
+ }
151
+
101
152
public:
102
153
// No-argument constructor needed for DenseMap use in PostfixCompletion.cpp
103
154
explicit ActorIsolation (Kind kind = Unspecified, bool isSILParsed = false )
104
155
: 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
+ }
106
160
107
161
static ActorIsolation forUnspecified () {
108
162
return ActorIsolation (Unspecified);
@@ -125,19 +179,22 @@ class ActorIsolation {
125
179
126
180
static ActorIsolation forActorInstanceParameter (NominalTypeDecl *actor,
127
181
unsigned parameterIndex) {
128
- return ActorIsolation (ActorInstance, actor, parameterIndex + 1 );
182
+ return ActorIsolation (ActorInstance, actor,
183
+ EncodedParameterIndex::parameter (parameterIndex));
129
184
}
130
185
131
186
static ActorIsolation forActorInstanceParameter (VarDecl *actor,
132
187
unsigned parameterIndex) {
133
- return ActorIsolation (ActorInstance, actor, parameterIndex + 1 );
188
+ return ActorIsolation (ActorInstance, actor,
189
+ EncodedParameterIndex::parameter (parameterIndex));
134
190
}
135
191
136
192
static ActorIsolation forActorInstanceParameter (Expr *actor,
137
193
unsigned parameterIndex);
138
194
139
195
static ActorIsolation forActorInstanceCapture (VarDecl *capturedActor) {
140
- return ActorIsolation (ActorInstance, capturedActor, 0 );
196
+ return ActorIsolation (ActorInstance, capturedActor,
197
+ EncodedParameterIndex::capture ());
141
198
}
142
199
143
200
static ActorIsolation forGlobalActor (Type globalActor) {
@@ -153,21 +210,14 @@ class ActorIsolation {
153
210
static std::optional<ActorIsolation> forSILString (StringRef string) {
154
211
auto kind =
155
212
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)
168
219
.Case (" caller_isolation_inheriting" ,
169
- std::optional<ActorIsolation>(
170
- ActorIsolation::CallerIsolationInheriting))
220
+ ActorIsolation::CallerIsolationInheriting)
171
221
.Default (std::nullopt);
172
222
if (kind == std::nullopt)
173
223
return std::nullopt;
@@ -187,17 +237,22 @@ class ActorIsolation {
187
237
bool isNonisolatedUnsafe () const { return kind == NonisolatedUnsafe; }
188
238
189
239
// / Retrieve the parameter to which actor-instance isolation applies.
190
- // /
191
- // / Parameter 0 is `self`.
192
- unsigned getActorInstanceParameter () const {
240
+ unsigned getActorInstanceParameterIndex () const {
193
241
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 ();
195
249
}
196
250
197
251
// / Returns true if this is an actor-instance isolation that additionally
198
252
// / applies to the self parameter of a method.
199
253
bool isActorInstanceForSelfParameter () const {
200
- return getActorInstanceParameter () == 0 ;
254
+ assert (getKind () == ActorInstance);
255
+ return getEncodedParameterIndex ().isSelf ();
201
256
}
202
257
203
258
bool isSILParsed () const { return silParsed; }
@@ -285,13 +340,13 @@ class ActorIsolation {
285
340
id.AddPointer (pointer);
286
341
id.AddBoolean (isolatedByPreconcurrency);
287
342
id.AddBoolean (silParsed);
288
- id.AddInteger (parameterIndex );
343
+ id.AddInteger (encodedParameterIndex );
289
344
}
290
345
291
346
friend llvm::hash_code hash_value (const ActorIsolation &state) {
292
347
return llvm::hash_combine (state.kind , state.pointer ,
293
348
state.isolatedByPreconcurrency , state.silParsed ,
294
- state.parameterIndex );
349
+ state.encodedParameterIndex );
295
350
}
296
351
297
352
void print (llvm::raw_ostream &os) const ;
0 commit comments