diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index ac13b2e983978..0fd4d044c0d58 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -377,6 +377,9 @@ class IRGenOptions { unsigned InternalizeAtLink : 1; + /// Internalize symbols (static library) - do not export any public symbols. + unsigned InternalizeSymbols : 1; + /// Whether to avoid emitting zerofill globals as preallocated type metadata /// and prototol conformance caches. unsigned NoPreallocatedInstantiationCaches : 1; @@ -443,7 +446,7 @@ class IRGenOptions { DisableStandardSubstitutionsInReflectionMangling(false), EnableGlobalISel(false), VirtualFunctionElimination(false), WitnessMethodElimination(false), ConditionalRuntimeRecords(false), - InternalizeAtLink(false), + InternalizeAtLink(false), InternalizeSymbols(false), NoPreallocatedInstantiationCaches(false), CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()), diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h index 2c0ff2a8a6828..552d2db833921 100644 --- a/include/swift/IRGen/Linking.h +++ b/include/swift/IRGen/Linking.h @@ -46,6 +46,7 @@ class UniversalLinkageInfo { public: bool IsELFObject; bool UseDLLStorage; + bool Internalize; /// True iff are multiple llvm modules. bool HasMultipleIGMs; @@ -57,7 +58,7 @@ class UniversalLinkageInfo { explicit UniversalLinkageInfo(IRGenModule &IGM); UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs, - bool forcePublicDecls); + bool forcePublicDecls, bool isStaticLibrary); /// In case of multiple llvm modules (in multi-threaded compilation) all /// private decls must be visible from other files. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 93ef56ead656e..98acf95af66ec 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -2190,6 +2190,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args, Opts.InternalizeAtLink = true; } + Opts.InternalizeSymbols = FrontendOpts.Static; + if (Args.hasArg(OPT_disable_preallocated_instantiation_caches)) { Opts.NoPreallocatedInstantiationCaches = true; } diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 22436c3279d9c..3229a81aeb9e9 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -2020,7 +2020,9 @@ void IRGenModule::emitVTableStubs() { if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden) alias->setVisibility(llvm::GlobalValue::HiddenVisibility); else - ApplyIRLinkage(IRLinkage::ExternalExport).to(alias); + ApplyIRLinkage(IRGen.Opts.InternalizeSymbols + ? IRLinkage::Internal + : IRLinkage::ExternalExport).to(alias); } } @@ -2090,7 +2092,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, switch (linkage) { case SILLinkage::Public: return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility, - ExportedStorage}; + info.Internalize ? llvm::GlobalValue::DefaultStorageClass + : ExportedStorage}; case SILLinkage::PublicNonABI: return isDefinition ? RESULT(WeakODR, Hidden, Default) diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp index acee202ed887c..03a66fdf7bcb9 100644 --- a/lib/IRGen/GenKeyPath.cpp +++ b/lib/IRGen/GenKeyPath.cpp @@ -1352,7 +1352,9 @@ void IRGenModule::emitSILProperty(SILProperty *prop) { TheTrivialPropertyDescriptor); ApplyIRLinkage({linkInfo.getLinkage(), linkInfo.getVisibility(), - llvm::GlobalValue::DLLExportStorageClass}) + IRGen.Opts.InternalizeSymbols + ? llvm::GlobalValue::DefaultStorageClass + : llvm::GlobalValue::DLLExportStorageClass}) .to(GA, linkInfo.isForDefinition()); } return; diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 3931f378d31e8..d31660983a543 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -1574,7 +1574,9 @@ static llvm::GlobalObject *createForceImportThunk(IRGenModule &IGM) { llvm::GlobalValue::LinkOnceODRLinkage, buf, &IGM.Module); ForceImportThunk->setAttributes(IGM.constructInitialAttributes()); - ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk); + ApplyIRLinkage(IGM.IRGen.Opts.InternalizeSymbols + ? IRLinkage::Internal + : IRLinkage::ExternalExport).to(ForceImportThunk); if (IGM.Triple.supportsCOMDAT()) if (auto *GO = cast(ForceImportThunk)) GO->setComdat(IGM.Module.getOrInsertComdat(ForceImportThunk->getName())); diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp index 56a1fb337a63a..40b2478b8802f 100644 --- a/lib/IRGen/Linking.cpp +++ b/lib/IRGen/Linking.cpp @@ -80,14 +80,16 @@ bool swift::irgen::useDllStorage(const llvm::Triple &triple) { UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM) : UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(), - IGM.IRGen.Opts.ForcePublicLinkage) {} + IGM.IRGen.Opts.ForcePublicLinkage, + IGM.IRGen.Opts.InternalizeSymbols) {} UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs, - bool forcePublicDecls) + bool forcePublicDecls, + bool isStaticLibrary) : IsELFObject(triple.isOSBinFormatELF()), UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs), - ForcePublicDecls(forcePublicDecls) {} + Internalize(isStaticLibrary), ForcePublicDecls(forcePublicDecls) {} /// Mangle this entity into the given buffer. void LinkEntity::mangle(SmallVectorImpl &buffer) const { diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h index d7c1a878cfd5f..3e41c791a2658 100644 --- a/lib/TBDGen/TBDGenVisitor.h +++ b/lib/TBDGen/TBDGenVisitor.h @@ -173,7 +173,8 @@ class TBDGenVisitor : public ASTVisitor { ModuleDecl *swiftModule, const TBDGenOptions &opts, APIRecorder &recorder) : DataLayoutDescription(dataLayoutString), - UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false), + UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false, + /*static=*/false), SwiftModule(swiftModule), Opts(opts), recorder(recorder), previousInstallNameMap(parsePreviousModuleInstallNameMap()) {} diff --git a/test/IRGen/static-library.swift b/test/IRGen/static-library.swift new file mode 100644 index 0000000000000..c11346a16da35 --- /dev/null +++ b/test/IRGen/static-library.swift @@ -0,0 +1,76 @@ +// RUN: %empty-directory(%t) +// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -DLIBRARY -module-name Library -emit-library -static -autolink-force-load -module-link-name Library %s -o %t/library.lib -emit-module-path %t +// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -DLIBRARY -module-name Library -emit-library -static -autolink-force-load -module-link-name Library %s -S -emit-ir -o - | %FileCheck -check-prefix CHECK-LIBRARY %s +// RUN: %swiftc_driver_plain -target x86_64-unknown-windows-msvc -I %t -emit-library -S -emit-ir -o - %s | %FileCheck -check-prefix CHECK-EMBEDDING %s + +// REQUIRES: OS=windows-msvc + +#if LIBRARY + +// nominal type descriptor for Library.C +// CHECK-LIBRARY: @"$s7Library1CCMn" = constant + +// nominal type descriptor for Library.S +// CHECK-LIBRARY: @"$s7Library1SVMn" = constant + +// method descriptor for Library.C.method +// CHECK-LBRARY: @"$s7Library1CC6methodyyFTq" = alias + +// type metadata for Library.C +// CHECK-LIBRARY: @"$s7Library1CCN" = alias + +// type metadata for Library.S +// CHECK-LIBRARY: @"$s7Library1SVN" = alias + +public func f() { +} + +// Library.f() -> () +// CHECK-LIBRARY: define swiftcc void @"$s7Library1fyyF"() + +open class C { + var property: () -> () { + return f + } + + open func method() { + } +} + +// Library.C.method() -> () +// CHECK-LIBRARY: define swiftcc void @"$s7Library1CC6methodyyF"(%T7Library1CC* swiftself %0) + +// Library.C.deinit +// CHECK-LIBRARY: define swiftcc %swift.refcounted* @"$s7Library1CCfd"(%T7Library1CC* swiftself %0) + +// Library.C.__deallocating_deinit +// CHECK-LIBRARY: define swiftcc void @"$s7Library1CCfD"(%T7Library1CC* swiftself %0) + +// Library.C.__allocating_init() -> Library.C +// CHECK-LIBRARY: define swiftcc %T7Library1CC* @"$s7Library1CCACycfC"(%swift.type* swiftself %0) + +public struct S { + var member: () -> Void = f +} + +// variable initialization expression of Library.S.member : () -> () +// CHECK-LIBRARY: define swiftcc { i8*, %swift.refcounted* } @"$s7Library1SV6memberyycvpfi"() + +// type metadata accessor for Library.C +// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1CCMa"(i64 %0) + +// type metadata accessor for Library.S +// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1SVMa"(i64 %0) + +// CHECK-LIBRARY: define internal void @"_swift_FORCE_LOAD_$_Library"() + +#else +import Library +func f() { + Library.f() +} + +// CHECK-EMBEDDING-NOT: @"_swift_FORCE_LOAD_$_Library" + +#endif +