Check for mismatched arch and OS when linking MachO files.

This patch makes use of the handleLoadedFile hook added in r257814.

That method is used to check the arch and the OS of the files we are linking
against the arch and OS on the context.

The first test to use this ensures that we do not try to combine i386 Mac OS code
with i386 simulator code.

llvm-svn: 257837
diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
index e5bc077..c129e9e 100644
--- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
@@ -35,6 +35,7 @@
 #endif
 
 using lld::mach_o::ArchHandler;
+using lld::mach_o::MachOFile;
 using lld::mach_o::MachODylibFile;
 using namespace llvm::MachO;
 
@@ -991,6 +992,29 @@
 }
 
 std::error_code MachOLinkingContext::handleLoadedFile(File &file) {
+  auto *machoFile = dyn_cast<MachOFile>(&file);
+  if (!machoFile)
+    return std::error_code();
+
+  // Check that the arch of the context matches that of the file.
+  // Also set the arch of the context if it didn't have one.
+  if (_arch == arch_unknown) {
+    _arch = machoFile->arch();
+  } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
+    // Archs are different.
+    return make_dynamic_error_code(file.path() +
+                  Twine(" cannot be linked due to incompatible architecture"));
+  }
+
+  // Check that the OS of the context matches that of the file.
+  // Also set the OS of the context if it didn't have one.
+  if (_os == OS::unknown) {
+    _os = machoFile->OS();
+  } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) {
+    // OSes are different.
+    return make_dynamic_error_code(file.path() +
+              Twine(" cannot be linked due to incompatible operating systems"));
+  }
   return std::error_code();
 }