Merge pull request #21891 from apple/revert-21436-revert-5.0-right-on-target

[5.0] Re-apply "[Serialization] Use full target architectures for swiftmodule files"
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index cfc2543..c0d3579 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -128,6 +128,23 @@
                      archName, foundArchs);
 }
 
+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,
@@ -143,19 +160,19 @@
   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);
 
   llvm::SmallString<128> scratch;
   llvm::SmallString<128> currPath;
@@ -169,10 +186,19 @@
       currPath = path;
       llvm::sys::path::append(currPath, moduleFilename.str());
       err = openModuleFiles(currPath,
-                            archFile.str(), archDocFile.str(),
+                            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) {
         addDiagnosticInfoForArchitectureMismatch(
             Ctx, moduleID.second, moduleName, archName, currPath);
@@ -197,9 +223,18 @@
       }
 
       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) {
         addDiagnosticInfoForArchitectureMismatch(
             Ctx, moduleID.second, moduleName, archName, currPath);
diff --git a/test/Serialization/load-arch-fallback-framework.swift b/test/Serialization/load-arch-fallback-framework.swift
new file mode 100644
index 0000000..c0f2dc4
--- /dev/null
+++ b/test/Serialization/load-arch-fallback-framework.swift
@@ -0,0 +1,18 @@
+// Test the fallback for 32-bit ARM platforms.
+
+// RUN: %empty-directory(%t)
+// RUN: mkdir -p %t/empty.framework/Modules/empty.swiftmodule
+// RUN: %target-swift-frontend -emit-module -o %t/empty.framework/Modules/empty.swiftmodule/arm.swiftmodule %S/../Inputs/empty.swift -module-name empty
+// RUN: %target-swift-frontend -typecheck %s -F %t
+
+// RUN: mv %t/empty.framework/Modules/empty.swiftmodule/arm.swiftmodule %t/empty.framework/Modules/empty.swiftmodule/%target-swiftmodule-name
+// RUN: touch %t/empty.framework/Modules/empty.swiftmodule/arm.swiftmodule
+// RUN: %target-swift-frontend -typecheck %s -F %t
+
+// RUN: rm %t/empty.framework/Modules/empty.swiftmodule/%target-swiftmodule-name
+// RUN: not %target-swift-frontend -typecheck %s -F %t 2>&1 | %FileCheck %s
+
+// REQUIRES: CPU=armv7 || CPU=armv7k || CPU=armv7s
+
+import empty
+// CHECK: :[[@LINE-1]]:8: error: malformed module file: {{.*}}arm.swiftmodule
diff --git a/test/Serialization/load-arch-fallback.swift b/test/Serialization/load-arch-fallback.swift
new file mode 100644
index 0000000..a8f978e
--- /dev/null
+++ b/test/Serialization/load-arch-fallback.swift
@@ -0,0 +1,18 @@
+// Test the fallback for 32-bit ARM platforms.
+
+// RUN: %empty-directory(%t)
+// RUN: mkdir %t/empty.swiftmodule
+// RUN: %target-swift-frontend -emit-module -o %t/empty.swiftmodule/arm.swiftmodule %S/../Inputs/empty.swift -module-name empty
+// RUN: %target-swift-frontend -typecheck %s -I %t
+
+// RUN: mv %t/empty.swiftmodule/arm.swiftmodule %t/empty.swiftmodule/%target-swiftmodule-name
+// RUN: touch %t/empty.swiftmodule/arm.swiftmodule
+// RUN: %target-swift-frontend -typecheck %s -I %t
+
+// RUN: rm %t/empty.swiftmodule/%target-swiftmodule-name
+// RUN: not %target-swift-frontend -typecheck %s -I %t 2>&1 | %FileCheck %s
+
+// REQUIRES: CPU=armv7 || CPU=armv7k || CPU=armv7s
+
+import empty
+// CHECK: :[[@LINE-1]]:8: error: malformed module file: {{.*}}arm.swiftmodule
diff --git a/test/lit.cfg b/test/lit.cfg
index 0fa7b66..3718069 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -569,8 +569,6 @@
 if 'swift_interpreter' in config.available_features:
     config.available_features.add('swift-remoteast-test')
 
-config.target_swiftmodule_name = "unknown.swiftmodule"
-config.target_swiftdoc_name = "unknown.swiftdoc"
 config.target_runtime = "unknown"
 
 swift_reflection_test_name = 'swift-reflection-test' + config.variant_suffix
@@ -609,8 +607,6 @@
 
 if run_vendor == 'apple':
     config.available_features.add('objc_interop')
-    config.target_swiftmodule_name = run_cpu + ".swiftmodule"
-    config.target_swiftdoc_name = run_cpu + ".swiftdoc"
     config.target_object_format = "macho"
     config.target_dylib_extension = "dylib"
     config.target_codesign = "codesign -f -s -"
@@ -646,15 +642,6 @@
            lit_config.note('Testing watchOS ' + config.variant_triple)
            xcrun_sdk_name = "watchos"
 
-       if run_cpu == "armv7" or run_cpu == "armv7s" or run_cpu == "armv7k":
-           config.target_swiftmodule_name = "arm.swiftmodule"
-           config.target_swiftdoc_name = "arm.swiftdoc"
-       elif run_cpu == "arm64":
-           config.target_swiftmodule_name = "arm64.swiftmodule"
-           config.target_swiftdoc_name = "arm64.swiftdoc"
-       else:
-           lit_config.fatal("Unknown CPU '%s'" % run_cpu)
-
        config.target_cc_options = (
            "-arch %s -m%s-version-min=%s %s" %
            (run_cpu, run_os, run_vers, clang_mcp_opt))
@@ -809,8 +796,6 @@
       config.target_object_format = "elf"
       config.target_dylib_extension = "so"
       config.target_sdk_name = "linux"
-    config.target_swiftmodule_name = run_cpu + ".swiftmodule"
-    config.target_swiftdoc_name = run_cpu + ".swiftdoc"
     config.target_runtime = "native"
     config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
     config.target_build_swift = (
@@ -1270,8 +1255,8 @@
 config.substitutions.insert(0, ('%platform-module-dir', platform_module_dir))
 config.substitutions.insert(0, ('%platform-sdk-overlay-dir', platform_sdk_overlay_dir))
 
-config.substitutions.append(('%target-swiftmodule-name', config.target_swiftmodule_name))
-config.substitutions.append(('%target-swiftdoc-name', config.target_swiftdoc_name))
+config.substitutions.append(('%target-swiftmodule-name', run_cpu + '.swiftmodule'))
+config.substitutions.append(('%target-swiftdoc-name', run_cpu + '.swiftdoc'))
 
 config.substitutions.append(('%target-object-format', config.target_object_format))
 config.substitutions.append(('%target-dylib-extension', config.target_dylib_extension))