Skip to content

Commit 63d6e7f

Browse files
authored
Merge pull request swiftlang#30424 from nkcsgexi/available-context
TBDGen: don't emit $ld$previous$ symbols for added members to a moved decl
2 parents 9dafc3b + 251edf3 commit 63d6e7f

File tree

4 files changed

+40
-9
lines changed

4 files changed

+40
-9
lines changed

lib/TBDGen/TBDGen.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,23 +277,39 @@ getLinkerPlatformName(OriginallyDefinedInAttr::ActiveVersion Ver) {
277277
return getLinkerPlatformName((uint8_t)getLinkerPlatformId(Ver));
278278
}
279279

280+
/// Find the most relevant introducing version of the decl stack we have visted
281+
/// so far.
282+
static Optional<llvm::VersionTuple>
283+
getInnermostIntroVersion(ArrayRef<Decl*> DeclStack, PlatformKind Platform) {
284+
for (auto It = DeclStack.rbegin(); It != DeclStack.rend(); ++ It) {
285+
if (auto Result = (*It)->getIntroducedOSVersion(Platform))
286+
return Result;
287+
}
288+
return None;
289+
}
290+
280291
void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious(StringRef name,
281292
llvm::MachO::SymbolKind kind) {
282293
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
283294
return;
284-
if (!TopLevelDecl)
295+
if(DeclStack.empty())
285296
return;
297+
auto TopLevelDecl = DeclStack.front();
286298
auto MovedVers = getAllMovedPlatformVersions(TopLevelDecl);
287299
if (MovedVers.empty())
288300
return;
289301
assert(!MovedVers.empty());
290302
assert(previousInstallNameMap);
291303
auto &Ctx = TopLevelDecl->getASTContext();
292304
for (auto &Ver: MovedVers) {
293-
auto IntroVer = TopLevelDecl->getIntroducedOSVersion(Ver.Platform);
305+
auto IntroVer = getInnermostIntroVersion(DeclStack, Ver.Platform);
294306
assert(IntroVer && "cannot find OS intro version");
295307
if (!IntroVer.hasValue())
296308
continue;
309+
// This decl is available after the top-level symbol has been moved here,
310+
// so we don't need the linker directives.
311+
if (*IntroVer >= Ver.Version)
312+
continue;
297313
auto PlatformNumber = getLinkerPlatformId(Ver);
298314
auto It = previousInstallNameMap->find(Ver.ModuleName);
299315
if (It == previousInstallNameMap->end()) {
@@ -330,8 +346,9 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdHide(StringRef name,
330346
llvm::MachO::SymbolKind kind) {
331347
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
332348
return;
333-
if (!TopLevelDecl)
349+
if (DeclStack.empty())
334350
return;
351+
auto TopLevelDecl = DeclStack.front();
335352
auto MovedVers = getAllMovedPlatformVersions(TopLevelDecl);
336353
if (MovedVers.empty())
337354
return;
@@ -346,11 +363,12 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdHide(StringRef name,
346363
unsigned Minor[2];
347364
Major[1] = MovedVer.getMajor();
348365
Minor[1] = MovedVer.getMinor().hasValue() ? *MovedVer.getMinor(): 0;
349-
auto IntroVer = TopLevelDecl->getIntroducedOSVersion(Platform);
366+
auto IntroVer = getInnermostIntroVersion(DeclStack, Platform);
350367
assert(IntroVer && "cannot find the start point of availability");
351368
if (!IntroVer.hasValue())
352369
return;
353-
assert(*IntroVer < MovedVer);
370+
// This decl is available after the top-level symbol has been moved here,
371+
// so we don't need the linker directives.
354372
if (*IntroVer >= MovedVer)
355373
return;
356374
Major[0] = IntroVer->getMajor();
@@ -911,6 +929,12 @@ void TBDGenVisitor::addFirstFileSymbols() {
911929
}
912930
}
913931

932+
void TBDGenVisitor::visit(Decl *D) {
933+
DeclStack.push_back(D);
934+
SWIFT_DEFER { DeclStack.pop_back(); };
935+
ASTVisitor::visit(D);
936+
}
937+
914938
/// The kind of version being parsed, used for diagnostics.
915939
/// Note: Must match the order in DiagnosticsFrontend.def
916940
enum DylibVersionKind_t: unsigned {
@@ -1018,8 +1042,6 @@ GenerateTBDRequest::evaluate(Evaluator &evaluator,
10181042
for (auto d : decls) {
10191043
if (opts.LinkerDirectivesOnly && !hasLinkerDirective(d))
10201044
continue;
1021-
visitor.TopLevelDecl = d;
1022-
SWIFT_DEFER { visitor.TopLevelDecl = nullptr; };
10231045
visitor.visit(d);
10241046
}
10251047
};

lib/TBDGen/TBDGenVisitor.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
6969
const UniversalLinkageInfo &UniversalLinkInfo;
7070
ModuleDecl *SwiftModule;
7171
const TBDGenOptions &Opts;
72-
Decl* TopLevelDecl = nullptr;
7372

7473
private:
74+
std::vector<Decl*> DeclStack;
7575
std::unique_ptr<std::map<std::string, InstallNameStore>>
7676
previousInstallNameMap;
7777
std::unique_ptr<std::map<std::string, InstallNameStore>>
@@ -108,7 +108,7 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
108108
DataLayout(dataLayout), UniversalLinkInfo(universalLinkInfo),
109109
SwiftModule(swiftModule), Opts(opts),
110110
previousInstallNameMap(parsePreviousModuleInstallNameMap()) {}
111-
111+
~TBDGenVisitor() { assert(DeclStack.empty()); }
112112
void addMainIfNecessary(FileUnit *file) {
113113
// HACK: 'main' is a special symbol that's always emitted in SILGen if
114114
// the file has an entry point. Since it doesn't show up in the
@@ -152,6 +152,8 @@ class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
152152
void visitEnumElementDecl(EnumElementDecl *EED);
153153

154154
void visitDecl(Decl *D) {}
155+
156+
void visit(Decl *D);
155157
};
156158
} // end namespace tbdgen
157159
} // end namespace swift

test/TBD/Inputs/linker-directive.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ public func toast() {}
66
@_originallyDefinedIn(module: "ToasterKit", macOS 10.15, iOS 13)
77
public struct Vehicle {
88
public func move() {}
9+
@available(macOS 10.15, iOS 13, *)
10+
public func originallyDefinedInCurrentModule() {}
911
}

test/TBD/linker-directives-ld-previous-macos.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44

55
// 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
66
// RUN: %FileCheck %s < %t/linker_directives.tbd
7+
// RUN: %FileCheck -check-prefix=CHECK-NO-NEW-SYMBOL %s < %t/linker_directives.tbd
78
// 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
89
// RUN: %FileCheck %s < %t/linker_directives.tbd
10+
// RUN: %FileCheck -check-prefix=CHECK-NO-NEW-SYMBOL %s < %t/linker_directives.tbd
911

1012
// RUN: %target-swift-frontend -target-variant x86_64-apple-ios13.0-macabi -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
1113
// RUN: %FileCheck -check-prefix=CHECK-ZIPPERED %s < %t/linker_directives.tbd
14+
// RUN: %FileCheck -check-prefix=CHECK-NO-NEW-SYMBOL %s < %t/linker_directives.tbd
1215

1316
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit5toastyyF$
1417
// CHECK: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit7VehicleV4moveyyF$
@@ -18,3 +21,5 @@
1821

1922
// CHECK-ZIPPERED: $ld$previous$/System/Previous/iOS/ToasterKit.dylib$$2$10.2$13.0$_$s10ToasterKit5toastyyF$
2023
// CHECK-ZIPPERED: $ld$previous$/System/Previous/macOS/ToasterKit.dylib$$1$10.8$10.15$_$s10ToasterKit5toastyyF$
24+
25+
// CHECK-NO-NEW-SYMBOL-NOT: $_$s10ToasterKit7VehicleV32originallyDefinedInCurrentModuleyyF

0 commit comments

Comments
 (0)