Skip to content

Commit 2a8c973

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents 8e87833 + f1d1df3 commit 2a8c973

File tree

11 files changed

+397
-109
lines changed

11 files changed

+397
-109
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@ ERROR(cannot_return_value_from_void_func,none,
586586

587587
ERROR(sema_no_import,Fatal,
588588
"no such module '%0'", (StringRef))
589-
ERROR(sema_no_import_arch,Fatal,
590-
"could not find module '%0' for architecture '%1'; "
589+
ERROR(sema_no_import_target,Fatal,
590+
"could not find module '%0' for target '%1'; "
591591
"found: %2", (StringRef, StringRef, StringRef))
592592
ERROR(sema_no_import_repl,none,
593593
"no such module '%0'", (StringRef))

include/swift/Basic/Platform.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ namespace swift {
7474
///
7575
/// This is a stop-gap until full Triple support (ala Clang) exists within swiftc.
7676
StringRef getMajorArchitectureName(const llvm::Triple &triple);
77+
78+
/// Computes the normalized target triple used as the most preferred name for
79+
/// module loading.
80+
///
81+
/// For platforms with fat binaries, this canonicalizes architecture,
82+
/// vendor, and OS names, strips OS versions, and makes inferred environments
83+
/// explicit. For other platforms, it returns the unmodified triple.
84+
///
85+
/// The input triple should already be "normalized" in the sense that
86+
/// llvm::Triple::normalize() would not affect it.
87+
llvm::Triple getTargetSpecificModuleTriple(const llvm::Triple &triple);
7788
} // end namespace swift
7889

7990
#endif // SWIFT_BASIC_PLATFORM_H

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ class SerializedModuleLoaderBase : public ModuleLoader {
6868
/// to list the architectures that \e are present.
6969
///
7070
/// \returns true if an error diagnostic was emitted
71-
virtual bool maybeDiagnoseArchitectureMismatch(SourceLoc sourceLocation,
72-
StringRef moduleName,
73-
StringRef archName,
74-
StringRef directoryPath) {
71+
virtual bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
72+
StringRef moduleName,
73+
StringRef archName,
74+
StringRef directoryPath) {
7575
return false;
7676
}
7777

@@ -139,10 +139,10 @@ class SerializedModuleLoader : public SerializedModuleLoaderBase {
139139
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
140140
std::unique_ptr<llvm::MemoryBuffer> *ModuleDocBuffer) override;
141141

142-
bool maybeDiagnoseArchitectureMismatch(SourceLoc sourceLocation,
143-
StringRef moduleName,
144-
StringRef archName,
145-
StringRef directoryPath) override;
142+
bool maybeDiagnoseTargetMismatch(SourceLoc sourceLocation,
143+
StringRef moduleName,
144+
StringRef archName,
145+
StringRef directoryPath) override;
146146

147147
public:
148148
virtual ~SerializedModuleLoader();

lib/Basic/Platform.cpp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/Basic/Platform.h"
14+
#include "llvm/ADT/StringExtras.h"
15+
#include "llvm/ADT/StringSwitch.h"
1416
#include "llvm/ADT/Triple.h"
1517

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

0 commit comments

Comments
 (0)