|
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