@@ -277,23 +277,39 @@ getLinkerPlatformName(OriginallyDefinedInAttr::ActiveVersion Ver) {
277
277
return getLinkerPlatformName ((uint8_t )getLinkerPlatformId (Ver));
278
278
}
279
279
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
+
280
291
void TBDGenVisitor::addLinkerDirectiveSymbolsLdPrevious (StringRef name,
281
292
llvm::MachO::SymbolKind kind) {
282
293
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
283
294
return ;
284
- if (!TopLevelDecl )
295
+ if (DeclStack. empty () )
285
296
return ;
297
+ auto TopLevelDecl = DeclStack.front ();
286
298
auto MovedVers = getAllMovedPlatformVersions (TopLevelDecl);
287
299
if (MovedVers.empty ())
288
300
return ;
289
301
assert (!MovedVers.empty ());
290
302
assert (previousInstallNameMap);
291
303
auto &Ctx = TopLevelDecl->getASTContext ();
292
304
for (auto &Ver: MovedVers) {
293
- auto IntroVer = TopLevelDecl-> getIntroducedOSVersion ( Ver.Platform );
305
+ auto IntroVer = getInnermostIntroVersion (DeclStack, Ver.Platform );
294
306
assert (IntroVer && " cannot find OS intro version" );
295
307
if (!IntroVer.hasValue ())
296
308
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 ;
297
313
auto PlatformNumber = getLinkerPlatformId (Ver);
298
314
auto It = previousInstallNameMap->find (Ver.ModuleName );
299
315
if (It == previousInstallNameMap->end ()) {
@@ -330,8 +346,9 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdHide(StringRef name,
330
346
llvm::MachO::SymbolKind kind) {
331
347
if (kind != llvm::MachO::SymbolKind::GlobalSymbol)
332
348
return ;
333
- if (!TopLevelDecl )
349
+ if (DeclStack. empty () )
334
350
return ;
351
+ auto TopLevelDecl = DeclStack.front ();
335
352
auto MovedVers = getAllMovedPlatformVersions (TopLevelDecl);
336
353
if (MovedVers.empty ())
337
354
return ;
@@ -346,11 +363,12 @@ void TBDGenVisitor::addLinkerDirectiveSymbolsLdHide(StringRef name,
346
363
unsigned Minor[2 ];
347
364
Major[1 ] = MovedVer.getMajor ();
348
365
Minor[1 ] = MovedVer.getMinor ().hasValue () ? *MovedVer.getMinor (): 0 ;
349
- auto IntroVer = TopLevelDecl-> getIntroducedOSVersion ( Platform);
366
+ auto IntroVer = getInnermostIntroVersion (DeclStack, Platform);
350
367
assert (IntroVer && " cannot find the start point of availability" );
351
368
if (!IntroVer.hasValue ())
352
369
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.
354
372
if (*IntroVer >= MovedVer)
355
373
return ;
356
374
Major[0 ] = IntroVer->getMajor ();
@@ -911,6 +929,12 @@ void TBDGenVisitor::addFirstFileSymbols() {
911
929
}
912
930
}
913
931
932
+ void TBDGenVisitor::visit (Decl *D) {
933
+ DeclStack.push_back (D);
934
+ SWIFT_DEFER { DeclStack.pop_back (); };
935
+ ASTVisitor::visit (D);
936
+ }
937
+
914
938
// / The kind of version being parsed, used for diagnostics.
915
939
// / Note: Must match the order in DiagnosticsFrontend.def
916
940
enum DylibVersionKind_t: unsigned {
@@ -1018,8 +1042,6 @@ GenerateTBDRequest::evaluate(Evaluator &evaluator,
1018
1042
for (auto d : decls) {
1019
1043
if (opts.LinkerDirectivesOnly && !hasLinkerDirective (d))
1020
1044
continue ;
1021
- visitor.TopLevelDecl = d;
1022
- SWIFT_DEFER { visitor.TopLevelDecl = nullptr ; };
1023
1045
visitor.visit (d);
1024
1046
}
1025
1047
};
0 commit comments