Skip to content

Commit 98bd2db

Browse files
committedFeb 18, 2022
IRGen: internalize symbols with -static
This pipes the `-static` flag when building a static library into IRGen. This should have no impact on non-Windows targets as the usage of the information simply removes the `dllexport` attribute on the generated interfaces. This ensures that a library built with `-static` will not re-export its interfaces from the consumer. This is important to ensure that the consumer does not vend the API surface when it statically links a library. In conjunction with the removal of the force load symbol, this allows the generation of static libraries which may be linked against on Windows. However, a subsequent change is needed to ensure that the consumer does not mark the symbol as being imported from a foreign module (i.e. `dllimport`).
1 parent b296d41 commit 98bd2db

File tree

9 files changed

+102
-10
lines changed

9 files changed

+102
-10
lines changed
 

‎include/swift/AST/IRGenOptions.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ class IRGenOptions {
377377

378378
unsigned InternalizeAtLink : 1;
379379

380+
/// Internalize symbols (static library) - do not export any public symbols.
381+
unsigned InternalizeSymbols : 1;
382+
380383
/// Whether to avoid emitting zerofill globals as preallocated type metadata
381384
/// and prototol conformance caches.
382385
unsigned NoPreallocatedInstantiationCaches : 1;
@@ -443,7 +446,7 @@ class IRGenOptions {
443446
DisableStandardSubstitutionsInReflectionMangling(false),
444447
EnableGlobalISel(false), VirtualFunctionElimination(false),
445448
WitnessMethodElimination(false), ConditionalRuntimeRecords(false),
446-
InternalizeAtLink(false),
449+
InternalizeAtLink(false), InternalizeSymbols(false),
447450
NoPreallocatedInstantiationCaches(false),
448451
CmdArgs(),
449452
SanitizeCoverage(llvm::SanitizerCoverageOptions()),

‎include/swift/IRGen/Linking.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class UniversalLinkageInfo {
4646
public:
4747
bool IsELFObject;
4848
bool UseDLLStorage;
49+
bool Internalize;
4950

5051
/// True iff are multiple llvm modules.
5152
bool HasMultipleIGMs;
@@ -57,7 +58,7 @@ class UniversalLinkageInfo {
5758
explicit UniversalLinkageInfo(IRGenModule &IGM);
5859

5960
UniversalLinkageInfo(const llvm::Triple &triple, bool hasMultipleIGMs,
60-
bool forcePublicDecls);
61+
bool forcePublicDecls, bool isStaticLibrary);
6162

6263
/// In case of multiple llvm modules (in multi-threaded compilation) all
6364
/// private decls must be visible from other files.

‎lib/Frontend/CompilerInvocation.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -2190,6 +2190,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
21902190
Opts.InternalizeAtLink = true;
21912191
}
21922192

2193+
Opts.InternalizeSymbols = FrontendOpts.Static;
2194+
21932195
if (Args.hasArg(OPT_disable_preallocated_instantiation_caches)) {
21942196
Opts.NoPreallocatedInstantiationCaches = true;
21952197
}

‎lib/IRGen/GenDecl.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,9 @@ void IRGenModule::emitVTableStubs() {
20202020
if (F.getEffectiveSymbolLinkage() == SILLinkage::Hidden)
20212021
alias->setVisibility(llvm::GlobalValue::HiddenVisibility);
20222022
else
2023-
ApplyIRLinkage(IRLinkage::ExternalExport).to(alias);
2023+
ApplyIRLinkage(IRGen.Opts.InternalizeSymbols
2024+
? IRLinkage::Internal
2025+
: IRLinkage::ExternalExport).to(alias);
20242026
}
20252027
}
20262028

@@ -2090,7 +2092,8 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage,
20902092
switch (linkage) {
20912093
case SILLinkage::Public:
20922094
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility,
2093-
ExportedStorage};
2095+
info.Internalize ? llvm::GlobalValue::DefaultStorageClass
2096+
: ExportedStorage};
20942097

20952098
case SILLinkage::PublicNonABI:
20962099
return isDefinition ? RESULT(WeakODR, Hidden, Default)

‎lib/IRGen/GenKeyPath.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,9 @@ void IRGenModule::emitSILProperty(SILProperty *prop) {
13521352
TheTrivialPropertyDescriptor);
13531353
ApplyIRLinkage({linkInfo.getLinkage(),
13541354
linkInfo.getVisibility(),
1355-
llvm::GlobalValue::DLLExportStorageClass})
1355+
IRGen.Opts.InternalizeSymbols
1356+
? llvm::GlobalValue::DefaultStorageClass
1357+
: llvm::GlobalValue::DLLExportStorageClass})
13561358
.to(GA, linkInfo.isForDefinition());
13571359
}
13581360
return;

‎lib/IRGen/IRGenModule.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,9 @@ static llvm::GlobalObject *createForceImportThunk(IRGenModule &IGM) {
15741574
llvm::GlobalValue::LinkOnceODRLinkage, buf,
15751575
&IGM.Module);
15761576
ForceImportThunk->setAttributes(IGM.constructInitialAttributes());
1577-
ApplyIRLinkage(IRLinkage::ExternalExport).to(ForceImportThunk);
1577+
ApplyIRLinkage(IGM.IRGen.Opts.InternalizeSymbols
1578+
? IRLinkage::Internal
1579+
: IRLinkage::ExternalExport).to(ForceImportThunk);
15781580
if (IGM.Triple.supportsCOMDAT())
15791581
if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
15801582
GO->setComdat(IGM.Module.getOrInsertComdat(ForceImportThunk->getName()));

