diff --git a/include/swift/SIL/SILModule.h b/include/swift/SIL/SILModule.h index b3445647395..86183e7a8ea 100644 --- a/include/swift/SIL/SILModule.h +++ b/include/swift/SIL/SILModule.h @@ -107,8 +107,6 @@ enum class SILStage { /// when a Swift compilation context is lowered to SIL. class SILModule { friend class SILFunctionBuilder; - friend class SILGenSourceFileRequest; - friend class SILGenWholeModuleRequest; public: using FunctionListType = llvm::ilist; @@ -276,8 +274,8 @@ private: /// invalidation message is sent. llvm::SetVector NotificationHandlers; - SILModule(ModuleDecl *M, Lowering::TypeConverter &TC, - const SILOptions &Options, const DeclContext *associatedDC); + SILModule(llvm::PointerUnion context, + Lowering::TypeConverter &TC, const SILOptions &Options); SILModule(const SILModule&) = delete; void operator=(const SILModule&) = delete; @@ -348,11 +346,14 @@ public: /// Erase a global SIL variable from the module. void eraseGlobalVariable(SILGlobalVariable *G); - /// Create and return an empty SIL module that we can - /// later parse SIL bodies directly into, without converting from an AST. + /// Create and return an empty SIL module suitable for generating or parsing + /// SIL into. + /// + /// \param context The associated decl context. This should be a FileUnit in + /// single-file mode, and a ModuleDecl in whole-module mode. static std::unique_ptr - createEmptyModule(ModuleDecl *M, Lowering::TypeConverter &TC, - const SILOptions &Options); + createEmptyModule(llvm::PointerUnion context, + Lowering::TypeConverter &TC, const SILOptions &Options); /// Get the Swift module associated with this SIL module. ModuleDecl *getSwiftModule() const { return TheSwiftModule; } diff --git a/lib/SIL/IR/SILModule.cpp b/lib/SIL/IR/SILModule.cpp index 1d5e4974dd3..50aadb293da 100644 --- a/lib/SIL/IR/SILModule.cpp +++ b/lib/SIL/IR/SILModule.cpp @@ -92,13 +92,17 @@ class SILModule::SerializationCallback final } }; -SILModule::SILModule(ModuleDecl *SwiftModule, TypeConverter &TC, - const SILOptions &Options, const DeclContext *associatedDC) - : TheSwiftModule(SwiftModule), - AssociatedDeclContext(associatedDC), - Stage(SILStage::Raw), Options(Options), serialized(false), +SILModule::SILModule(llvm::PointerUnion context, + Lowering::TypeConverter &TC, const SILOptions &Options) + : Stage(SILStage::Raw), Options(Options), serialized(false), SerializeSILAction(), Types(TC) { - assert(AssociatedDeclContext); + assert(!context.isNull()); + if (auto *file = context.dyn_cast()) { + AssociatedDeclContext = file; + } else { + AssociatedDeclContext = context.get(); + } + TheSwiftModule = AssociatedDeclContext->getParentModule(); // We always add the base SILModule serialization callback. std::unique_ptr callback( @@ -123,10 +127,10 @@ SILModule::~SILModule() { } } -std::unique_ptr -SILModule::createEmptyModule(ModuleDecl *M, TypeConverter &TC, - const SILOptions &Options) { - return std::unique_ptr(new SILModule(M, TC, Options, M)); +std::unique_ptr SILModule::createEmptyModule( + llvm::PointerUnion context, + Lowering::TypeConverter &TC, const SILOptions &Options) { + return std::unique_ptr(new SILModule(context, TC, Options)); } ASTContext &SILModule::getASTContext() const { diff --git a/lib/SIL/Parser/ParseSIL.cpp b/lib/SIL/Parser/ParseSIL.cpp index 734478829c4..1ed4354feac 100644 --- a/lib/SIL/Parser/ParseSIL.cpp +++ b/lib/SIL/Parser/ParseSIL.cpp @@ -115,8 +115,8 @@ ParseSILModuleRequest::evaluate(Evaluator &evaluator, auto bufferID = SF->getBufferID(); assert(bufferID); - auto *mod = SF->getParentModule(); - auto silMod = SILModule::createEmptyModule(mod, desc.conv, desc.opts); + auto silMod = SILModule::createEmptyModule(desc.context, desc.conv, + desc.opts); SILParserState parserState(silMod.get()); Parser parser(*bufferID, *SF, parserState.Impl.get()); PrettyStackTraceParser StackTrace(parser); @@ -125,7 +125,7 @@ ParseSILModuleRequest::evaluate(Evaluator &evaluator, if (hadError) { // The rest of the SIL pipeline expects well-formed SIL, so if we encounter // a parsing error, just return an empty SIL module. - return SILModule::createEmptyModule(mod, desc.conv, desc.opts); + return SILModule::createEmptyModule(desc.context, desc.conv, desc.opts); } return silMod; } diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index 7db276a2fc3..1e6a4bcbb4f 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -1867,8 +1867,7 @@ SILGenSourceFileRequest::evaluate(Evaluator &evaluator, auto *unit = desc.context.get(); auto *mod = unit->getParentModule(); - auto M = std::unique_ptr( - new SILModule(mod, desc.conv, desc.opts, unit)); + auto M = SILModule::createEmptyModule(desc.context, desc.conv, desc.opts); SILGenModuleRAII scope(*M, mod); if (auto *file = dyn_cast(unit)) { @@ -1890,8 +1889,7 @@ SILGenWholeModuleRequest::evaluate(Evaluator &evaluator, } auto *mod = desc.context.get(); - auto M = std::unique_ptr( - new SILModule(mod, desc.conv, desc.opts, mod)); + auto M = SILModule::createEmptyModule(desc.context, desc.conv, desc.opts); SILGenModuleRAII scope(*M, mod); for (auto file : mod->getFiles()) { diff --git a/test/IRGen/multi_file_resilience.swift b/test/IRGen/multi_file_resilience.swift index aaadb088fee..2a898f8bb41 100644 --- a/test/IRGen/multi_file_resilience.swift +++ b/test/IRGen/multi_file_resilience.swift @@ -7,6 +7,11 @@ // RUN: %target-swift-frontend -module-name main -I %t -emit-ir -primary-file %s %S/Inputs/OtherModule.swift | %FileCheck %s -DINT=i%target-ptrsize +// Check that we correctly handle resilience when parsing as SIL + SIB. +// RUN: %target-swift-frontend -emit-sib -module-name main %S/Inputs/OtherModule.swift -I %t -o %t/other.sib +// RUN: %target-swift-frontend -emit-silgen -module-name main -primary-file %s %S/Inputs/OtherModule.swift -I %t -o %t/main.sil +// RUN: %target-swift-frontend -emit-ir -module-name main -primary-file %t/main.sil %t/other.sib -I %t | %FileCheck %s -DINT=i%target-ptrsize + // This is a single-module version of the test case in // multi_module_resilience. // rdar://39763787