[swiftinterface] Improve target overwrite for the swiftinterface

In certain cases (e.g. using arm64e interface to build arm64 target),
the target needs to be updated when building swiftinterface. Push the
target overwrite as early as possible to swiftinterface parsing by
providing a preferred target to relevant functions. In such cases, the
wrong target is never observed by other functions to avoid errors like
the sub-invocation was partially setup for the wrong target.
This commit is contained in:
Steven Wu
2024-02-15 13:26:04 -08:00
parent cdeef58e0f
commit 9f736811f0
4 changed files with 37 additions and 66 deletions

View File

@@ -1265,10 +1265,10 @@ void swift::serialization::diagnoseSerializedASTLoadFailureTransitive(
}
}
bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
StringRef buffer,
llvm::StringSaver &ArgSaver,
SmallVectorImpl<const char *> &SubArgs) {
bool swift::extractCompilerFlagsFromInterface(
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
SmallVectorImpl<const char *> &SubArgs,
std::optional<llvm::Triple> PreferredTarget) {
SmallVector<StringRef, 1> FlagMatches;
auto FlagRe = llvm::Regex("^// swift-module-flags:(.*)$", llvm::Regex::Newline);
if (!FlagRe.match(buffer, &FlagMatches))
@@ -1276,26 +1276,23 @@ bool swift::extractCompilerFlagsFromInterface(StringRef interfacePath,
assert(FlagMatches.size() == 2);
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
auto intFileName = llvm::sys::path::filename(interfacePath);
// Sanitize arch if the file name and the encoded flags disagree.
// It's a known issue that we are using arm64e interfaces contents for the arm64 target,
// meaning the encoded module flags are using -target arm64e-x-x. Fortunately,
// we can tell the target arch from the interface file name, so we could sanitize
// the target to use by inferring target from the file name.
StringRef arm64 = "arm64";
StringRef arm64e = "arm64e";
if (intFileName.contains(arm64) && !intFileName.contains(arm64e)) {
for (unsigned I = 1; I < SubArgs.size(); ++I) {
if (strcmp(SubArgs[I - 1], "-target") != 0) {
continue;
}
StringRef triple(SubArgs[I]);
if (triple.startswith(arm64e)) {
SubArgs[I] = ArgSaver.save((llvm::Twine(arm64) +
triple.substr(arm64e.size())).str()).data();
}
// If the target triple parsed from the Swift interface file differs
// only in subarchitecture from the compatible target triple, then
// we have loaded a Swift interface from a different-but-compatible
// architecture slice. Use the compatible subarchitecture.
for (unsigned I = 1; I < SubArgs.size(); ++I) {
if (strcmp(SubArgs[I - 1], "-target") != 0) {
continue;
}
llvm::Triple target(SubArgs[I]);
if (PreferredTarget &&
target.getSubArch() != PreferredTarget->getSubArch() &&
target.getArch() == PreferredTarget->getArch() &&
target.getVendor() == PreferredTarget->getVendor() &&
target.getOS() == PreferredTarget->getOS() &&
target.getEnvironment() == PreferredTarget->getEnvironment())
target.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch());
SubArgs[I] = ArgSaver.save(target.str()).data();
}
SmallVector<StringRef, 1> IgnFlagMatches;