mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
ModuleInterface: Canonicalize OS version numbers in loaded swiftinterfaces.
This commit is contained in:
@@ -1470,30 +1470,70 @@ static std::optional<StringRef> getFlagsFromInterfaceFile(StringRef &file,
|
||||
bool swift::extractCompilerFlagsFromInterface(
|
||||
StringRef interfacePath, StringRef buffer, llvm::StringSaver &ArgSaver,
|
||||
SmallVectorImpl<const char *> &SubArgs,
|
||||
std::optional<llvm::Triple> PreferredTarget) {
|
||||
std::optional<llvm::Triple> PreferredTarget, DiagnosticEngine *Diag) {
|
||||
auto FlagMatch = getFlagsFromInterfaceFile(buffer, SWIFT_MODULE_FLAGS_KEY);
|
||||
if (!FlagMatch)
|
||||
return true;
|
||||
llvm::cl::TokenizeGNUCommandLine(*FlagMatch, ArgSaver, SubArgs);
|
||||
|
||||
// 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.
|
||||
if (PreferredTarget) {
|
||||
for (unsigned I = 1; I < SubArgs.size(); ++I) {
|
||||
if (strcmp(SubArgs[I - 1], "-target") != 0 &&
|
||||
strcmp(SubArgs[I - 1], "-target-variant") != 0)
|
||||
continue;
|
||||
for (unsigned I = 1; I < SubArgs.size(); ++I) {
|
||||
if (strcmp(SubArgs[I - 1], "-target") != 0 &&
|
||||
strcmp(SubArgs[I - 1], "-target-variant") != 0)
|
||||
continue;
|
||||
|
||||
llvm::Triple triple(SubArgs[I]);
|
||||
if (triple.getArch() != PreferredTarget->getArch())
|
||||
continue;
|
||||
if (triple.getSubArch() == PreferredTarget->getSubArch())
|
||||
continue;
|
||||
llvm::Triple triple(SubArgs[I]);
|
||||
bool shouldModify = false;
|
||||
// If the target triple parsed from the swiftinterface 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.
|
||||
if (PreferredTarget && triple.getArch() == PreferredTarget->getArch() &&
|
||||
triple.getSubArch() != PreferredTarget->getSubArch()) {
|
||||
triple.setArch(PreferredTarget->getArch(), PreferredTarget->getSubArch());
|
||||
SubArgs[I] = ArgSaver.save(triple.str()).data();
|
||||
shouldModify = true;
|
||||
}
|
||||
|
||||
// Diagnose if the version in the target triple parsed from the
|
||||
// swiftinterface is invalid for the OS.
|
||||
const llvm::VersionTuple originalVer = triple.getOSVersion();
|
||||
bool isValidVersion =
|
||||
llvm::Triple::isValidVersionForOS(triple.getOS(), originalVer);
|
||||
if (!isValidVersion) {
|
||||
if (Diag) {
|
||||
Diag->diagnose(SourceLoc(),
|
||||
diag::target_os_version_from_textual_interface_invalid,
|
||||
triple.str(), interfacePath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Canonicalize the version in the target triple parsed from the
|
||||
// swiftinterface.
|
||||
llvm::VersionTuple newVer = llvm::Triple::getCanonicalVersionForOS(
|
||||
triple.getOS(), originalVer, isValidVersion);
|
||||
if (originalVer != newVer) {
|
||||
std::string originalOSName = triple.getOSName().str();
|
||||
std::string originalVerStr = originalVer.getAsString();
|
||||
std::string newVerStr = newVer.getAsString();
|
||||
const int OSNameWithoutVersionLength =
|
||||
originalOSName.size() - originalVerStr.size();
|
||||
if (!StringRef(originalOSName).ends_with(originalVerStr) ||
|
||||
(OSNameWithoutVersionLength <= 0)) {
|
||||
if (Diag) {
|
||||
Diag->diagnose(SourceLoc(),
|
||||
diag::map_os_version_from_textual_interface_failed,
|
||||
originalVerStr, newVerStr, interfacePath);
|
||||
}
|
||||
break;
|
||||
}
|
||||
llvm::SmallString<64> buffer(
|
||||
originalOSName.substr(0, OSNameWithoutVersionLength));
|
||||
buffer.append(newVerStr);
|
||||
triple.setOSName(buffer.str());
|
||||
shouldModify = true;
|
||||
}
|
||||
if (shouldModify)
|
||||
SubArgs[I] = ArgSaver.save(triple.str()).data();
|
||||
}
|
||||
|
||||
auto IgnFlagMatch =
|
||||
|
||||
Reference in New Issue
Block a user