@@ -2756,7 +2756,17 @@ class SyncCallEmission final : public CallEmission {
27562756 Explosion &out) override {
27572757 SILFunctionConventions fnConv (getCallee ().getOrigFunctionType (),
27582758 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+ }
27602770
27612771 // Bail out immediately on a void result.
27622772 llvm::Value *result = call;
@@ -2803,8 +2813,72 @@ class SyncCallEmission final : public CallEmission {
28032813
28042814 // Handle direct return of typed errors
28052815 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 ;
28082882 }
28092883
28102884 if (result->getType ()->isVoidTy ())
@@ -4361,93 +4435,6 @@ void CallEmission::externalizeArguments(IRGenFunction &IGF, const Callee &callee
43614435 }
43624436}
43634437
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-
44514438void CallEmission::setKeyPathAccessorArguments (Explosion &in, bool isOutlined,
44524439 Explosion &out) {
44534440 auto origCalleeType = CurCallee.getOrigFunctionType ();
0 commit comments