[Serialization] Use full target architectures for swiftmodule files (#21053)

Previously these used the same "major architecture" names that the
`#if os(...)` query accepts, but that can be a problem when building
for, say, both armv7 and armv7s, even if the content is "the same".

For a transition period where external build tools are involved, the
compiler will look for "arm.swiftmodule" if it fails to find
"armv7.swiftmodule" or any other 32-bit ARM architecture. No other
Apple platform architectures are affected, and AFAIK no one's using
the architecture-based layout on Linux or any other platforms.

rdar://problem/45174692
This commit is contained in:
Jordan Rose
2018-12-06 13:31:02 -08:00
committed by GitHub
parent 9596624981
commit 06f3c11377
4 changed files with 87 additions and 33 deletions

View File

@@ -142,6 +142,23 @@ bool SerializedModuleLoader::maybeDiagnoseArchitectureMismatch(
return true;
}
static std::pair<llvm::SmallString<16>, llvm::SmallString<16>>
getArchSpecificModuleFileNames(StringRef archName) {
llvm::SmallString<16> archFile, archDocFile;
if (!archName.empty()) {
archFile += archName;
archFile += '.';
archFile += file_types::getExtension(file_types::TY_SwiftModuleFile);
archDocFile += archName;
archDocFile += '.';
archDocFile += file_types::getExtension(file_types::TY_SwiftModuleDocFile);
}
return {archFile, archDocFile};
}
bool
SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
std::unique_ptr<llvm::MemoryBuffer> *moduleBuffer,
@@ -157,19 +174,19 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
moduleDocFilename +=
file_types::getExtension(file_types::TY_SwiftModuleDocFile);
// FIXME: Which name should we be using here? Do we care about CPU subtypes?
// FIXME: At the very least, don't hardcode "arch".
llvm::SmallString<16> archName{
Ctx.LangOpts.getPlatformConditionValue(PlatformConditionKind::Arch)};
llvm::SmallString<16> archFile{archName};
llvm::SmallString<16> archDocFile{archName};
if (!archFile.empty()) {
archFile += '.';
archFile += file_types::getExtension(file_types::TY_SwiftModuleFile);
StringRef archName = Ctx.LangOpts.Target.getArchName();
auto archFileNames = getArchSpecificModuleFileNames(archName);
archDocFile += '.';
archDocFile += file_types::getExtension(file_types::TY_SwiftModuleDocFile);
}
// FIXME: We used to use "major architecture" names for these files---the
// names checked in "#if arch(...)". Fall back to that name in the one case
// where it's different from what Swift 4.2 supported: 32-bit ARM platforms.
// We should be able to drop this once there's an Xcode that supports the
// new names.
StringRef alternateArchName;
if (Ctx.LangOpts.Target.getArch() == llvm::Triple::ArchType::arm)
alternateArchName = "arm";
auto alternateArchFileNames =
getArchSpecificModuleFileNames(alternateArchName);
auto &fs = *Ctx.SourceMgr.getFileSystem();
isFramework = false;
@@ -188,10 +205,19 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
if (statResult && statResult->isDirectory()) {
// A .swiftmodule directory contains architecture-specific files.
result = openModuleFiles(currPath,
archFile.str(), archDocFile.str(),
archFileNames.first, archFileNames.second,
moduleBuffer, moduleDocBuffer,
scratch);
if (result == std::errc::no_such_file_or_directory &&
!alternateArchName.empty()) {
result = openModuleFiles(currPath,
alternateArchFileNames.first,
alternateArchFileNames.second,
moduleBuffer, moduleDocBuffer,
scratch);
}
if (result == std::errc::no_such_file_or_directory) {
if (maybeDiagnoseArchitectureMismatch(moduleID.second, moduleName,
archName, currPath)) {
@@ -228,9 +254,18 @@ SerializedModuleLoaderBase::findModule(AccessPathElem moduleID,
// Frameworks always use architecture-specific files within a .swiftmodule
// directory.
llvm::sys::path::append(currPath, "Modules", moduleFilename.str());
auto err = openModuleFiles(currPath, archFile.str(), archDocFile.str(),
auto err = openModuleFiles(currPath,
archFileNames.first, archFileNames.second,
moduleBuffer, moduleDocBuffer, scratch);
if (err == std::errc::no_such_file_or_directory &&
!alternateArchName.empty()) {
err = openModuleFiles(currPath,
alternateArchFileNames.first,
alternateArchFileNames.second,
moduleBuffer, moduleDocBuffer, scratch);
}
if (err == std::errc::no_such_file_or_directory) {
if (maybeDiagnoseArchitectureMismatch(moduleID.second, moduleName,
archName, currPath)) {