@@ -2745,17 +2745,7 @@ class SyncCallEmission final : public CallEmission {
27452745 Explosion &out) override {
27462746 SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
27472747 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 ();
27592749
27602750 // Bail out immediately on a void result.
27612751 llvm::Value *result = call;
@@ -2812,72 +2802,8 @@ class SyncCallEmission final : public CallEmission {
28122802
28132803 // Handle direct return of typed errors
28142804 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);
28812807 }
28822808
28832809 if (result->getType ()->isVoidTy ())
@@ -4434,6 +4360,93 @@ void CallEmission::externalizeArguments(IRGenFunction &IGF, const Callee &callee
44344360 }
44354361}
44364362
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+
44374450void CallEmission::setKeyPathAccessorArguments (Explosion &in, bool isOutlined,
44384451 Explosion &out) {
44394452 auto origCalleeType = CurCallee.getOrigFunctionType ();
0 commit comments