@@ -72,20 +72,31 @@ void TBDGenVisitor::addSymbolInternal(StringRef name,
72
72
}
73
73
}
74
74
75
- static Optional<llvm::VersionTuple> getDeclMoveOSVersion (Decl *D) {
75
+ static std::vector<OriginallyDefinedInAttr::ActiveVersion>
76
+ getAllMovedPlatformVersions (Decl *D) {
77
+ std::vector<OriginallyDefinedInAttr::ActiveVersion> Results;
76
78
for (auto *attr: D->getAttrs ()) {
77
79
if (auto *ODA = dyn_cast<OriginallyDefinedInAttr>(attr)) {
78
- if (ODA->isActivePlatform (D->getASTContext ()))
79
- return ODA->MovedVersion ;
80
+ auto Active = ODA->isActivePlatform (D->getASTContext ());
81
+ if (Active.hasValue ()) {
82
+ Results.push_back (*Active);
83
+ }
80
84
}
81
85
}
82
- return None ;
86
+ return Results ;
83
87
}
84
88
85
- enum class LinkerPlatformId : uint8_t {
86
- #define LD_PLATFORM (Name, Id ) Name = Id,
87
- #include " ldPlatformKinds.def"
88
- };
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
+ }
89
100
90
101
static StringRef getLinkerPlatformName (uint8_t Id) {
91
102
switch (Id) {
@@ -103,29 +114,23 @@ static Optional<uint8_t> getLinkerPlatformId(StringRef Platform) {
103
114
.Default (None);
104
115
}
105
116
106
- struct InstallNameStore {
107
- // The default install name to use when no specific install name is specified.
108
- std::string InstallName;
109
- // The install name specific to the platform id. This takes precedence over
110
- // the default install name.
111
- std::map<uint8_t , std::string> PlatformInstallName;
112
- StringRef getInstallName (LinkerPlatformId Id) const {
113
- auto It = PlatformInstallName.find ((uint8_t )Id);
114
- if (It == PlatformInstallName.end ())
115
- return InstallName;
116
- else
117
- return It->second ;
118
- }
119
- void remark (ASTContext &Ctx, StringRef ModuleName) const {
120
- Ctx.Diags .diagnose (SourceLoc (), diag::default_previous_install_name,
121
- ModuleName, InstallName);
122
- for (auto Pair: PlatformInstallName) {
123
- Ctx.Diags .diagnose (SourceLoc (), diag::platform_previous_install_name,
124
- ModuleName, getLinkerPlatformName (Pair.first ),
125
- Pair.second );
126
- }
117
+ StringRef InstallNameStore::getInstallName (LinkerPlatformId Id) const {
118
+ auto It = PlatformInstallName.find ((uint8_t )Id);
119
+ if (It == PlatformInstallName.end ())
120
+ return InstallName;
121
+ else
122
+ return It->second ;
123
+ }
124
+
125
+ void InstallNameStore::remark (ASTContext &Ctx, StringRef ModuleName) const {
126
+ Ctx.Diags .diagnose (SourceLoc (), diag::default_previous_install_name,
127
+ ModuleName, InstallName);
128
+ for (auto Pair: PlatformInstallName) {
129
+ Ctx.Diags .diagnose (SourceLoc (), diag::platform_previous_install_name,
130
+ ModuleName, getLinkerPlatformName (Pair.first ),
131
+ Pair.second );
127
132
}
128
- };
133
+ }
129
134
130
135
static std::string getScalaNodeText (Node *N) {
131
136
SmallString<32 > Buffer;
@@ -195,37 +200,49 @@ parseEntry(ASTContext &Ctx,
195
200
return 0 ;
196
201
}
197
202
198
- static std::map<std::string, InstallNameStore>
199
- parsePreviousModuleInstallNameMap (ASTContext &Ctx, StringRef FileName) {
203
+ std::unique_ptr<std::map<std::string, InstallNameStore>>
204
+ TBDGenVisitor::parsePreviousModuleInstallNameMap () {
205
+ StringRef FileName = Opts.ModuleInstallNameMapPath ;
206
+ // Nothing to parse.
207
+ if (FileName.empty ())
208
+ return nullptr ;
200
209
namespace yaml = llvm::yaml;
201
- std::map<std::string, InstallNameStore> AllInstallNames;
210
+ ASTContext &Ctx = SwiftModule->getASTContext ();
211
+ std::unique_ptr<std::map<std::string, InstallNameStore>> pResult (
212
+ new std::map<std::string, InstallNameStore>());
213
+ auto &AllInstallNames = *pResult;
202
214
SWIFT_DEFER {
203
215
for (auto Pair: AllInstallNames) {
204
216
Pair.second .remark (Ctx, Pair.first );
205
217
}
206
218
};
219
+
207
220
// Load the input file.
208
221
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
209
- vfs::getFileOrSTDIN (*Ctx. SourceMgr . getFileSystem (), FileName);
222
+ llvm::MemoryBuffer::getFile ( FileName);
210
223
if (!FileBufOrErr) {
211
224
Ctx.Diags .diagnose (SourceLoc (), diag::previous_installname_map_missing,
212
225
FileName);
213
- return AllInstallNames ;
226
+ return nullptr ;
214
227
}
215
228
StringRef Buffer = FileBufOrErr->get ()->getBuffer ();
229
+
230
+ // Use a new source manager instead of the one from ASTContext because we
231
+ // don't want the Json file to be persistent.
232
+ SourceManager SM;
216
233
yaml::Stream Stream (llvm::MemoryBufferRef (Buffer, FileName),
217
- Ctx. SourceMgr .getLLVMSourceMgr ());
234
+ SM .getLLVMSourceMgr ());
218
235
for (auto DI = Stream.begin (); DI != Stream.end (); ++ DI) {
219
236
assert (DI != Stream.end () && " Failed to read a document" );
220
237
yaml::Node *N = DI->getRoot ();
221
238
assert (N && " Failed to find a root" );
222
239
if (parseEntry (Ctx, N, AllInstallNames)) {
223
240
Ctx.Diags .diagnose (SourceLoc (), diag::previous_installname_map_corrupted,
224
241
FileName);
225
- return AllInstallNames ;
242
+ return nullptr ;
226
243
}
227
244
}
228
- return AllInstallNames ;
245
+ return pResult ;
229
246
}
230
247
231
248
void TBDGenVisitor::addLinkerDirectiveSymbols (StringRef name,
@@ -234,26 +251,29 @@ void TBDGenVisitor::addLinkerDirectiveSymbols(StringRef name,
234
251
return ;
235
252
if (!TopLevelDecl)
236
253
return ;
237
- auto MovedVer = getDeclMoveOSVersion (TopLevelDecl);
238
- if (!MovedVer. hasValue ())
254
+ auto MovedVers = getAllMovedPlatformVersions (TopLevelDecl);
255
+ if (MovedVers. empty ())
239
256
return ;
240
- assert (MovedVer.hasValue ());
257
+ assert (!MovedVers.empty ());
258
+
259
+ // Using $ld$add and $ld$hide cannot encode platform name in the version number,
260
+ // so we can only handle one version.
261
+ // FIXME: use $ld$previous instead
262
+ auto MovedVer = MovedVers.front ().Version ;
263
+ auto Platform = MovedVers.front ().Platform ;
241
264
unsigned Major[2 ];
242
265
unsigned Minor[2 ];
243
- Major[1 ] = MovedVer->getMajor ();
244
- Minor[1 ] = MovedVer->getMinor ().hasValue () ? *MovedVer->getMinor (): 0 ;
245
- auto AvailRange = AvailabilityInference::availableRange (TopLevelDecl,
246
- TopLevelDecl->getASTContext ()).getOSVersion ();
247
- assert (AvailRange.hasLowerEndpoint () &&
248
- " cannot find the start point of availability" );
249
- if (!AvailRange.hasLowerEndpoint ())
266
+ Major[1 ] = MovedVer.getMajor ();
267
+ Minor[1 ] = MovedVer.getMinor ().hasValue () ? *MovedVer.getMinor (): 0 ;
268
+ auto IntroVer = getIntroducedOSVersion (TopLevelDecl, Platform);
269
+ assert (IntroVer && " cannot find the start point of availability" );
270
+ if (!IntroVer.hasValue ())
250
271
return ;
251
- assert (AvailRange. getLowerEndpoint () < * MovedVer);
252
- if (AvailRange. getLowerEndpoint () >= * MovedVer)
272
+ assert (*IntroVer < MovedVer);
273
+ if (*IntroVer >= MovedVer)
253
274
return ;
254
- Major[0 ] = AvailRange.getLowerEndpoint ().getMajor ();
255
- Minor[0 ] = AvailRange.getLowerEndpoint ().getMinor ().hasValue () ?
256
- AvailRange.getLowerEndpoint ().getMinor ().getValue () : 0 ;
275
+ Major[0 ] = IntroVer->getMajor ();
276
+ Minor[0 ] = IntroVer->getMinor ().hasValue () ? IntroVer->getMinor ().getValue () : 0 ;
257
277
for (auto CurMaj = Major[0 ]; CurMaj <= Major[1 ]; ++ CurMaj) {
258
278
unsigned MinRange[2 ] = {0 , 31 };
259
279
if (CurMaj == Major[0 ])
@@ -850,7 +870,7 @@ static bool isApplicationExtensionSafe(const LangOptions &LangOpts) {
850
870
}
851
871
852
872
static bool hasLinkerDirective (Decl *D) {
853
- return getDeclMoveOSVersion (D).hasValue ();
873
+ return ! getAllMovedPlatformVersions (D).empty ();
854
874
}
855
875
856
876
static void enumeratePublicSymbolsAndWrite (ModuleDecl *M, FileUnit *singleFile,
@@ -882,10 +902,6 @@ static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
882
902
file.setCompatibilityVersion (*packed);
883
903
}
884
904
885
- if (!opts.ModuleInstallNameMapPath .empty ()) {
886
- parsePreviousModuleInstallNameMap (ctx, opts.ModuleInstallNameMapPath );
887
- }
888
-
889
905
llvm::MachO::Target target (triple);
890
906
file.addTarget (target);
891
907
0 commit comments