diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 4f6d153e293f3..d4d0e74725fde 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -602,7 +602,7 @@ class alignas(1 << DeclAlignInBits) Decl { HasAnyUnavailableValues : 1 ); - SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1, + SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1, /// If the module was or is being compiled with `-enable-testing`. TestingEnabled : 1, @@ -624,7 +624,10 @@ class alignas(1 << DeclAlignInBits) Decl { ImplicitDynamicEnabled : 1, // Whether the module is a system module. - IsSystemModule : 1 + IsSystemModule : 1, + + // If the module is a static library. + IsStaticLibrary : 1 ); SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2, diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def index 74561817ca550..3fc50d240d8e5 100644 --- a/include/swift/AST/DiagnosticsDriver.def +++ b/include/swift/AST/DiagnosticsDriver.def @@ -64,6 +64,9 @@ ERROR(error_expected_frontend_command,none, ERROR(error_cannot_specify__o_for_multiple_outputs,none, "cannot specify -o when generating multiple output files", ()) +ERROR(error_static_emit_executable_disallowed,none, + "-static may not be used with -emit-executable", ()) + ERROR(error_unable_to_load_output_file_map, none, "unable to load output file map '%1': %0", (StringRef, StringRef)) diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index 0b3daffc4fd5f..c678e9086917c 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -338,6 +338,14 @@ class ModuleDecl : public DeclContext, public TypeDecl { return getResilienceStrategy() != ResilienceStrategy::Default; } + bool isStaticLibrary() const { + return Bits.ModuleDecl.IsStaticLibrary; + } + + void setIsStaticLibrary(bool isStaticLibrary = true) { + Bits.ModuleDecl.IsStaticLibrary = isStaticLibrary; + } + /// Look up a (possibly overloaded) value set at top-level scope /// (but with the specified access path, which may come from an import decl) /// within the current module. diff --git a/include/swift/Driver/Action.h b/include/swift/Driver/Action.h index c230b0925ecc7..08dcf7f96d22e 100644 --- a/include/swift/Driver/Action.h +++ b/include/swift/Driver/Action.h @@ -48,6 +48,7 @@ class Action { AutolinkExtractJob, REPLJob, LinkJob, + ArchiveJob, GenerateDSYMJob, VerifyDebugInfoJob, GeneratePCHJob, @@ -313,7 +314,7 @@ class LinkJobAction : public JobAction { LinkJobAction(ArrayRef Inputs, LinkKind K) : JobAction(Action::Kind::LinkJob, Inputs, file_types::TY_Image), Kind(K) { - assert(Kind != LinkKind::None); + assert(Kind != LinkKind::None && Kind != LinkKind::StaticLibrary); } LinkKind getKind() const { return Kind; } @@ -323,6 +324,20 @@ class LinkJobAction : public JobAction { } }; +class ArchiveJobAction : public JobAction { + virtual void anchor(); + +public: + ArchiveJobAction(ArrayRef Inputs, LinkKind K) + : JobAction(Action::Kind::ArchiveJob, Inputs, file_types::TY_Image) { + assert(K == LinkKind::StaticLibrary); + } + + static bool classof(const Action *A) { + return A->getKind() == Action::Kind::ArchiveJob; + } +}; + } // end namespace driver } // end namespace swift diff --git a/include/swift/Driver/ToolChain.h b/include/swift/Driver/ToolChain.h index c8b28c02d72e0..2d414695de55e 100644 --- a/include/swift/Driver/ToolChain.h +++ b/include/swift/Driver/ToolChain.h @@ -161,6 +161,9 @@ class ToolChain { virtual InvocationInfo constructInvocation(const LinkJobAction &job, const JobContext &context) const; + virtual InvocationInfo constructInvocation(const ArchiveJobAction &job, + const JobContext &context) const; + /// Searches for the given executable in appropriate paths relative to the /// Swift binary. /// diff --git a/include/swift/Driver/Util.h b/include/swift/Driver/Util.h index 9859f0a8387af..8f9fd30357fe1 100644 --- a/include/swift/Driver/Util.h +++ b/include/swift/Driver/Util.h @@ -34,7 +34,8 @@ namespace driver { enum class LinkKind { None, Executable, - DynamicLibrary + DynamicLibrary, + StaticLibrary }; /// Used by a Job to request a "filelist": a file containing a list of all diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 5862ccdfcc182..d9dfb2c99cfc2 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -228,6 +228,9 @@ class FrontendOptions { /// the Objective-C half should implicitly be visible to the Swift sources. bool ImportUnderlyingModule = false; + /// If set, this module should be built and linked as a static library. + bool IsStaticLibrary = false; + /// If set, the header provided in ImplicitObjCHeaderPath will be rewritten /// by the Clang importer as part of semantic analysis. bool SerializeBridgingHeader = false; diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h index c4206911720a2..be8d25b0a5fbd 100644 --- a/include/swift/IRGen/Linking.h +++ b/include/swift/IRGen/Linking.h @@ -1177,7 +1177,7 @@ class LinkInfo { static LinkInfo get(const UniversalLinkageInfo &linkInfo, StringRef name, SILLinkage linkage, ForDefinition_t isDefinition, - bool isWeakImported); + bool isWeakImported, bool isStaticLibrary); StringRef getName() const { return Name.str(); diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 1934f7db036f3..3fbdf76707477 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -368,6 +368,10 @@ def emit_objc_header_path : Separate<["-"], "emit-objc-header-path">, ArgumentIsPath]>, MetaVarName<"">, HelpText<"Emit an Objective-C header file to ">; +def static : Flag<["-"], "static">, + Flags<[FrontendOption, ModuleInterfaceOption, NoInteractiveOption]>, + HelpText<"Make this module statically linkable and make the output of -emit-library a static library.">; + def import_cf_types : Flag<["-"], "import-cf-types">, Flags<[FrontendOption, HelpHidden]>, HelpText<"Recognize and import CF types as class types">; diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h index 65f32f7c0ae52..310221e7c402a 100644 --- a/include/swift/Serialization/ModuleFormat.h +++ b/include/swift/Serialization/ModuleFormat.h @@ -600,7 +600,8 @@ namespace options_block { IS_SIB, IS_TESTABLE, RESILIENCE_STRATEGY, - ARE_PRIVATE_IMPORTS_ENABLED + ARE_PRIVATE_IMPORTS_ENABLED, + IS_STATIC_LIBRARY }; using SDKPathLayout = BCRecordLayout< @@ -630,6 +631,10 @@ namespace options_block { RESILIENCE_STRATEGY, BCFixed<2> >; + + using IsStaticLibraryLayout = BCRecordLayout< + IS_STATIC_LIBRARY + >; } /// The record types within the input block. diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index 785a8e4d27158..763616675a1b8 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -98,6 +98,7 @@ class ExtendedValidationInfo { unsigned IsSIB : 1; unsigned IsTestable : 1; unsigned ResilienceStrategy : 2; + unsigned IsStaticLibrary : 1; } Bits; public: ExtendedValidationInfo() : Bits() {} @@ -135,6 +136,11 @@ class ExtendedValidationInfo { void setResilienceStrategy(ResilienceStrategy resilience) { Bits.ResilienceStrategy = unsigned(resilience); } + + bool isStaticLibrary() const { return Bits.IsStaticLibrary; } + void setIsStaticLibrary(bool isStaticLibrary) { + Bits.IsStaticLibrary = isStaticLibrary; + } }; /// Returns info about the serialized AST in the given data. diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp index 95df884e3530c..44421a95a7f30 100644 --- a/lib/Driver/Action.cpp +++ b/lib/Driver/Action.cpp @@ -29,6 +29,7 @@ const char *Action::getClassName(Kind AC) { case Kind::AutolinkExtractJob: return "swift-autolink-extract"; case Kind::REPLJob: return "repl"; case Kind::LinkJob: return "link"; + case Kind::ArchiveJob: return "archive"; case Kind::GenerateDSYMJob: return "generate-dSYM"; case Kind::VerifyDebugInfoJob: return "verify-debug-info"; case Kind::GeneratePCHJob: return "generate-pch"; @@ -57,6 +58,8 @@ void REPLJobAction::anchor() {} void LinkJobAction::anchor() {} +void ArchiveJobAction::anchor() {} + void GenerateDSYMJobAction::anchor() {} void VerifyDebugInfoJobAction::anchor() {} diff --git a/lib/Driver/DarwinToolChains.cpp b/lib/Driver/DarwinToolChains.cpp index 1e26ab873fa36..d8d7d73f9934b 100644 --- a/lib/Driver/DarwinToolChains.cpp +++ b/lib/Driver/DarwinToolChains.cpp @@ -284,6 +284,8 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, case LinkKind::DynamicLibrary: Arguments.push_back("-dylib"); break; + case LinkKind::StaticLibrary: + llvm_unreachable("invalid link kind"); } assert(Triple.isOSDarwin()); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 1f588596411ee..9e3a7a23d7deb 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1255,6 +1255,8 @@ static bool maybeBuildingExecutable(const OutputInfo &OI, return true; case LinkKind::DynamicLibrary: return false; + case LinkKind::StaticLibrary: + return false; case LinkKind::None: break; } @@ -1366,15 +1368,24 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, switch (OutputModeArg->getOption().getID()) { case options::OPT_emit_executable: + if (Args.hasArg(options::OPT_static)) + Diags.diagnose(SourceLoc(), + diag::error_static_emit_executable_disallowed); + OI.LinkAction = LinkKind::Executable; OI.CompilerOutputType = file_types::TY_Object; break; case options::OPT_emit_library: - OI.LinkAction = LinkKind::DynamicLibrary; + OI.LinkAction = Args.hasArg(options::OPT_static) ? + LinkKind::StaticLibrary : + LinkKind::DynamicLibrary; OI.CompilerOutputType = file_types::TY_Object; break; + case options::OPT_static: + break; + case options::OPT_emit_object: OI.CompilerOutputType = file_types::TY_Object; break; @@ -1550,7 +1561,8 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args, OI.ModuleName = "REPL"; } else if (const Arg *A = Args.getLastArg(options::OPT_o)) { OI.ModuleName = llvm::sys::path::stem(A->getValue()); - if (OI.LinkAction == LinkKind::DynamicLibrary && + if ((OI.LinkAction == LinkKind::DynamicLibrary || + OI.LinkAction == LinkKind::StaticLibrary) && !llvm::sys::path::extension(A->getValue()).empty() && StringRef(OI.ModuleName).startswith("lib")) { // Chop off a "lib" prefix if we're building a library. @@ -1949,8 +1961,15 @@ void Driver::buildActions(SmallVectorImpl &TopLevelActions, } if (OI.shouldLink() && !AllLinkerInputs.empty()) { - auto *LinkAction = C.createAction(AllLinkerInputs, - OI.LinkAction); + JobAction *LinkAction = nullptr; + + if (OI.LinkAction == LinkKind::StaticLibrary) { + LinkAction = C.createAction(AllLinkerInputs, + OI.LinkAction); + } else { + LinkAction = C.createAction(AllLinkerInputs, + OI.LinkAction); + } // On ELF platforms there's no built in autolinking mechanism, so we // pull the info we need from the .o files directly and pass them as an @@ -2177,6 +2196,19 @@ static StringRef baseNameForImage(const JobAction *JA, const OutputInfo &OI, StringRef BaseInput, StringRef BaseName) { if (JA->size() == 1 && OI.ModuleNameIsFallback && BaseInput != "-") return llvm::sys::path::stem(BaseInput); + + if (auto link = dyn_cast(JA)) { + Buffer = Triple.isOSWindows() ? "" : "lib"; + Buffer.append(BaseName); + + if (Triple.isOSWindows()) + Buffer.append(".lib"); + else + Buffer.append(".a"); + + return Buffer.str(); + } + auto link = dyn_cast(JA); if (!link) return BaseName; @@ -2192,6 +2224,7 @@ static StringRef baseNameForImage(const JobAction *JA, const OutputInfo &OI, Buffer.append(".dll"); else Buffer.append(".so"); + return Buffer.str(); } diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 321d9aef16b55..4fab274fa40fd 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -100,6 +100,7 @@ std::unique_ptr ToolChain::constructJob( CASE(MergeModuleJob) CASE(ModuleWrapJob) CASE(LinkJob) + CASE(ArchiveJob) CASE(GenerateDSYMJob) CASE(VerifyDebugInfoJob) CASE(GeneratePCHJob) diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index ad75b4b454f50..dc8a8baf0d227 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -208,6 +208,7 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_warnings_as_errors); inputArgs.AddLastArg(arguments, options::OPT_sanitize_EQ); inputArgs.AddLastArg(arguments, options::OPT_sanitize_coverage_EQ); + inputArgs.AddLastArg(arguments, options::OPT_static); inputArgs.AddLastArg(arguments, options::OPT_swift_version); inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ); inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir); @@ -1078,6 +1079,73 @@ ToolChain::constructInvocation(const LinkJobAction &job, llvm_unreachable("linking not implemented for this toolchain"); } +ToolChain::InvocationInfo +ToolChain::constructInvocation(const ArchiveJobAction &job, + const JobContext &context) const { + assert(context.Output.getPrimaryOutputType() == file_types::TY_Image && + "Invalid linker output type."); + + ArgStringList Arguments; + + // Configure the toolchain. + bool isLLVMAR = false; + const char *AR = nullptr; + if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) { + StringRef toolchainPath(A->getValue()); + + // If there is an llvm-ar in the toolchain folder, use that instead. + if (auto toolchainAR = + llvm::sys::findProgramByName("llvm-ar", {toolchainPath})) { + AR = context.Args.MakeArgString(toolchainAR.get()); + isLLVMAR = true; + } + + } + if (AR == nullptr) { + if (auto pathAR = llvm::sys::findProgramByName("llvm-ar", None)) { + AR = context.Args.MakeArgString(pathAR.get()); + isLLVMAR = true; + } + } + if (AR == nullptr) { + if (auto pathAR = llvm::sys::findProgramByName("ar", None)) + AR = context.Args.MakeArgString(pathAR.get()); + } + + assert(AR && + "neither ar nor llvm-ar was not found in the toolchain directory or system path."); + + if (isLLVMAR) { + switch (getTriple().getOS()) { + case llvm::Triple::Darwin: + Arguments.push_back("--format=darwin"); + break; + case llvm::Triple::FreeBSD: + Arguments.push_back("--format=bsd"); + break; + case llvm::Triple::Linux: + Arguments.push_back("--format=gnu"); + break; + default: + break; + } + } + + Arguments.push_back("crs"); + + Arguments.push_back( + context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); + + addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, + file_types::TY_Object); + addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); + + InvocationInfo II{AR, Arguments}; + II.allowsResponseFiles = true; + + return II; +} + void ToolChain::addPathEnvironmentVariableIfNeeded( Job::EnvironmentVector &env, const char *name, const char *separator, options::ID optionID, const ArgList &args, StringRef extraEntry) const { diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp index fb3c8aa910c9e..3b2f7481d5a52 100644 --- a/lib/Driver/UnixToolChains.cpp +++ b/lib/Driver/UnixToolChains.cpp @@ -130,6 +130,8 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, case LinkKind::DynamicLibrary: Arguments.push_back("-shared"); break; + case LinkKind::StaticLibrary: + llvm_unreachable("invalid link kind"); } // Select the linker to use. diff --git a/lib/Driver/WindowsToolChains.cpp b/lib/Driver/WindowsToolChains.cpp index 8a94f7e26540b..b0d3f41b30f82 100644 --- a/lib/Driver/WindowsToolChains.cpp +++ b/lib/Driver/WindowsToolChains.cpp @@ -61,6 +61,8 @@ toolchains::Windows::constructInvocation(const LinkJobAction &job, case LinkKind::DynamicLibrary: Arguments.push_back("-shared"); break; + case LinkKind::StaticLibrary: + llvm_unreachable("invalid link kind"); } // Select the linker to use. diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index d2d7c8f3586f6..e5c187a0af81d 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -72,6 +72,8 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.EnableTesting |= Args.hasArg(OPT_enable_testing); Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports); Opts.EnableLibraryEvolution |= Args.hasArg(OPT_enable_library_evolution); + + Opts.IsStaticLibrary |= Args.hasArg(OPT_static); // FIXME: Remove this flag Opts.EnableLibraryEvolution |= Args.hasArg(OPT_enable_resilience); diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 4a3b147a05ece..61ae54584e56d 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -535,6 +535,8 @@ ModuleDecl *CompilerInstance::getMainModule() { MainModule->setPrivateImportsEnabled(); if (Invocation.getFrontendOptions().EnableImplicitDynamic) MainModule->setImplicitDynamicEnabled(); + if (Invocation.getFrontendOptions().IsStaticLibrary) + MainModule->setIsStaticLibrary(); if (Invocation.getFrontendOptions().EnableLibraryEvolution) MainModule->setResilienceStrategy(ResilienceStrategy::Resilient); diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 5226ce832bbd3..e05f54d553767 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -1605,12 +1605,15 @@ void IRGenModule::emitVTableStubs() { static IRLinkage getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, ForDefinition_t isDefinition, - bool isWeakImported) { + bool isWeakImported, + bool isStaticLibrary) { #define RESULT(LINKAGE, VISIBILITY, DLL_STORAGE) \ IRLinkage{llvm::GlobalValue::LINKAGE##Linkage, \ llvm::GlobalValue::VISIBILITY##Visibility, \ llvm::GlobalValue::DLL_STORAGE##StorageClass} + bool useDLLStorage = info.UseDLLStorage && !isStaticLibrary; + // Use protected visibility for public symbols we define on ELF. ld.so // doesn't support relative relocations at load time, which interferes with // our metadata formats. Default visibility should suffice for other object @@ -1619,11 +1622,11 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, info.IsELFObject ? llvm::GlobalValue::ProtectedVisibility : llvm::GlobalValue::DefaultVisibility; llvm::GlobalValue::DLLStorageClassTypes ExportedStorage = - info.UseDLLStorage ? llvm::GlobalValue::DLLExportStorageClass - : llvm::GlobalValue::DefaultStorageClass; + useDLLStorage ? llvm::GlobalValue::DLLExportStorageClass + : llvm::GlobalValue::DefaultStorageClass; llvm::GlobalValue::DLLStorageClassTypes ImportedStorage = - info.UseDLLStorage ? llvm::GlobalValue::DLLImportStorageClass - : llvm::GlobalValue::DefaultStorageClass; + (useDLLStorage && !isDefinition) ? llvm::GlobalValue::DLLImportStorageClass + : llvm::GlobalValue::DefaultStorageClass; switch (linkage) { case SILLinkage::Public: @@ -1645,7 +1648,7 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, case SILLinkage::Private: { if (info.forcePublicDecls() && !isDefinition) return getIRLinkage(info, SILLinkage::PublicExternal, isDefinition, - isWeakImported); + isWeakImported, isStaticLibrary); auto linkage = info.needLinkerToMergeDuplicateSymbols() ? llvm::GlobalValue::LinkOnceODRLinkage : llvm::GlobalValue::InternalLinkage; @@ -1687,9 +1690,10 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM, UniversalLinkageInfo linkInfo(IGM); bool weakImported = entity.isWeakImported(IGM.getSwiftModule(), IGM.getAvailabilityContext()); + bool isStaticLibrary = IGM.getSwiftModule()->isStaticLibrary(); auto IRL = getIRLinkage(linkInfo, entity.getLinkage(ForDefinition), - ForDefinition, weakImported); + ForDefinition, weakImported, isStaticLibrary); ApplyIRLinkage(IRL).to(global); // Everything externally visible is considered used in Swift. @@ -1729,19 +1733,21 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo, entity.mangle(result.Name); bool weakImported = entity.isWeakImported(swiftModule, availabilityContext); + bool isStaticLibrary = swiftModule->isStaticLibrary(); result.IRL = getIRLinkage(linkInfo, entity.getLinkage(isStdlibOrDefinition), - isDefinition, weakImported); + isDefinition, weakImported, isStaticLibrary); result.ForDefinition = isDefinition; return result; } LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo, StringRef name, SILLinkage linkage, ForDefinition_t isDefinition, - bool isWeakImported) { + bool isWeakImported, bool isStaticLibrary) { LinkInfo result; result.Name += name; - result.IRL = getIRLinkage(linkInfo, linkage, isDefinition, isWeakImported); + result.IRL = getIRLinkage(linkInfo, linkage, isDefinition, isWeakImported, + isStaticLibrary); result.ForDefinition = isDefinition; return result; } diff --git a/lib/Serialization/ModuleFile.cpp b/lib/Serialization/ModuleFile.cpp index d5c4190d575ae..e83988f08875e 100644 --- a/lib/Serialization/ModuleFile.cpp +++ b/lib/Serialization/ModuleFile.cpp @@ -120,6 +120,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor, options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy); extendedInfo.setResilienceStrategy(ResilienceStrategy(Strategy)); break; + case options_block::IS_STATIC_LIBRARY: + extendedInfo.setIsStaticLibrary(true); + break; default: // Unknown options record, possibly for use by a future version of the // module format. diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index cf2b2bc9ee9a7..13ab519fe6d88 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -828,6 +828,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(options_block, IS_TESTABLE); BLOCK_RECORD(options_block, ARE_PRIVATE_IMPORTS_ENABLED); BLOCK_RECORD(options_block, RESILIENCE_STRATEGY); + BLOCK_RECORD(options_block, IS_STATIC_LIBRARY); BLOCK(INPUT_BLOCK); BLOCK_RECORD(input_block, IMPORTED_MODULE); @@ -993,6 +994,11 @@ void Serializer::writeHeader(const SerializationOptions &options) { Strategy.emit(ScratchRecord, unsigned(M->getResilienceStrategy())); } + if (M->isStaticLibrary()) { + options_block::IsStaticLibraryLayout IsStaticLibrary(Out); + IsStaticLibrary.emit(ScratchRecord); + } + if (options.SerializeOptionsForDebugging) { options_block::SDKPathLayout SDKPath(Out); options_block::XCCLayout XCC(Out); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 927e12aa2dc82..15806d2c004e6 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -552,6 +552,8 @@ FileUnit *SerializedModuleLoaderBase::loadAST( M.setTestingEnabled(); if (extendedInfo.arePrivateImportsEnabled()) M.setPrivateImportsEnabled(); + if (extendedInfo.isStaticLibrary()) + M.setIsStaticLibrary(); auto diagLocOrInvalid = diagLoc.getValueOr(SourceLoc()); loadInfo.status =