Skip to content

Commit 3ee9b11

Browse files
committed
TBDGen: when previous install name map is specified, emit $ld$previous linker directives.
Progress towards: rdar://58281536
1 parent acce4a0 commit 3ee9b11

11 files changed

+158
-17
lines changed

include/swift/AST/Attr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,7 @@ class OriginallyDefinedInAttr: public DeclAttribute {
16071607
const llvm::VersionTuple MovedVersion;
16081608

16091609
struct ActiveVersion {
1610+
StringRef ModuleName;
16101611
PlatformKind Platform;
16111612
bool IsSimulator;
16121613
llvm::VersionTuple Version;

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,11 @@ class alignas(1 << DeclAlignInBits) Decl {
753753
return Attrs;
754754
}
755755

756+
/// Returns the introduced OS version in the given platform kind specified
757+
/// by @available attribute.
758+
/// This function won't consider the parent context to get the information.
759+
Optional<llvm::VersionTuple> getIntroducedOSVersion(PlatformKind Kind) const;
760+
756761
/// Returns the starting location of the entire declaration.
757762
SourceLoc getStartLoc() const { return getSourceRange().Start; }
758763

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ REMARK(platform_previous_install_name, none,
282282
ERROR(unknown_platform_name, none,
283283
"unkown platform name %0", (StringRef))
284284

285+
ERROR(cannot_find_install_name, none,
286+
"cannot find previous install name for module %0 in %1", (StringRef, StringRef))
287+
285288
ERROR(symbol_in_tbd_not_in_ir,none,
286289
"symbol '%0' (%1) is in TBD file, but not in generated IR",
287290
(StringRef, StringRef))

lib/AST/Attr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,7 @@ OriginallyDefinedInAttr::isActivePlatform(const ASTContext &ctx) const {
12911291
OriginallyDefinedInAttr::ActiveVersion Result;
12921292
Result.Platform = Platform;
12931293
Result.Version = MovedVersion;
1294+
Result.ModuleName = OriginalModuleName;
12941295
if (isPlatformActive(Platform, ctx.LangOpts)) {
12951296
Result.IsSimulator = ctx.LangOpts.Target.isSimulatorEnvironment();
12961297
return Result;

lib/AST/Decl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,18 @@ StringRef Decl::getDescriptiveKindName(DescriptiveDeclKind K) {
331331
llvm_unreachable("bad DescriptiveDeclKind");
332332
}
333333

334+
Optional<llvm::VersionTuple>
335+
Decl::getIntroducedOSVersion(PlatformKind Kind) const {
336+
for (auto *attr: getAttrs()) {
337+
if (auto *ava = dyn_cast<AvailableAttr>(attr)) {
338+
if (ava->Platform == Kind && ava->Introduced) {
339+
return ava->Introduced;
340+
}
341+
}
342+
}
343+
return None;
344+
}
345+
334346
llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS,
335347
StaticSpellingKind SSK) {
336348
switch (SSK) {

lib/TBDGen/TBDGen.cpp

Lines changed: 85 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,6 @@ getAllMovedPlatformVersions(Decl *D) {
8686
return Results;
8787
}
8888

89-
static Optional<llvm::VersionTuple>
90-
getIntroducedOSVersion(Decl *D, PlatformKind Kind) {
91-
for (auto *attr: D->getAttrs()) {
92-
if (auto *ava = dyn_cast<AvailableAttr>(attr)) {
93-
if (ava->Platform == Kind && ava->Introduced) {
94-
return ava->Introduced;
95-
}
96-
}
97-
}
98-
return None;
99-
}
100-
10189
static StringRef getLinkerPlatformName(uint8_t Id) {
10290
switch (Id) {
10391
#define LD_PLATFORM(Name, Id) case Id: return #Name;
@@ -245,8 +233,85 @@ TBDGenVisitor::parsePreviousModuleInstallNameMap() {
245233
return pResult;
246234
}
247235

248-
void TBDGenVisitor::addLinkerDirectiveSymbols(StringRef name,
249-
llvm::MachO::SymbolKind kind) {
236+
static LinkerPlatformId
237+
getLinkerPlatformId(OriginallyDefinedInAttr::ActiveVersion Ver) {
238+
switch(Ver.Platform) {
239+
case swift::PlatformKind::none:
240+
llvm_unreachable("cannot find platform kind");
241+
case swift::PlatformKind::iOS:
242+
case swift::PlatformKind::iOSApplicationExtension:
243+
return Ver.IsSimulator ? LinkerPlatformId::iOS_sim:
244+
LinkerPlatformId::iOS;
245+
case swift::PlatformKind::tvOS:
246+
case swift::PlatformKind::tvOSApplicationExtension:
247+
return Ver.IsSimulator ? LinkerPlatformId::tvOS_sim:
248+
LinkerPlatformId::tvOS;
249+
case swift::PlatformKind::watchOS:
250+
case swift::PlatformKind::watchOSApplicationExtension:
251+
return Ver.IsSimulator ? LinkerPlatformId::watchOS_sim:
252+
LinkerPlatformId::watchOS;
253+
case swift::PlatformKind::OSX:
254+
case swift::PlatformKind::OSXApplicationExtension:
255+
return LinkerPlatformId::macOS;
256+
}
257+
}
258+
259+
static StringRef
260+
getLinkerPlatformName(OriginallyDefinedInAttr::ActiveVersion Ver) {
261+
return getLinkerPlatformName((uint8_t)getLinkerPlatformId(Ver));
262+
}
263+
264+
void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious(StringRef name,
265+
llvm::MachO::SymbolKind kind) {
266+
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
267+
return;
268+
if (!TopLevelDecl)
269+
return;
270+
auto MovedVers = getAllMovedPlatformVersions(TopLevelDecl);
271+
if (MovedVers.empty())
272+
return;
273+
assert(!MovedVers.empty());
274+
assert(previousInstallNameMap);
275+
auto &Ctx = TopLevelDecl->getASTContext();
276+
for (auto &Ver: MovedVers) {
277+
auto IntroVer = TopLevelDecl->getIntroducedOSVersion(Ver.Platform);
278+
assert(IntroVer && "cannot find OS intro version");
279+
if (!IntroVer.hasValue())
280+
continue;
281+
auto PlatformNumber = getLinkerPlatformId(Ver);
282+
auto It = previousInstallNameMap->find(Ver.ModuleName);
283+
if (It == previousInstallNameMap->end()) {
284+
Ctx.Diags.diagnose(SourceLoc(), diag::cannot_find_install_name,
285+
Ver.ModuleName, getLinkerPlatformName(Ver));
286+
continue;
287+
}
288+
auto InstallName = It->second.getInstallName(PlatformNumber);
289+
if (InstallName.empty()) {
290+
Ctx.Diags.diagnose(SourceLoc(), diag::cannot_find_install_name,
291+
Ver.ModuleName, getLinkerPlatformName(Ver));
292+
continue;
293+
}
294+
llvm::SmallString<64> Buffer;
295+
llvm::raw_svector_ostream OS(Buffer);
296+
// Empty compatible version indicates using the current compatible version.
297+
StringRef ComptibleVersion = "";
298+
OS << "$ld$previous$";
299+
OS << InstallName << "$";
300+
OS << ComptibleVersion << "$";
301+
OS << std::to_string((uint8_t)PlatformNumber) << "$";
302+
static auto getMinor = [](Optional<unsigned> Minor) {
303+
return Minor.hasValue() ? *Minor : 0;
304+
};
305+
OS << IntroVer->getMajor() << "." << getMinor(IntroVer->getMinor()) << "$";
306+
OS << Ver.Version.getMajor() << "." << getMinor(Ver.Version.getMinor()) << "$";
307+
OS << name << "$";
308+
addSymbolInternal(OS.str(), llvm::MachO::SymbolKind::GlobalSymbol,
309+
/*LinkerDirective*/true);
310+
}
311+
}
312+
313+
void TBDGenVisitor::addLinkerDirectiveSymbolsLdHide(StringRef name,
314+
llvm::MachO::SymbolKind kind) {
250315
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
251316
return;
252317
if (!TopLevelDecl)
@@ -265,7 +330,7 @@ void TBDGenVisitor::addLinkerDirectiveSymbols(StringRef name,
265330
unsigned Minor[2];
266331
Major[1] = MovedVer.getMajor();
267332
Minor[1] = MovedVer.getMinor().hasValue() ? *MovedVer.getMinor(): 0;
268-
auto IntroVer = getIntroducedOSVersion(TopLevelDecl, Platform);
333+
auto IntroVer = TopLevelDecl->getIntroducedOSVersion(Platform);
269334
assert(IntroVer && "cannot find the start point of availability");
270335
if (!IntroVer.hasValue())
271336
return;
@@ -296,7 +361,11 @@ void TBDGenVisitor::addSymbol(StringRef name, SymbolKind kind) {
296361
SmallString<32> mangled;
297362
llvm::Mangler::getNameWithPrefix(mangled, name, DataLayout);
298363
addSymbolInternal(mangled, kind);
299-
addLinkerDirectiveSymbols(mangled, kind);
364+
if (previousInstallNameMap) {
365+
addLinkerDirectiveSymbolsLdPrevious(mangled, kind);
366+
} else {
367+
addLinkerDirectiveSymbolsLdHide(mangled, kind);
368+
}
300369
}
301370

302371
void TBDGenVisitor::addSymbol(SILDeclRef declRef) {

lib/TBDGen/TBDGenVisitor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
7878
parsePreviousModuleInstallNameMap();
7979
void addSymbolInternal(StringRef name, llvm::MachO::SymbolKind kind,
8080
bool isLinkerDirective = false);
81-
void addLinkerDirectiveSymbols(StringRef name, llvm::MachO::SymbolKind kind);
81+
void addLinkerDirectiveSymbolsLdHide(StringRef name, llvm::MachO::SymbolKind kind);
82+
void addLinkerDirectiveSymbolsLdPrevious(StringRef name, llvm::MachO::SymbolKind kind);
8283
void addSymbol(StringRef name, llvm::MachO::SymbolKind kind =
8384
llvm::MachO::SymbolKind::GlobalSymbol);
8485

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"module": "ToasterKit",
4+
"install_name": "/System/Previous/macOS/ToasterKit.dylib",
5+
"platforms": ["macOS"]
6+
},
7+
{
8+
"module": "ToasterKit",
9+
"install_name": "/System/Previous/iOS/ToasterKit.dylib",
10+
"platforms": ["iOS"]
11+
}
12+
]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@available(OSX 10.8, iOS 10.2, *)
2+
@_originallyDefinedIn(module: "ToasterKit", macOS 10.15, iOS 13)
3+
public func toast() {}
4+
5+
@available(OSX 10.8, iOS 10.2, *)
6+
@_originallyDefinedIn(module: "ToasterKit", macOS 10.15, iOS 13)
7+
public struct Vehicle {
8+
public func move() {}
9+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// REQUIRES: OS=ios
2+
3+
// RUN: %empty-directory(%t)
4+
5+
// RUN: %target-swift-frontend -typecheck %S/Inputs/linker-directive.swift -tbd-is-installapi -emit-tbd -emit-tbd-path %t/linker_directives.tbd -previous-module-installname-map-file %S/Inputs/install-name-map-toasterkit.json
6+
// RUN: %FileCheck %s < %t/linker_directives.tbd
7+
// RUN: %target-swift-frontend -typecheck %S/Inputs/linker-directive.swift -emit-tbd -emit-tbd-path %t/linker_directives.tbd -previous-module-installname-map-file %S/Inputs/install-name-map-toasterkit.json
8+
// RUN: %FileCheck %s < %t/linker_directives.tbd
9+
10+
// CHECK: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit5toastyyF$
11+
// CHECK: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit7VehicleV4moveyyF$
12+
// CHECK: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit7VehicleVMa$
13+
// CHECK: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit7VehicleVMn$
14+
// CHECK: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit7VehicleVN$
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// REQUIRES: OS=macosx
2+
3+
// RUN: %empty-directory(%t)
4+
5+
// RUN: %target-swift-frontend -typecheck %S/Inputs/linker-directive.swift -tbd-is-installapi -emit-tbd -emit-tbd-path %t/linker_directives.tbd -previous-module-installname-map-file %S/Inputs/install-name-map-toasterkit.json
6+
// RUN: %FileCheck %s < %t/linker_directives.tbd
7+
// RUN: %target-swift-frontend -typecheck %S/Inputs/linker-directive.swift -emit-tbd -emit-tbd-path %t/linker_directives.tbd -previous-module-installname-map-file %S/Inputs/install-name-map-toasterkit.json
8+
// RUN: %FileCheck %s < %t/linker_directives.tbd
9+
10+
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit5toastyyF$
11+
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleV4moveyyF$
12+
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVMa$
13+
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVMn$
14+
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleVN$

0 commit comments

Comments
 (0)