@@ -260,46 +260,116 @@ class AbstractionPattern {
260
260
OpaqueDerivativeFunction,
261
261
};
262
262
263
- class EncodedForeignErrorInfo {
263
+ class EncodedForeignInfo {
264
264
unsigned Value;
265
+
266
+ enum Error_t {
267
+ Error,
268
+ };
269
+
270
+ enum Async_t {
271
+ Async,
272
+ };
273
+
274
+ public:
275
+ enum ForeignKind {
276
+ IsNotForeign,
277
+ IsError,
278
+ IsAsync,
279
+ };
280
+
281
+ private:
282
+ friend AbstractionPattern;
283
+
284
+ EncodedForeignInfo () : Value(0 ) {}
285
+ EncodedForeignInfo (Error_t,
286
+ unsigned errorParameterIndex,
287
+ bool replaceParamWithVoid,
288
+ bool stripsResultOptionality)
289
+ : Value(1
290
+ + (unsigned (IsError) - 1 )
291
+ + (unsigned (stripsResultOptionality) << 1 )
292
+ + (unsigned (replaceParamWithVoid) << 2 )
293
+ + (errorParameterIndex << 3 )) {
294
+ assert (getKind () == IsError);
295
+ assert (getErrorParamIndex () == errorParameterIndex);
296
+ assert (hasErrorParameterReplacedWithVoid () == replaceParamWithVoid);
297
+ assert (errorStripsResultOptionality () == stripsResultOptionality);
298
+ }
299
+
300
+ EncodedForeignInfo (Async_t,
301
+ unsigned completionParameterIndex,
302
+ Optional<unsigned > completionErrorParameterIndex)
303
+ : Value(1
304
+ + (unsigned (IsAsync) - 1 )
305
+ + (unsigned (completionParameterIndex) << 1 )
306
+ + ((completionErrorParameterIndex ? *completionErrorParameterIndex + 1
307
+ : 0 ) << 21 )) {
308
+ assert (getKind () == IsAsync);
309
+ assert (getAsyncCompletionHandlerParamIndex () == completionParameterIndex);
310
+ assert (getAsyncCompletionHandlerErrorParamIndex () == completionErrorParameterIndex);
311
+ }
265
312
266
313
public:
267
- EncodedForeignErrorInfo () : Value(0 ) {}
268
- EncodedForeignErrorInfo (unsigned errorParameterIndex,
269
- bool replaceParamWithVoid,
270
- bool stripsResultOptionality)
271
- : Value(1 +
272
- (unsigned (stripsResultOptionality)) +
273
- (unsigned (replaceParamWithVoid) << 1 ) +
274
- (errorParameterIndex << 2 )) {}
275
-
276
- static EncodedForeignErrorInfo
277
- encode (const Optional<ForeignErrorConvention> &foreignError);
314
+ static EncodedForeignInfo
315
+ encode (const Optional<ForeignErrorConvention> &foreignError,
316
+ const Optional<ForeignAsyncConvention> &foreignAsync);
278
317
279
318
bool hasValue () const { return Value != 0 ; }
280
- bool hasErrorParameter () const { return hasValue (); }
281
- bool hasUnreplacedErrorParameter () const {
282
- return hasValue () && !isErrorParameterReplacedWithVoid ();
319
+ ForeignKind getKind () const {
320
+ if (!hasValue ())
321
+ return IsNotForeign;
322
+
323
+ return ForeignKind ((Value - 1 & 1 ) + 1 );
324
+ }
325
+
326
+ bool errorStripsResultOptionality () const {
327
+ if (getKind () != IsError) return false ;
328
+ return (Value - 1 ) & 2 ;
283
329
}
284
330
285
- bool stripsResultOptionality () const {
286
- assert ( hasValue ()) ;
287
- return (Value - 1 ) & 1 ;
331
+ bool hasErrorParameterReplacedWithVoid () const {
332
+ if ( getKind () != IsError) return false ;
333
+ return (Value - 1 ) & 4 ;
288
334
}
289
335
290
- bool isErrorParameterReplacedWithVoid () const {
291
- assert (hasValue () );
292
- return (Value - 1 ) & 2 ;
336
+ unsigned getErrorParamIndex () const {
337
+ assert (getKind () == IsError );
338
+ return (Value - 1 ) >> 3 ;
293
339
}
340
+
341
+ unsigned getAsyncCompletionHandlerParamIndex () const {
342
+ assert (getKind () == IsAsync);
343
+ return ((Value - 1 ) >> 1 ) & 0xFFFFFu ;
344
+ }
345
+
346
+ Optional<unsigned > getAsyncCompletionHandlerErrorParamIndex () const {
347
+ assert (getKind () == IsAsync);
294
348
295
- unsigned getErrorParameterIndex () const {
296
- assert (hasValue ());
297
- return (Value - 1 ) >> 2 ;
349
+ unsigned encodedValue = (Value - 1 ) >> 21 ;
350
+ if (encodedValue == 0 ) {
351
+ return llvm::None;
352
+ }
353
+ return encodedValue - 1 ;
354
+ }
355
+
356
+ unsigned getForeignParamIndex () const {
357
+ switch (getKind ()) {
358
+ case IsNotForeign:
359
+ llvm_unreachable (" no foreign param" );
360
+
361
+ case IsError:
362
+ return getErrorParamIndex ();
363
+
364
+ case IsAsync:
365
+ return getAsyncCompletionHandlerParamIndex ();
366
+ }
367
+ llvm_unreachable (" uncovered switch" );
298
368
}
299
369
300
370
unsigned getOpaqueValue () const { return Value; }
301
- static EncodedForeignErrorInfo fromOpaqueValue (unsigned value) {
302
- EncodedForeignErrorInfo result;
371
+ static EncodedForeignInfo fromOpaqueValue (unsigned value) {
372
+ EncodedForeignInfo result;
303
373
result.Value = value;
304
374
return result;
305
375
}
@@ -374,7 +444,7 @@ class AbstractionPattern {
374
444
}
375
445
}
376
446
377
- bool hasStoredForeignErrorInfo () const {
447
+ bool hasStoredForeignInfo () const {
378
448
return hasStoredObjCMethod ();
379
449
}
380
450
@@ -411,7 +481,7 @@ class AbstractionPattern {
411
481
412
482
void initObjCMethod (CanGenericSignature signature,
413
483
CanType origType, const clang::ObjCMethodDecl *method,
414
- Kind kind, EncodedForeignErrorInfo errorInfo) {
484
+ Kind kind, EncodedForeignInfo errorInfo) {
415
485
initSwiftType (signature, origType, kind);
416
486
ObjCMethod = method;
417
487
OtherData = errorInfo.getOpaqueValue ();
@@ -519,7 +589,8 @@ class AbstractionPattern {
519
589
// / Objective-C method.
520
590
static AbstractionPattern
521
591
getCurriedObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
522
- const Optional<ForeignErrorConvention> &foreignError);
592
+ const Optional<ForeignErrorConvention> &foreignError,
593
+ const Optional<ForeignAsyncConvention> &foreignAsync);
523
594
524
595
// / Return an abstraction pattern for the uncurried type of a C function
525
596
// / imported as a method.
@@ -644,7 +715,7 @@ class AbstractionPattern {
644
715
// / Objective-C method.
645
716
static AbstractionPattern
646
717
getCurriedObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
647
- EncodedForeignErrorInfo errorInfo) {
718
+ EncodedForeignInfo errorInfo) {
648
719
assert (isa<AnyFunctionType>(origType));
649
720
AbstractionPattern pattern;
650
721
pattern.initObjCMethod (nullptr , origType, method,
@@ -670,7 +741,7 @@ class AbstractionPattern {
670
741
getPartialCurriedObjCMethod (CanGenericSignature signature,
671
742
CanType origType,
672
743
const clang::ObjCMethodDecl *method,
673
- EncodedForeignErrorInfo errorInfo) {
744
+ EncodedForeignInfo errorInfo) {
674
745
assert (isa<AnyFunctionType>(origType));
675
746
AbstractionPattern pattern;
676
747
pattern.initObjCMethod (signature, origType, method,
@@ -733,14 +804,15 @@ class AbstractionPattern {
733
804
// / Return an abstraction pattern for the type of an Objective-C method.
734
805
static AbstractionPattern
735
806
getObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
736
- const Optional<ForeignErrorConvention> &foreignError);
807
+ const Optional<ForeignErrorConvention> &foreignError,
808
+ const Optional<ForeignAsyncConvention> &foreignAsync);
737
809
738
810
private:
739
811
// / Return an abstraction pattern for the uncurried type of an
740
812
// / Objective-C method.
741
813
static AbstractionPattern
742
814
getObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
743
- EncodedForeignErrorInfo errorInfo) {
815
+ EncodedForeignInfo errorInfo) {
744
816
assert (isa<AnyFunctionType>(origType));
745
817
AbstractionPattern pattern;
746
818
pattern.initObjCMethod (nullptr , origType, method, Kind::ObjCMethodType,
@@ -998,9 +1070,9 @@ class AbstractionPattern {
998
1070
getKind () == Kind::OpaqueDerivativeFunction);
999
1071
}
1000
1072
1001
- EncodedForeignErrorInfo getEncodedForeignErrorInfo () const {
1002
- assert (hasStoredForeignErrorInfo ());
1003
- return EncodedForeignErrorInfo ::fromOpaqueValue (OtherData);
1073
+ EncodedForeignInfo getEncodedForeignInfo () const {
1074
+ assert (hasStoredForeignInfo ());
1075
+ return EncodedForeignInfo ::fromOpaqueValue (OtherData);
1004
1076
}
1005
1077
1006
1078
bool hasForeignErrorStrippingResultOptionality () const {
@@ -1029,8 +1101,8 @@ class AbstractionPattern {
1029
1101
case Kind::PartialCurriedObjCMethodType:
1030
1102
case Kind::CurriedObjCMethodType:
1031
1103
case Kind::ObjCMethodType: {
1032
- auto errorInfo = getEncodedForeignErrorInfo ();
1033
- return ( errorInfo.hasValue () && errorInfo. stripsResultOptionality () );
1104
+ auto errorInfo = getEncodedForeignInfo ();
1105
+ return errorInfo.errorStripsResultOptionality ( );
1034
1106
}
1035
1107
}
1036
1108
llvm_unreachable (" bad kind" );
@@ -1203,6 +1275,14 @@ class AbstractionPattern {
1203
1275
GenericSignature derivativeGenericSignature = GenericSignature(),
1204
1276
bool makeSelfParamFirst = false);
1205
1277
1278
+ // / If this pattern refers to a foreign ObjC method that was imported as async, this returns
1279
+ // / the abstraction pattern for the completion callback with the original ObjC block type.
1280
+ // /
1281
+ // / Otherwise, this produces the default fully-concrete abstraction pattern for the given
1282
+ // / Swift type.
1283
+ AbstractionPattern getObjCMethodAsyncCompletionHandlerType (
1284
+ CanType swiftCompletionHandlerType) const ;
1285
+
1206
1286
void dump () const LLVM_ATTRIBUTE_USED;
1207
1287
void print (raw_ostream &OS) const ;
1208
1288
};
0 commit comments