@@ -260,46 +260,116 @@ class AbstractionPattern {
260260 OpaqueDerivativeFunction,
261261 };
262262
263- class EncodedForeignErrorInfo {
263+ class EncodedForeignInfo {
264264 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+ }
265312
266313 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);
278317
279318 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 ;
283329 }
284330
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 ;
288334 }
289335
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 ;
293339 }
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);
294348
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" );
298368 }
299369
300370 unsigned getOpaqueValue () const { return Value; }
301- static EncodedForeignErrorInfo fromOpaqueValue (unsigned value) {
302- EncodedForeignErrorInfo result;
371+ static EncodedForeignInfo fromOpaqueValue (unsigned value) {
372+ EncodedForeignInfo result;
303373 result.Value = value;
304374 return result;
305375 }
@@ -374,7 +444,7 @@ class AbstractionPattern {
374444 }
375445 }
376446
377- bool hasStoredForeignErrorInfo () const {
447+ bool hasStoredForeignInfo () const {
378448 return hasStoredObjCMethod ();
379449 }
380450
@@ -411,7 +481,7 @@ class AbstractionPattern {
411481
412482 void initObjCMethod (CanGenericSignature signature,
413483 CanType origType, const clang::ObjCMethodDecl *method,
414- Kind kind, EncodedForeignErrorInfo errorInfo) {
484+ Kind kind, EncodedForeignInfo errorInfo) {
415485 initSwiftType (signature, origType, kind);
416486 ObjCMethod = method;
417487 OtherData = errorInfo.getOpaqueValue ();
@@ -519,7 +589,8 @@ class AbstractionPattern {
519589 // / Objective-C method.
520590 static AbstractionPattern
521591 getCurriedObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
522- const Optional<ForeignErrorConvention> &foreignError);
592+ const Optional<ForeignErrorConvention> &foreignError,
593+ const Optional<ForeignAsyncConvention> &foreignAsync);
523594
524595 // / Return an abstraction pattern for the uncurried type of a C function
525596 // / imported as a method.
@@ -644,7 +715,7 @@ class AbstractionPattern {
644715 // / Objective-C method.
645716 static AbstractionPattern
646717 getCurriedObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
647- EncodedForeignErrorInfo errorInfo) {
718+ EncodedForeignInfo errorInfo) {
648719 assert (isa<AnyFunctionType>(origType));
649720 AbstractionPattern pattern;
650721 pattern.initObjCMethod (nullptr , origType, method,
@@ -670,7 +741,7 @@ class AbstractionPattern {
670741 getPartialCurriedObjCMethod (CanGenericSignature signature,
671742 CanType origType,
672743 const clang::ObjCMethodDecl *method,
673- EncodedForeignErrorInfo errorInfo) {
744+ EncodedForeignInfo errorInfo) {
674745 assert (isa<AnyFunctionType>(origType));
675746 AbstractionPattern pattern;
676747 pattern.initObjCMethod (signature, origType, method,
@@ -733,14 +804,15 @@ class AbstractionPattern {
733804 // / Return an abstraction pattern for the type of an Objective-C method.
734805 static AbstractionPattern
735806 getObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
736- const Optional<ForeignErrorConvention> &foreignError);
807+ const Optional<ForeignErrorConvention> &foreignError,
808+ const Optional<ForeignAsyncConvention> &foreignAsync);
737809
738810private:
739811 // / Return an abstraction pattern for the uncurried type of an
740812 // / Objective-C method.
741813 static AbstractionPattern
742814 getObjCMethod (CanType origType, const clang::ObjCMethodDecl *method,
743- EncodedForeignErrorInfo errorInfo) {
815+ EncodedForeignInfo errorInfo) {
744816 assert (isa<AnyFunctionType>(origType));
745817 AbstractionPattern pattern;
746818 pattern.initObjCMethod (nullptr , origType, method, Kind::ObjCMethodType,
@@ -998,9 +1070,9 @@ class AbstractionPattern {
9981070 getKind () == Kind::OpaqueDerivativeFunction);
9991071 }
10001072
1001- EncodedForeignErrorInfo getEncodedForeignErrorInfo () const {
1002- assert (hasStoredForeignErrorInfo ());
1003- return EncodedForeignErrorInfo ::fromOpaqueValue (OtherData);
1073+ EncodedForeignInfo getEncodedForeignInfo () const {
1074+ assert (hasStoredForeignInfo ());
1075+ return EncodedForeignInfo ::fromOpaqueValue (OtherData);
10041076 }
10051077
10061078 bool hasForeignErrorStrippingResultOptionality () const {
@@ -1029,8 +1101,8 @@ class AbstractionPattern {
10291101 case Kind::PartialCurriedObjCMethodType:
10301102 case Kind::CurriedObjCMethodType:
10311103 case Kind::ObjCMethodType: {
1032- auto errorInfo = getEncodedForeignErrorInfo ();
1033- return ( errorInfo.hasValue () && errorInfo. stripsResultOptionality () );
1104+ auto errorInfo = getEncodedForeignInfo ();
1105+ return errorInfo.errorStripsResultOptionality ( );
10341106 }
10351107 }
10361108 llvm_unreachable (" bad kind" );
@@ -1203,6 +1275,14 @@ class AbstractionPattern {
12031275 GenericSignature derivativeGenericSignature = GenericSignature(),
12041276 bool makeSelfParamFirst = false);
12051277
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+
12061286 void dump () const LLVM_ATTRIBUTE_USED;
12071287 void print (raw_ostream &OS) const ;
12081288};
0 commit comments