|
20 | 20 | using namespace swift; |
21 | 21 | using namespace Lowering; |
22 | 22 |
|
| 23 | +static FuncDecl *synthesizeExit(ASTContext &ctx, ModuleDecl *moduleDecl) { |
| 24 | + // Synthesize an exit function with this interface. |
| 25 | + // @_extern(c) |
| 26 | + // func exit(_: Int32) -> Never |
| 27 | + ParameterList *params = |
| 28 | + ParameterList::createWithoutLoc(ParamDecl::createImplicit( |
| 29 | + ctx, Identifier(), Identifier(), ctx.getInt32Type(), moduleDecl)); |
| 30 | + FuncDecl *exitFuncDecl = FuncDecl::createImplicit( |
| 31 | + ctx, StaticSpellingKind::None, |
| 32 | + DeclName(ctx, DeclBaseName(ctx.getIdentifier("exit")), params), {}, |
| 33 | + /*async*/ false, /*throws*/ false, /*thrownType*/ Type(), {}, params, |
| 34 | + ctx.getNeverType(), moduleDecl); |
| 35 | + exitFuncDecl->getAttrs().add(new (ctx) ExternAttr( |
| 36 | + llvm::None, llvm::None, ExternKind::C, /*implicit*/ true)); |
| 37 | + return exitFuncDecl; |
| 38 | +} |
| 39 | + |
23 | 40 | void SILGenModule::emitEntryPoint(SourceFile *SF, SILFunction *TopLevel) { |
24 | 41 |
|
25 | 42 | auto EntryRef = SILDeclRef::getMainFileEntryPoint(SF); |
@@ -85,7 +102,10 @@ void SILGenModule::emitEntryPoint(SourceFile *SF, SILFunction *TopLevel) { |
85 | 102 | SILType returnType; |
86 | 103 | if (isAsyncTopLevel) { |
87 | 104 | FuncDecl *exitFuncDecl = getExit(); |
88 | | - assert(exitFuncDecl && "Failed to find exit function declaration"); |
| 105 | + if (!exitFuncDecl) { |
| 106 | + // If it doesn't exist, we can conjure one up instead of crashing |
| 107 | + exitFuncDecl = synthesizeExit(getASTContext(), TopLevel->getModule().getSwiftModule()); |
| 108 | + } |
89 | 109 | exitFunc = getFunction( |
90 | 110 | SILDeclRef(exitFuncDecl, SILDeclRef::Kind::Func, /*isForeign*/ true), |
91 | 111 | NotForDefinition); |
@@ -216,20 +236,7 @@ void SILGenFunction::emitCallToMain(FuncDecl *mainFunc) { |
216 | 236 | FuncDecl *exitFuncDecl = SGM.getExit(); |
217 | 237 | if (!exitFuncDecl) { |
218 | 238 | // If it doesn't exist, we can conjure one up instead of crashing |
219 | | - // @_extern(c) |
220 | | - // func exit(_: Int32) -> Never |
221 | | - ASTContext &ctx = getASTContext(); |
222 | | - ModuleDecl *moduleDecl = mainFunc->getModuleContext(); |
223 | | - ParameterList *params = |
224 | | - ParameterList::createWithoutLoc(ParamDecl::createImplicit( |
225 | | - ctx, Identifier(), Identifier(), ctx.getInt32Type(), moduleDecl)); |
226 | | - exitFuncDecl = FuncDecl::createImplicit( |
227 | | - ctx, StaticSpellingKind::None, |
228 | | - DeclName(ctx, DeclBaseName(ctx.getIdentifier("exit")), params), {}, |
229 | | - /*async*/ false, /*throws*/ false, /*thrownType*/ Type(), {}, params, |
230 | | - ctx.getNeverType(), moduleDecl); |
231 | | - exitFuncDecl->getAttrs().add(new (ctx) ExternAttr( |
232 | | - llvm::None, llvm::None, ExternKind::C, /*implicit*/ true)); |
| 239 | + exitFuncDecl = synthesizeExit(getASTContext(), mainFunc->getModuleContext()); |
233 | 240 | } |
234 | 241 | SILFunction *exitSILFunc = SGM.getFunction( |
235 | 242 | SILDeclRef(exitFuncDecl, SILDeclRef::Kind::Func, /*isForeign*/ true), |
|
0 commit comments