@@ -53,6 +53,8 @@ class UnsafeUse {
53
53
ReferenceToUnsafeThroughTypealias,
54
54
// / A call to an unsafe declaration.
55
55
CallToUnsafe,
56
+ // / An unsafe argument in a call.
57
+ CallArgument,
56
58
// / A @preconcurrency import.
57
59
PreconcurrencyImport,
58
60
// / A use of withoutActuallyEscaping that lacks enforcement that the
@@ -91,6 +93,15 @@ class UnsafeUse {
91
93
92
94
MakeTemporarilyEscapableExpr *temporarilyEscaping;
93
95
96
+ struct {
97
+ Expr *call;
98
+ const Decl *calleeDecl;
99
+ TypeBase *paramType;
100
+ const void *argumentName;
101
+ unsigned argumentIndex;
102
+ Expr *argument;
103
+ } callArgument;
104
+
94
105
const ImportDecl *importDecl;
95
106
} storage;
96
107
@@ -201,6 +212,19 @@ class UnsafeUse {
201
212
decl, type, location);
202
213
}
203
214
215
+ static UnsafeUse forCallArgument (
216
+ Expr *call, const Decl *calleeDecl, Type paramType,
217
+ Identifier argumentName, unsigned argumentIndex, Expr *argument) {
218
+ UnsafeUse result (CallArgument);
219
+ result.storage .callArgument .call = call;
220
+ result.storage .callArgument .calleeDecl = calleeDecl;
221
+ result.storage .callArgument .paramType = paramType.getPointer ();
222
+ result.storage .callArgument .argumentName = argumentName.getAsOpaquePointer ();
223
+ result.storage .callArgument .argumentIndex = argumentIndex;
224
+ result.storage .callArgument .argument = argument;
225
+ return result;
226
+ }
227
+
204
228
static UnsafeUse forTemporarilyEscaping (MakeTemporarilyEscapableExpr *expr) {
205
229
UnsafeUse result (TemporarilyEscaping);
206
230
result.storage .temporarilyEscaping = expr;
@@ -242,6 +266,9 @@ class UnsafeUse {
242
266
return SourceLoc (
243
267
llvm::SMLoc::getFromPointer ((const char *)storage.entity .location ));
244
268
269
+ case CallArgument:
270
+ return storage.callArgument .call ->getLoc ();
271
+
245
272
case TemporarilyEscaping:
246
273
return storage.temporarilyEscaping ->getLoc ();
247
274
@@ -257,6 +284,7 @@ class UnsafeUse {
257
284
case Witness:
258
285
case TemporarilyEscaping:
259
286
case PreconcurrencyImport:
287
+ case CallArgument:
260
288
// Cannot replace location.
261
289
return ;
262
290
@@ -298,6 +326,9 @@ class UnsafeUse {
298
326
case CallToUnsafe:
299
327
return storage.entity .decl ;
300
328
329
+ case CallArgument:
330
+ return storage.callArgument .calleeDecl ;
331
+
301
332
case UnsafeConformance:
302
333
case TemporarilyEscaping:
303
334
return nullptr ;
@@ -330,6 +361,7 @@ class UnsafeUse {
330
361
case ReferenceToUnsafeThroughTypealias:
331
362
case ReferenceToUnsafeStorage:
332
363
case CallToUnsafe:
364
+ case CallArgument:
333
365
case UnsafeConformance:
334
366
case PreconcurrencyImport:
335
367
case TemporarilyEscaping:
@@ -360,6 +392,9 @@ class UnsafeUse {
360
392
case CallToUnsafe:
361
393
return storage.entity .type ;
362
394
395
+ case CallArgument:
396
+ return storage.callArgument .paramType ;
397
+
363
398
case TemporarilyEscaping:
364
399
return storage.temporarilyEscaping ->getOpaqueValue ()->getType ();
365
400
}
@@ -386,11 +421,24 @@ class UnsafeUse {
386
421
case ReferenceToUnsafeStorage:
387
422
case ReferenceToUnsafeThroughTypealias:
388
423
case CallToUnsafe:
424
+ case CallArgument:
389
425
case TemporarilyEscaping:
390
426
case PreconcurrencyImport:
391
427
return ProtocolConformanceRef::forInvalid ();
392
428
}
393
429
}
430
+
431
+ // / Get information about the call argument.
432
+ // /
433
+ // / Produces the argument name, argument index, and argument expression for
434
+ // / a unsafe use describing a call argument.
435
+ std::tuple<Identifier, unsigned , Expr *> getCallArgument () const {
436
+ assert (getKind () == CallArgument);
437
+ return std::make_tuple (
438
+ Identifier::getFromOpaquePointer (storage.callArgument .argumentName ),
439
+ storage.callArgument .argumentIndex ,
440
+ storage.callArgument .argument );
441
+ }
394
442
};
395
443
396
444
} // end namespace swift
0 commit comments