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