11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " swift/Basic/Platform.h"
14
- #include " llvm/ADT/Triple.h"
15
- #include " llvm/ADT/StringSwitch.h"
16
14
#include " llvm/ADT/StringExtras.h"
15
+ #include " llvm/ADT/StringSwitch.h"
16
+ #include " llvm/ADT/Triple.h"
17
17
18
18
using namespace swift ;
19
19
@@ -191,61 +191,106 @@ StringRef swift::getMajorArchitectureName(const llvm::Triple &Triple) {
191
191
}
192
192
}
193
193
194
+ // The code below is responsible for normalizing target triples into the form
195
+ // used to name target-specific swiftmodule, swiftinterface, and swiftdoc files.
196
+ // If two triples have incompatible ABIs or can be distinguished by Swift #if
197
+ // declarations, they should normalize to different values.
198
+ //
199
+ // This code is only really used on platforms with toolchains supporting fat
200
+ // binaries (a single binary containing multiple architectures). On these
201
+ // platforms, this code should strip unnecessary details from target triple
202
+ // components and map synonyms to canonical values. Even values which don't need
203
+ // any special canonicalization should be documented here as comments.
204
+ //
205
+ // (Fallback behavior does not belong here; it should be implemented in code
206
+ // that calls this function, most importantly in SerializedModuleLoaderBase.)
207
+ //
208
+ // If you're trying to refer to this code to understand how Swift behaves and
209
+ // you're unfamiliar with LLVM internals, here's a cheat sheet for reading it:
210
+ //
211
+ // * llvm::Triple is the type for a target name. It's a bit of a misnomer,
212
+ // because it can contain three or four values: arch-vendor-os[-environment].
213
+ //
214
+ // * In .Cases and .Case, the last argument is the value the arguments before it
215
+ // map to. That is, `.Cases("bar", "baz", "foo")` will return "foo" if it sees
216
+ // "bar" or "baz".
217
+ //
218
+ // * llvm::Optional is similar to a Swift Optional: it either contains a value
219
+ // or represents the absence of one. `None` is equivalent to `nil`; leading
220
+ // `*` is equivalent to trailing `!`; conversion to `bool` is a not-`None`
221
+ // check.
222
+
194
223
static StringRef
195
224
getArchForAppleTargetSpecificModuleTriple (const llvm::Triple &triple) {
196
225
auto tripleArchName = triple.getArchName ();
197
226
198
227
return llvm::StringSwitch<StringRef>(tripleArchName)
199
228
.Cases (" arm64" , " aarch64" , " arm64" )
200
- .Case (" armv7s" , " armv7s" )
201
- .Case (" armv7k" , " armv7k" )
202
- .Case (" armv7" , " armv7" )
203
- .Case (" x86_64h" , " x86_64h" )
204
229
.Cases (" x86_64" , " amd64" , " x86_64" )
205
230
.Cases (" i386" , " i486" , " i586" , " i686" , " i786" , " i886" , " i986" ,
206
231
" i386" )
207
232
.Cases (" unknown" , " " , " unknown" )
233
+ // These values are also supported, but are handled by the default case below:
234
+ // .Case ("armv7s", "armv7s")
235
+ // .Case ("armv7k", "armv7k")
236
+ // .Case ("armv7", "armv7")
208
237
.Default (tripleArchName);
209
238
}
210
239
211
240
static StringRef
212
241
getVendorForAppleTargetSpecificModuleTriple (const llvm::Triple &triple) {
242
+ // We unconditionally normalize to "apple" because it's relatively common for
243
+ // build systems to omit the vendor name or use an incorrect one like
244
+ // "unknown". Most parts of the compiler ignore the vendor, so you might not
245
+ // notice such a mistake.
246
+ //
247
+ // Please don't depend on this behavior--specify 'apple' if you're building
248
+ // for an Apple platform.
249
+
250
+ assert (triple.isOSDarwin () &&
251
+ " shouldn't normalize non-Darwin triple to 'apple'" );
252
+
213
253
return " apple" ;
214
254
}
215
255
216
256
static StringRef
217
257
getOSForAppleTargetSpecificModuleTriple (const llvm::Triple &triple) {
218
258
auto tripleOSName = triple.getOSName ();
219
259
220
- // Truncate the OS name before the first digit.
260
+ // Truncate the OS name before the first digit. "Digit" here is ASCII '0'-'9'.
221
261
auto tripleOSNameNoVersion = tripleOSName.take_until (llvm::isDigit);
222
262
223
263
return llvm::StringSwitch<StringRef>(tripleOSNameNoVersion)
224
264
.Cases (" macos" , " macosx" , " darwin" , " macos" )
225
- .Case (" ios" , " ios" )
226
- .Case (" tvos" , " tvos" )
227
265
.Cases (" unknown" , " " , " unknown" )
266
+ // These values are also supported, but are handled by the default case below:
267
+ // .Case ("ios", "ios")
268
+ // .Case ("tvos", "tvos")
269
+ // .Case ("watchos", "watchos")
228
270
.Default (tripleOSNameNoVersion);
229
271
}
230
272
231
273
static Optional<StringRef>
232
274
getEnvironmentForAppleTargetSpecificModuleTriple (const llvm::Triple &triple) {
233
275
auto tripleEnvironment = triple.getEnvironmentName ();
234
276
235
- if (tripleEnvironment == " " ) {
236
- if ( swift::tripleIsAnySimulator (triple))
237
- return StringRef ( " simulator" );
238
- else
239
- return None;
240
- }
277
+ // If the environment is empty, infer a "simulator" environment based on the
278
+ // OS and architecture combination. This feature is deprecated and exists for
279
+ // backwards compatibility only; build systems should pass the "simulator"
280
+ // environment explicitly if they know they're building for a simulator.
281
+ if (tripleEnvironment == " " && swift::tripleIsAnySimulator (triple))
282
+ return StringRef ( " simulator " );
241
283
242
284
return llvm::StringSwitch<Optional<StringRef>>(tripleEnvironment)
243
- .Case (" simulator" , StringRef (" simulator" ))
244
- .Case (" unknown" , None)
285
+ .Cases (" unknown" , " " , None)
286
+ // These values are also supported, but are handled by the default case below:
287
+ // .Case ("simulator", StringRef("simulator"))
245
288
.Default (tripleEnvironment);
246
289
}
247
290
248
291
llvm::Triple swift::getTargetSpecificModuleTriple (const llvm::Triple &triple) {
292
+ // isOSDarwin() returns true for all Darwin-style OSes, including macOS, iOS,
293
+ // etc.
249
294
if (triple.isOSDarwin ()) {
250
295
StringRef newArch = getArchForAppleTargetSpecificModuleTriple (triple);
251
296
@@ -256,12 +301,15 @@ llvm::Triple swift::getTargetSpecificModuleTriple(const llvm::Triple &triple) {
256
301
Optional<StringRef> newEnvironment =
257
302
getEnvironmentForAppleTargetSpecificModuleTriple (triple);
258
303
259
- if (newEnvironment)
260
- return llvm::Triple (newArch, newVendor, newOS, *newEnvironment);
261
- else
304
+ if (!newEnvironment)
305
+ // Generate an arch-vendor-os triple.
262
306
return llvm::Triple (newArch, newVendor, newOS);
263
- } else {
264
- return triple;
307
+
308
+ // Generate an arch-vendor-os-environment triple.
309
+ return llvm::Triple (newArch, newVendor, newOS, *newEnvironment);
265
310
}
311
+
312
+ // Other platforms get no normalization.
313
+ return triple;
266
314
}
267
315
0 commit comments