@@ -203,6 +203,7 @@ AbstractionPattern::getOptional(AbstractionPattern object) {
203
203
case Kind::PartialCurriedCXXOperatorMethodType:
204
204
case Kind::OpaqueFunction:
205
205
case Kind::OpaqueDerivativeFunction:
206
+ case Kind::ObjCCompletionHandlerArgumentsType:
206
207
llvm_unreachable (" cannot add optionality to non-type abstraction" );
207
208
case Kind::Opaque:
208
209
return AbstractionPattern::getOpaque ();
@@ -310,6 +311,7 @@ bool AbstractionPattern::matchesTuple(CanTupleType substType) {
310
311
return true ;
311
312
case Kind::Tuple:
312
313
return getNumTupleElements_Stored () == substType->getNumElements ();
314
+ case Kind::ObjCCompletionHandlerArgumentsType:
313
315
case Kind::ClangType:
314
316
case Kind::Type:
315
317
case Kind::Discard: {
@@ -399,6 +401,19 @@ AbstractionPattern::getTupleElementType(unsigned index) const {
399
401
return AbstractionPattern::getOpaque ();
400
402
return AbstractionPattern (getGenericSignature (),
401
403
getCanTupleElementType (getType (), index));
404
+
405
+ case Kind::ObjCCompletionHandlerArgumentsType: {
406
+ // Match up the tuple element with the parameter from the Clang block type,
407
+ // skipping the error parameter index if any.
408
+ auto callback = cast<clang::FunctionProtoType>(getClangType ());
409
+ auto errorIndex = getEncodedForeignInfo ()
410
+ .getAsyncCompletionHandlerErrorParamIndex ();
411
+ unsigned paramIndex = index + (errorIndex && index >= *errorIndex);
412
+ return AbstractionPattern (getGenericSignature (),
413
+ getCanTupleElementType (getType (), index),
414
+ callback->getParamType (paramIndex).getTypePtr ());
415
+ }
416
+
402
417
}
403
418
llvm_unreachable (" bad kind" );
404
419
}
@@ -465,6 +480,7 @@ AbstractionPattern AbstractionPattern::getFunctionResultType() const {
465
480
switch (getKind ()) {
466
481
case Kind::Invalid:
467
482
llvm_unreachable (" querying invalid abstraction pattern!" );
483
+ case Kind::ObjCCompletionHandlerArgumentsType:
468
484
case Kind::Tuple:
469
485
llvm_unreachable (" abstraction pattern for tuple cannot be function" );
470
486
case Kind::Opaque:
@@ -524,25 +540,45 @@ AbstractionPattern AbstractionPattern::getFunctionResultType() const {
524
540
->getPointeeType ()
525
541
->getAs <clang::FunctionProtoType>();
526
542
527
- // The result is the first non-error argument to the callback.
528
- unsigned callbackResultIndex = 0 ;
529
- if (auto callbackErrorIndex = getEncodedForeignInfo ()
530
- .getAsyncCompletionHandlerErrorParamIndex ()) {
531
- if (*callbackErrorIndex == 0 ) {
532
- callbackResultIndex = 1 ;
533
- }
543
+ // The result comprises the non-error argument(s) to the callback, if
544
+ // any.
545
+
546
+ auto callbackErrorIndex = getEncodedForeignInfo ()
547
+ .getAsyncCompletionHandlerErrorParamIndex ();
548
+ assert ((!callbackErrorIndex.hasValue ()
549
+ || callbackParamTy->getNumParams () > *callbackErrorIndex)
550
+ && " completion handler has invalid error param index?!" );
551
+ unsigned numNonErrorParams
552
+ = callbackParamTy->getNumParams () - callbackErrorIndex.hasValue ();
553
+
554
+ switch (numNonErrorParams) {
555
+ case 0 :
556
+ // If there are no result arguments, then the imported result type is
557
+ // Void, with no interesting abstraction properties.
558
+ return AbstractionPattern (TupleType::getEmpty (getType ()->getASTContext ()));
559
+
560
+ case 1 : {
561
+ // If there's a single argument, abstract it according to its formal type
562
+ // in the ObjC signature.
563
+ unsigned callbackResultIndex
564
+ = callbackErrorIndex && *callbackErrorIndex == 0 ;
565
+ auto clangResultType = callbackParamTy
566
+ ->getParamType (callbackResultIndex)
567
+ .getTypePtr ();
568
+
569
+ return AbstractionPattern (getGenericSignatureForFunctionComponent (),
570
+ getResultType (getType ()), clangResultType);
534
571
}
535
-
536
- const clang::Type *clangResultType = nullptr ;
537
- if (callbackResultIndex < callbackParamTy->getNumParams ()) {
538
- clangResultType = callbackParamTy->getParamType (callbackResultIndex)
539
- .getTypePtr ();
540
- } else {
541
- clangResultType = getObjCMethod ()->getASTContext ().VoidTy .getTypePtr ();
572
+
573
+ default :
574
+ // If there are multiple results, we have a special abstraction pattern
575
+ // form to represent the mapping from block parameters to tuple elements
576
+ // in the return type.
577
+ return AbstractionPattern::getObjCCompletionHandlerArgumentsType (
578
+ getGenericSignatureForFunctionComponent (),
579
+ getResultType (getType ()), callbackParamTy,
580
+ getEncodedForeignInfo ());
542
581
}
543
-
544
- return AbstractionPattern (getGenericSignatureForFunctionComponent (),
545
- getResultType (getType ()), clangResultType);
546
582
}
547
583
548
584
return AbstractionPattern (getGenericSignatureForFunctionComponent (),
@@ -594,6 +630,7 @@ AbstractionPattern::getObjCMethodAsyncCompletionHandlerType(
594
630
case Kind::CurriedCFunctionAsMethodType:
595
631
case Kind::CurriedCXXMethodType:
596
632
case Kind::CurriedCXXOperatorMethodType:
633
+ case Kind::ObjCCompletionHandlerArgumentsType:
597
634
swift_unreachable (" not appropriate for this kind" );
598
635
}
599
636
}
@@ -791,6 +828,7 @@ AbstractionPattern AbstractionPattern::getOptionalObjectType() const {
791
828
case Kind::Tuple:
792
829
case Kind::OpaqueFunction:
793
830
case Kind::OpaqueDerivativeFunction:
831
+ case Kind::ObjCCompletionHandlerArgumentsType:
794
832
llvm_unreachable (" pattern for function or tuple cannot be for optional" );
795
833
796
834
case Kind::Opaque:
@@ -837,6 +875,7 @@ AbstractionPattern AbstractionPattern::getReferenceStorageReferentType() const {
837
875
case Kind::Tuple:
838
876
case Kind::OpaqueFunction:
839
877
case Kind::OpaqueDerivativeFunction:
878
+ case Kind::ObjCCompletionHandlerArgumentsType:
840
879
return *this ;
841
880
case Kind::Type:
842
881
return AbstractionPattern (getGenericSignature (),
@@ -897,12 +936,15 @@ void AbstractionPattern::print(raw_ostream &out) const {
897
936
case Kind::CurriedCFunctionAsMethodType:
898
937
case Kind::PartialCurriedCFunctionAsMethodType:
899
938
case Kind::CFunctionAsMethodType:
939
+ case Kind::ObjCCompletionHandlerArgumentsType:
900
940
out << (getKind () == Kind::ClangType
901
941
? " AP::ClangType(" :
902
942
getKind () == Kind::CurriedCFunctionAsMethodType
903
943
? " AP::CurriedCFunctionAsMethodType(" :
904
944
getKind () == Kind::PartialCurriedCFunctionAsMethodType
905
- ? " AP::PartialCurriedCFunctionAsMethodType("
945
+ ? " AP::PartialCurriedCFunctionAsMethodType(" :
946
+ getKind () == Kind::ObjCCompletionHandlerArgumentsType
947
+ ? " AP::ObjCCompletionHandlerArgumentsType("
906
948
: " AP::CFunctionAsMethodType(" );
907
949
if (auto sig = getGenericSignature ()) {
908
950
sig->print (out);
@@ -922,6 +964,12 @@ void AbstractionPattern::print(raw_ostream &out) const {
922
964
out << " static" ;
923
965
}
924
966
}
967
+ if (hasStoredForeignInfo ()) {
968
+ if (auto errorIndex
969
+ = getEncodedForeignInfo ().getAsyncCompletionHandlerErrorParamIndex ()){
970
+ out << " , errorParamIndex=" << *errorIndex;
971
+ }
972
+ }
925
973
out << " )" ;
926
974
return ;
927
975
case Kind::CXXMethodType:
@@ -1069,6 +1117,9 @@ const {
1069
1117
case Kind::OpaqueDerivativeFunction:
1070
1118
llvm_unreachable (" should not have an opaque derivative function pattern "
1071
1119
" matching a struct/enum type" );
1120
+ case Kind::ObjCCompletionHandlerArgumentsType:
1121
+ llvm_unreachable (" should not have a completion handler argument pattern "
1122
+ " matching a struct/enum type" );
1072
1123
case Kind::PartialCurriedObjCMethodType:
1073
1124
case Kind::CurriedObjCMethodType:
1074
1125
case Kind::PartialCurriedCFunctionAsMethodType:
0 commit comments