@@ -2745,17 +2745,7 @@ class SyncCallEmission final : public CallEmission {
2745
2745
Explosion &out) override {
2746
2746
SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
2747
2747
IGF.getSILModule ());
2748
- bool mayReturnErrorDirectly = false ;
2749
- if (!convertDirectToIndirectReturn &&
2750
- !fnConv.hasIndirectSILErrorResults () &&
2751
- fnConv.funcTy ->hasErrorResult () && fnConv.isTypedError ()) {
2752
- auto errorType =
2753
- fnConv.getSILErrorType (IGF.IGM .getMaximalTypeExpansionContext ());
2754
- auto &errorSchema =
2755
- IGF.IGM .getTypeInfo (errorType).nativeReturnValueSchema (IGF.IGM );
2756
-
2757
- mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly ();
2758
- }
2748
+ bool mayReturnErrorDirectly = mayReturnTypedErrorDirectly ();
2759
2749
2760
2750
// Bail out immediately on a void result.
2761
2751
llvm::Value *result = call;
@@ -2812,72 +2802,8 @@ class SyncCallEmission final : public CallEmission {
2812
2802
2813
2803
// Handle direct return of typed errors
2814
2804
if (mayReturnErrorDirectly && !nativeSchema.requiresIndirect ()) {
2815
- auto errorType =
2816
- fnConv.getSILErrorType (IGF.IGM .getMaximalTypeExpansionContext ());
2817
- auto &errorSchema =
2818
- IGF.IGM .getTypeInfo (errorType).nativeReturnValueSchema (IGF.IGM );
2819
-
2820
- auto combined =
2821
- combineResultAndTypedErrorType (IGF.IGM , nativeSchema, errorSchema);
2822
-
2823
- if (combined.combinedTy ->isVoidTy ()) {
2824
- typedErrorExplosion = Explosion ();
2825
- return ;
2826
- }
2827
-
2828
- Explosion nativeExplosion;
2829
- extractScalarResults (IGF, result->getType (), result, nativeExplosion);
2830
- auto values = nativeExplosion.claimAll ();
2831
-
2832
- auto convertIfNecessary = [&](llvm::Type *nativeTy,
2833
- llvm::Value *elt) -> llvm::Value * {
2834
- auto *eltTy = elt->getType ();
2835
- if (nativeTy->isIntOrPtrTy () && eltTy->isIntOrPtrTy () &&
2836
- nativeTy->getPrimitiveSizeInBits () !=
2837
- eltTy->getPrimitiveSizeInBits ()) {
2838
- return IGF.Builder .CreateTruncOrBitCast (elt, nativeTy);
2839
- }
2840
- return elt;
2841
- };
2842
-
2843
- Explosion errorExplosion;
2844
- if (!errorSchema.empty ()) {
2845
- if (auto *structTy = dyn_cast<llvm::StructType>(
2846
- errorSchema.getExpandedType (IGF.IGM ))) {
2847
- for (unsigned i = 0 , e = structTy->getNumElements (); i < e; ++i) {
2848
- llvm::Value *elt = values[combined.errorValueMapping [i]];
2849
- auto *nativeTy = structTy->getElementType (i);
2850
- elt = convertIfNecessary (nativeTy, elt);
2851
- errorExplosion.add (elt);
2852
- }
2853
- } else {
2854
- errorExplosion.add (convertIfNecessary (
2855
- combined.combinedTy , values[combined.errorValueMapping [0 ]]));
2856
- }
2857
-
2858
- typedErrorExplosion =
2859
- errorSchema.mapFromNative (IGF.IGM , IGF, errorExplosion, errorType);
2860
- } else {
2861
- typedErrorExplosion = std::move (errorExplosion);
2862
- }
2863
-
2864
- // If the regular result type is void, there is nothing to explode
2865
- if (!resultType.isVoid ()) {
2866
- Explosion resultExplosion;
2867
- if (auto *structTy = dyn_cast<llvm::StructType>(
2868
- nativeSchema.getExpandedType (IGF.IGM ))) {
2869
- for (unsigned i = 0 , e = structTy->getNumElements (); i < e; ++i) {
2870
- auto *nativeTy = structTy->getElementType (i);
2871
- resultExplosion.add (convertIfNecessary (nativeTy, values[i]));
2872
- }
2873
- } else {
2874
- resultExplosion.add (
2875
- convertIfNecessary (combined.combinedTy , values[0 ]));
2876
- }
2877
- out = nativeSchema.mapFromNative (IGF.IGM , IGF, resultExplosion,
2878
- resultType);
2879
- }
2880
- return ;
2805
+ return emitToUnmappedExplosionWithDirectTypedError (resultType, result,
2806
+ out);
2881
2807
}
2882
2808
2883
2809
if (result->getType ()->isVoidTy ())
@@ -4434,6 +4360,93 @@ void CallEmission::externalizeArguments(IRGenFunction &IGF, const Callee &callee
4434
4360
}
4435
4361
}
4436
4362
4363
+ bool CallEmission::mayReturnTypedErrorDirectly () const {
4364
+ SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
4365
+ IGF.getSILModule ());
4366
+ bool mayReturnErrorDirectly = false ;
4367
+ if (!convertDirectToIndirectReturn && !fnConv.hasIndirectSILErrorResults () &&
4368
+ fnConv.funcTy ->hasErrorResult () && fnConv.isTypedError ()) {
4369
+ auto errorType =
4370
+ fnConv.getSILErrorType (IGF.IGM .getMaximalTypeExpansionContext ());
4371
+ auto &errorSchema =
4372
+ IGF.IGM .getTypeInfo (errorType).nativeReturnValueSchema (IGF.IGM );
4373
+
4374
+ mayReturnErrorDirectly = !errorSchema.shouldReturnTypedErrorIndirectly ();
4375
+ }
4376
+
4377
+ return mayReturnErrorDirectly;
4378
+ }
4379
+
4380
+ void CallEmission::emitToUnmappedExplosionWithDirectTypedError (
4381
+ SILType resultType, llvm::Value *result, Explosion &out) {
4382
+ SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
4383
+ IGF.getSILModule ());
4384
+ auto &nativeSchema =
4385
+ IGF.IGM .getTypeInfo (resultType).nativeReturnValueSchema (IGF.IGM );
4386
+ auto errorType =
4387
+ fnConv.getSILErrorType (IGF.IGM .getMaximalTypeExpansionContext ());
4388
+ auto &errorSchema =
4389
+ IGF.IGM .getTypeInfo (errorType).nativeReturnValueSchema (IGF.IGM );
4390
+
4391
+ auto combined =
4392
+ combineResultAndTypedErrorType (IGF.IGM , nativeSchema, errorSchema);
4393
+
4394
+ if (combined.combinedTy ->isVoidTy ()) {
4395
+ typedErrorExplosion = Explosion ();
4396
+ return ;
4397
+ }
4398
+
4399
+ Explosion nativeExplosion;
4400
+ extractScalarResults (IGF, result->getType (), result, nativeExplosion);
4401
+ auto values = nativeExplosion.claimAll ();
4402
+
4403
+ auto convertIfNecessary = [&](llvm::Type *nativeTy,
4404
+ llvm::Value *elt) -> llvm::Value * {
4405
+ auto *eltTy = elt->getType ();
4406
+ if (nativeTy->isIntOrPtrTy () && eltTy->isIntOrPtrTy () &&
4407
+ nativeTy->getPrimitiveSizeInBits () != eltTy->getPrimitiveSizeInBits ()) {
4408
+ return IGF.Builder .CreateTruncOrBitCast (elt, nativeTy);
4409
+ }
4410
+ return elt;
4411
+ };
4412
+
4413
+ Explosion errorExplosion;
4414
+ if (!errorSchema.empty ()) {
4415
+ if (auto *structTy =
4416
+ dyn_cast<llvm::StructType>(errorSchema.getExpandedType (IGF.IGM ))) {
4417
+ for (unsigned i = 0 , e = structTy->getNumElements (); i < e; ++i) {
4418
+ llvm::Value *elt = values[combined.errorValueMapping [i]];
4419
+ auto *nativeTy = structTy->getElementType (i);
4420
+ elt = convertIfNecessary (nativeTy, elt);
4421
+ errorExplosion.add (elt);
4422
+ }
4423
+ } else {
4424
+ errorExplosion.add (convertIfNecessary (
4425
+ combined.combinedTy , values[combined.errorValueMapping [0 ]]));
4426
+ }
4427
+
4428
+ typedErrorExplosion =
4429
+ errorSchema.mapFromNative (IGF.IGM , IGF, errorExplosion, errorType);
4430
+ } else {
4431
+ typedErrorExplosion = std::move (errorExplosion);
4432
+ }
4433
+
4434
+ // If the regular result type is void, there is nothing to explode
4435
+ if (!resultType.isVoid ()) {
4436
+ Explosion resultExplosion;
4437
+ if (auto *structTy =
4438
+ dyn_cast<llvm::StructType>(nativeSchema.getExpandedType (IGF.IGM ))) {
4439
+ for (unsigned i = 0 , e = structTy->getNumElements (); i < e; ++i) {
4440
+ auto *nativeTy = structTy->getElementType (i);
4441
+ resultExplosion.add (convertIfNecessary (nativeTy, values[i]));
4442
+ }
4443
+ } else {
4444
+ resultExplosion.add (convertIfNecessary (combined.combinedTy , values[0 ]));
4445
+ }
4446
+ out = nativeSchema.mapFromNative (IGF.IGM , IGF, resultExplosion, resultType);
4447
+ }
4448
+ }
4449
+
4437
4450
void CallEmission::setKeyPathAccessorArguments (Explosion &in, bool isOutlined,
4438
4451
Explosion &out) {
4439
4452
auto origCalleeType = CurCallee.getOrigFunctionType ();
0 commit comments