@@ -1469,6 +1469,7 @@ class IRGenSILFunction :
1469
1469
void visitCondBranchInst(CondBranchInst *i);
1470
1470
void visitReturnInst(ReturnInst *i);
1471
1471
void visitThrowInst(ThrowInst *i);
1472
+ void visitThrowAddrInst(ThrowAddrInst *i);
1472
1473
void visitUnwindInst(UnwindInst *i);
1473
1474
void visitYieldInst(YieldInst *i);
1474
1475
void visitSwitchValueInst(SwitchValueInst *i);
@@ -4251,23 +4252,34 @@ void IRGenSILFunction::visitReturnInst(swift::ReturnInst *i) {
4251
4252
void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) {
4252
4253
SILFunctionConventions conv(CurSILFn->getLoweredFunctionType(),
4253
4254
getSILModule());
4255
+ assert(!conv.hasIndirectSILErrorResults());
4256
+
4254
4257
if (!isAsync()) {
4255
4258
if (conv.isTypedError()) {
4256
4259
llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
4257
4260
flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy);
4258
- if (!conv.hasIndirectSILErrorResults()) {
4259
- Explosion errorResult = getLoweredExplosion(i->getOperand());
4260
- auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4261
- IGM.getMaximalTypeExpansionContext())));
4262
- ti.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false);
4263
- }
4261
+ Explosion errorResult = getLoweredExplosion(i->getOperand());
4262
+ auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4263
+ IGM.getMaximalTypeExpansionContext())));
4264
+ ti.initialize(*this, errorResult, getCallerTypedErrorResultSlot(), false);
4265
+
4264
4266
Builder.CreateStore(flag, getCallerErrorResultSlot());
4265
4267
} else {
4266
4268
Explosion errorResult = getLoweredExplosion(i->getOperand());
4267
4269
Builder.CreateStore(errorResult.claimNext(), getCallerErrorResultSlot());
4268
4270
}
4269
- // Async functions just return to the continuation.
4270
- } else if (isAsync()) {
4271
+
4272
+ // Create a normal return, but leaving the return value undefined.
4273
+ auto fnTy = CurFn->getFunctionType();
4274
+ auto retTy = fnTy->getReturnType();
4275
+ if (retTy->isVoidTy()) {
4276
+ Builder.CreateRetVoid();
4277
+ } else {
4278
+ Builder.CreateRet(llvm::UndefValue::get(retTy));
4279
+ }
4280
+
4281
+ // Async functions just return to the continuation.
4282
+ } else {
4271
4283
// Store the exception to the error slot.
4272
4284
auto exn = getLoweredExplosion(i->getOperand());
4273
4285
@@ -4276,13 +4288,9 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) {
4276
4288
conv.getSILResultType(IGM.getMaximalTypeExpansionContext()));
4277
4289
4278
4290
if (conv.isTypedError()) {
4279
- if (conv.hasIndirectSILErrorResults()) {
4280
- (void)exn.claimAll();
4281
- } else {
4282
- auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4283
- IGM.getMaximalTypeExpansionContext())));
4284
- ti.initialize(*this, exn, getCallerTypedErrorResultSlot(), false);
4285
- }
4291
+ auto &ti = cast<LoadableTypeInfo>(IGM.getTypeInfo(conv.getSILErrorType(
4292
+ IGM.getMaximalTypeExpansionContext())));
4293
+ ti.initialize(*this, exn, getCallerTypedErrorResultSlot(), false);
4286
4294
llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
4287
4295
flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy);
4288
4296
assert(exn.empty() && "Unclaimed typed error results");
@@ -4293,16 +4301,44 @@ void IRGenSILFunction::visitThrowInst(swift::ThrowInst *i) {
4293
4301
Explosion empty;
4294
4302
emitAsyncReturn(*this, layout, funcResultType,
4295
4303
i->getFunction()->getLoweredFunctionType(), empty, exn);
4296
- return;
4297
4304
}
4305
+ }
4298
4306
4299
- // Create a normal return, but leaving the return value undefined.
4300
- auto fnTy = CurFn->getFunctionType();
4301
- auto retTy = fnTy->getReturnType();
4302
- if (retTy->isVoidTy()) {
4303
- Builder.CreateRetVoid();
4307
+ void IRGenSILFunction::visitThrowAddrInst(swift::ThrowAddrInst *i) {
4308
+ SILFunctionConventions conv(CurSILFn->getLoweredFunctionType(),
4309
+ getSILModule());
4310
+ assert(conv.isTypedError());
4311
+ assert(conv.hasIndirectSILErrorResults());
4312
+
4313
+ if (!isAsync()) {
4314
+ llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
4315
+ flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy);
4316
+ Builder.CreateStore(flag, getCallerErrorResultSlot());
4317
+
4318
+ // Create a normal return, but leaving the return value undefined.
4319
+ auto fnTy = CurFn->getFunctionType();
4320
+ auto retTy = fnTy->getReturnType();
4321
+ if (retTy->isVoidTy()) {
4322
+ Builder.CreateRetVoid();
4323
+ } else {
4324
+ Builder.CreateRet(llvm::UndefValue::get(retTy));
4325
+ }
4326
+
4327
+ // Async functions just return to the continuation.
4304
4328
} else {
4305
- Builder.CreateRet(llvm::UndefValue::get(retTy));
4329
+ auto layout = getAsyncContextLayout(*this);
4330
+ auto funcResultType = CurSILFn->mapTypeIntoContext(
4331
+ conv.getSILResultType(IGM.getMaximalTypeExpansionContext()));
4332
+
4333
+ llvm::Constant *flag = llvm::ConstantInt::get(IGM.IntPtrTy, 1);
4334
+ flag = llvm::ConstantExpr::getIntToPtr(flag, IGM.Int8PtrTy);
4335
+
4336
+ Explosion exn;
4337
+ exn.add(flag);
4338
+
4339
+ Explosion empty;
4340
+ emitAsyncReturn(*this, layout, funcResultType,
4341
+ i->getFunction()->getLoweredFunctionType(), empty, exn);
4306
4342
}
4307
4343
}
4308
4344
0 commit comments