‎lib/IRGen/Linking.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,16 @@ bool swift::irgen::useDllStorage(const llvm::Triple &triple) {
8080

8181
UniversalLinkageInfo::UniversalLinkageInfo(IRGenModule &IGM)
8282
: UniversalLinkageInfo(IGM.Triple, IGM.IRGen.hasMultipleIGMs(),
83-
IGM.IRGen.Opts.ForcePublicLinkage) {}
83+
IGM.IRGen.Opts.ForcePublicLinkage,
84+
IGM.IRGen.Opts.InternalizeSymbols) {}
8485

8586
UniversalLinkageInfo::UniversalLinkageInfo(const llvm::Triple &triple,
8687
bool hasMultipleIGMs,
87-
bool forcePublicDecls)
88+
bool forcePublicDecls,
89+
bool isStaticLibrary)
8890
: IsELFObject(triple.isOSBinFormatELF()),
8991
UseDLLStorage(useDllStorage(triple)), HasMultipleIGMs(hasMultipleIGMs),
90-
ForcePublicDecls(forcePublicDecls) {}
92+
Internalize(isStaticLibrary), ForcePublicDecls(forcePublicDecls) {}
9193

9294
/// Mangle this entity into the given buffer.
9395
void LinkEntity::mangle(SmallVectorImpl<char> &buffer) const {

‎lib/TBDGen/TBDGenVisitor.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
173173
ModuleDecl *swiftModule, const TBDGenOptions &opts,
174174
APIRecorder &recorder)
175175
: DataLayoutDescription(dataLayoutString),
176-
UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false),
176+
UniversalLinkInfo(target, opts.HasMultipleIGMs, /*forcePublic*/ false,
177+
/*static=*/false),
177178
SwiftModule(swiftModule), Opts(opts), recorder(recorder),
178179
previousInstallNameMap(parsePreviousModuleInstallNameMap()) {}
179180

‎test/IRGen/static-library.swift

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// RUN: %empty-directory(%t)
2+
// 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
3+
// 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
4+
// 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
5+
6+
// REQUIRES: OS=windows-msvc
7+
8+
#if LIBRARY
9+
10+
// nominal type descriptor for Library.C
11+
// CHECK-LIBRARY: @"$s7Library1CCMn" = constant
12+
13+
// nominal type descriptor for Library.S
14+
// CHECK-LIBRARY: @"$s7Library1SVMn" = constant
15+
16+
// method descriptor for Library.C.method
17+
// CHECK-LBRARY: @"$s7Library1CC6methodyyFTq" = alias
18+
19+
// type metadata for Library.C
20+
// CHECK-LIBRARY: @"$s7Library1CCN" = alias
21+
22+
// type metadata for Library.S
23+
// CHECK-LIBRARY: @"$s7Library1SVN" = alias
24+
25+
public func f() {
26+
}
27+
28+
// Library.f() -> ()
29+
// CHECK-LIBRARY: define swiftcc void @"$s7Library1fyyF"()
30+
31+
open class C {
32+
var property: () -> () {
33+
return f
34+
}
35+
36+
open func method() {
37+
}
38+
}
39+
40+
// Library.C.method() -> ()
41+
// CHECK-LIBRARY: define swiftcc void @"$s7Library1CC6methodyyF"(%T7Library1CC* swiftself %0)
42+
43+
// Library.C.deinit
44+
// CHECK-LIBRARY: define swiftcc %swift.refcounted* @"$s7Library1CCfd"(%T7Library1CC* swiftself %0)
45+
46+
// Library.C.__deallocating_deinit
47+
// CHECK-LIBRARY: define swiftcc void @"$s7Library1CCfD"(%T7Library1CC* swiftself %0)
48+
49+
// Library.C.__allocating_init() -> Library.C
50+
// CHECK-LIBRARY: define swiftcc %T7Library1CC* @"$s7Library1CCACycfC"(%swift.type* swiftself %0)
51+
52+
public struct S {
53+
var member: () -> Void = f
54+
}
55+
56+
// variable initialization expression of Library.S.member : () -> ()
57+
// CHECK-LIBRARY: define swiftcc { i8*, %swift.refcounted* } @"$s7Library1SV6memberyycvpfi"()
58+
59+
// type metadata accessor for Library.C
60+
// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1CCMa"(i64 %0)
61+
62+
// type metadata accessor for Library.S
63+
// CHECK-LIBRARY: define swiftcc %swift.metadata_response @"$s7Library1SVMa"(i64 %0)
64+
65+
// CHECK-LIBRARY: define internal void @"_swift_FORCE_LOAD_$_Library"()
66+
67+
#else
68+
import Library
69+
func f() {
70+
Library.f()
71+
}
72+
73+
// CHECK-EMBEDDING-NOT: @"_swift_FORCE_LOAD_$_Library"
74+
75+
#endif
76+

0 commit comments

Comments
 (0)