[clang] 2542c1a - [clang][driver][darwin] Add driver support for Mac Catalyst

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 22 10:20:48 PDT 2021


Author: Alex Lorenz
Date: 2021-07-22T10:20:19-07:00
New Revision: 2542c1a5a1306398d73c3c0c5d71cacf7c690093

URL: https://github.com/llvm/llvm-project/commit/2542c1a5a1306398d73c3c0c5d71cacf7c690093
DIFF: https://github.com/llvm/llvm-project/commit/2542c1a5a1306398d73c3c0c5d71cacf7c690093.diff

LOG: [clang][driver][darwin] Add driver support for Mac Catalyst

This commit adds driver support for the Mac Catalyst target,
as supported by the Apple clang compile

Differential Revision: https://reviews.llvm.org/D105960

Added: 
    clang/test/Driver/Inputs/MacOSX10.15.versioned.sdk/SDKSettings.json
    clang/test/Driver/darwin-ld-platform-version-maccatalyst.c
    clang/test/Driver/darwin-mac-catalyst-32bit-not-supported.c
    clang/test/Driver/darwin-maccatalyst.c
    clang/test/Driver/darwin-objc-runtime-maccatalyst.m
    clang/test/Driver/darwin-sdk-version-maccatalyst.c

Modified: 
    clang/include/clang/Basic/DarwinSDKInfo.h
    clang/include/clang/Basic/DiagnosticDriverKinds.td
    clang/lib/Basic/DarwinSDKInfo.cpp
    clang/lib/Driver/ToolChains/Darwin.cpp
    clang/lib/Driver/ToolChains/Darwin.h
    clang/test/Driver/darwin-ld.c
    clang/test/Driver/darwin-objc-defaults.m
    clang/test/Driver/darwin-sanitizer-ld.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h
index f6892269bb609..918dc7c8becc6 100644
--- a/clang/include/clang/Basic/DarwinSDKInfo.h
+++ b/clang/include/clang/Basic/DarwinSDKInfo.h
@@ -50,6 +50,13 @@ class DarwinSDKInfo {
                        llvm::Triple::IOS, llvm::Triple::MacABI);
     }
 
+    /// Returns the os-environment mapping pair that's used to represent the
+    /// Mac Catalyst -> macOS version mapping.
+    static inline constexpr OSEnvPair macCatalystToMacOSPair() {
+      return OSEnvPair(llvm::Triple::IOS, llvm::Triple::MacABI,
+                       llvm::Triple::MacOSX, llvm::Triple::UnknownEnvironment);
+    }
+
   private:
     StorageType Value;
 

diff  --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index c7da9713b1e4e..fc3704303a956 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -231,6 +231,8 @@ def warn_invalid_ios_deployment_target : Warning<
   "invalid iOS deployment version '%0', iOS 10 is the maximum deployment "
   "target for 32-bit targets">, InGroup<InvalidIOSDeploymentTarget>,
   DefaultError;
+def err_invalid_macos_32bit_deployment_target : Error<
+  "32-bit targets are not supported when building for Mac Catalyst">;
 def err_drv_conflicting_deployment_targets : Error<
   "conflicting deployment targets, both '%0' and '%1' are present in environment">;
 def err_arc_unsupported_on_runtime : Error<

diff  --git a/clang/lib/Basic/DarwinSDKInfo.cpp b/clang/lib/Basic/DarwinSDKInfo.cpp
index fe3e8edbcd5cb..fe35f77782c92 100644
--- a/clang/lib/Basic/DarwinSDKInfo.cpp
+++ b/clang/lib/Basic/DarwinSDKInfo.cpp
@@ -92,6 +92,14 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(const llvm::json::Object *Obj) {
       VersionMappings[OSEnvPair::macOStoMacCatalystPair().Value] =
           std::move(VersionMap);
     }
+    if (const auto *Mapping = VM->getObject("iOSMac_macOS")) {
+      auto VersionMap = RelatedTargetVersionMapping::parseJSON(
+          *Mapping, *MaximumDeploymentVersion);
+      if (!VersionMap)
+        return None;
+      VersionMappings[OSEnvPair::macCatalystToMacOSPair().Value] =
+          std::move(VersionMap);
+    }
   }
 
   return DarwinSDKInfo(std::move(*Version),

diff  --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index fc1f10111941b..4de5e81d2c0c0 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -34,6 +34,10 @@ using namespace clang::driver::toolchains;
 using namespace clang;
 using namespace llvm::opt;
 
+static const VersionTuple minimumMacCatalystDeploymentTarget() {
+  return VersionTuple(13, 1);
+}
+
 llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
   // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
   // archs which Darwin doesn't use.
@@ -820,9 +824,9 @@ bool MachO::HasNativeLLVMSupport() const { return true; }
 
 ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
   // Default to use libc++ on OS X 10.9+ and iOS 7+.
-  if ((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
-       (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
-       isTargetWatchOSBased())
+  if ((isTargetMacOSBased() && !isMacosxVersionLT(10, 9)) ||
+      (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) ||
+      isTargetWatchOSBased())
     return ToolChain::CST_Libcxx;
 
   return ToolChain::CST_Libstdcxx;
@@ -846,7 +850,7 @@ bool Darwin::hasBlocksRuntime() const {
   else if (isTargetIOSBased())
     return !isIPhoneOSVersionLT(3, 2);
   else {
-    assert(isTargetMacOS() && "unexpected darwin target");
+    assert(isTargetMacOSBased() && "unexpected darwin target");
     return !isMacosxVersionLT(10, 6);
   }
 }
@@ -947,11 +951,11 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
     Str += "watchos";
   else if (isTargetTvOSBased())
     Str += "tvos";
-  else if (isTargetIOSBased())
+  else if (isTargetIOSBased() || isTargetMacCatalyst())
     Str += "ios";
   else
     Str += "macosx";
-  Str += getTargetVersion().getAsString();
+  Str += getTripleTargetVersion().getAsString();
   Triple.setOSName(Str);
 
   return Triple.getTriple();
@@ -1020,7 +1024,7 @@ static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) {
 void DarwinClang::AddLinkARCArgs(const ArgList &Args,
                                  ArgStringList &CmdArgs) const {
   // Avoid linking compatibility stubs on i386 mac.
-  if (isTargetMacOS() && getArch() == llvm::Triple::x86)
+  if (isTargetMacOSBased() && getArch() == llvm::Triple::x86)
     return;
   if (isTargetAppleSiliconMac())
     return;
@@ -1078,7 +1082,7 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
 
 unsigned DarwinClang::GetDefaultDwarfVersion() const {
   // Default to use DWARF 2 on OS X 10.10 / iOS 8 and lower.
-  if ((isTargetMacOS() && isMacosxVersionLT(10, 11)) ||
+  if ((isTargetMacOSBased() && isMacosxVersionLT(10, 11)) ||
       (isTargetIOSBased() && isIPhoneOSVersionLT(9)))
     return 2;
   return 4;
@@ -1139,6 +1143,8 @@ StringRef Darwin::getPlatformFamily() const {
     case DarwinPlatformKind::MacOS:
       return "MacOSX";
     case DarwinPlatformKind::IPhoneOS:
+      if (TargetEnvironment == MacCatalyst)
+        return "MacOSX";
       return "iPhone";
     case DarwinPlatformKind::TvOS:
       return "AppleTV";
@@ -1165,6 +1171,8 @@ StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {
   case DarwinPlatformKind::MacOS:
     return "osx";
   case DarwinPlatformKind::IPhoneOS:
+    if (TargetEnvironment == MacCatalyst)
+      return "osx";
     return TargetEnvironment == NativeEnvironment || IgnoreSim ? "ios"
                                                                : "iossim";
   case DarwinPlatformKind::TvOS:
@@ -1409,6 +1417,12 @@ struct DarwinPlatform {
 
   bool hasOSVersion() const { return HasOSVersion; }
 
+  VersionTuple getNativeTargetVersion() const {
+    assert(Environment == DarwinEnvironmentKind::MacCatalyst &&
+           "native target version is specified only for Mac Catalyst");
+    return NativeTargetVersion;
+  }
+
   /// Returns true if the target OS was explicitly specified.
   bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }
 
@@ -1455,21 +1469,40 @@ struct DarwinPlatform {
     llvm_unreachable("Unsupported Darwin Source Kind");
   }
 
-  static DarwinPlatform createFromTarget(const llvm::Triple &TT,
-                                         StringRef OSVersion, Arg *A) {
+  static DarwinPlatform
+  createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
+                   const Optional<DarwinSDKInfo> &SDKInfo) {
     DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
                           A);
+    unsigned Major, Minor, Micro;
+    TT.getOSVersion(Major, Minor, Micro);
+    if (Major == 0)
+      Result.HasOSVersion = false;
+
     switch (TT.getEnvironment()) {
     case llvm::Triple::Simulator:
       Result.Environment = DarwinEnvironmentKind::Simulator;
       break;
+    case llvm::Triple::MacABI: {
+      // The minimum native macOS target for MacCatalyst is macOS 10.15.
+      auto NativeTargetVersion = VersionTuple(10, 15);
+      if (Result.HasOSVersion && SDKInfo) {
+        if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
+                DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
+          if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
+                  VersionTuple(Major, Minor, Micro), NativeTargetVersion,
+                  None)) {
+            NativeTargetVersion = *MacOSVersion;
+          }
+        }
+      }
+      Result.Environment = DarwinEnvironmentKind::MacCatalyst;
+      Result.NativeTargetVersion = NativeTargetVersion;
+      break;
+    }
     default:
       break;
     }
-    unsigned Major, Minor, Micro;
-    TT.getOSVersion(Major, Minor, Micro);
-    if (Major == 0)
-      Result.HasOSVersion = false;
     return Result;
   }
   static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
@@ -1537,6 +1570,7 @@ struct DarwinPlatform {
   SourceKind Kind;
   DarwinPlatformKind Platform;
   DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
+  VersionTuple NativeTargetVersion;
   std::string OSVersion;
   bool HasOSVersion = true, InferSimulatorFromArch = true;
   Arg *Argument;
@@ -1770,15 +1804,16 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
 
 /// Returns the deployment target that's specified using the -target option.
 Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
-    DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver) {
+    DerivedArgList &Args, const llvm::Triple &Triple, const Driver &TheDriver,
+    const Optional<DarwinSDKInfo> &SDKInfo) {
   if (!Args.hasArg(options::OPT_target))
     return None;
   if (Triple.getOS() == llvm::Triple::Darwin ||
       Triple.getOS() == llvm::Triple::UnknownOS)
     return None;
   std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
-  return DarwinPlatform::createFromTarget(Triple, OSVersion,
-                                          Args.getLastArg(options::OPT_target));
+  return DarwinPlatform::createFromTarget(
+      Triple, OSVersion, Args.getLastArg(options::OPT_target), SDKInfo);
 }
 
 Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
@@ -1827,7 +1862,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
 
   // The OS and the version can be specified using the -target argument.
   Optional<DarwinPlatform> OSTarget =
-      getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver());
+      getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
   if (OSTarget) {
     Optional<DarwinPlatform> OSVersionArgTarget =
         getDeploymentTargetFromOSVersionArg(Args, getDriver());
@@ -1913,13 +1948,24 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
       getDriver().Diag(diag::err_drv_invalid_version_number)
           << OSTarget->getAsString(Args, Opts);
     ;
+    if (OSTarget->getEnvironment() == MacCatalyst &&
+        (Major < 13 || (Major == 13 && Minor < 1))) {
+      getDriver().Diag(diag::err_drv_invalid_version_number)
+          << OSTarget->getAsString(Args, Opts);
+      Major = 13;
+      Minor = 1;
+      Micro = 0;
+    }
     // For 32-bit targets, the deployment target for iOS has to be earlier than
     // iOS 11.
     if (getTriple().isArch32Bit() && Major >= 11) {
       // If the deployment target is explicitly specified, print a diagnostic.
       if (OSTarget->isExplicitlySpecified()) {
-        getDriver().Diag(diag::warn_invalid_ios_deployment_target)
-            << OSTarget->getAsString(Args, Opts);
+        if (OSTarget->getEnvironment() == MacCatalyst)
+          getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);
+        else
+          getDriver().Diag(diag::warn_invalid_ios_deployment_target)
+              << OSTarget->getAsString(Args, Opts);
         // Otherwise, set it to 10.99.99.
       } else {
         Major = 10;
@@ -1948,7 +1994,10 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
       OSTarget->canInferSimulatorFromArch() && getTriple().isX86())
     Environment = Simulator;
 
-  setTarget(Platform, Environment, Major, Minor, Micro);
+  VersionTuple NativeTargetVersion;
+  if (Environment == MacCatalyst)
+    NativeTargetVersion = OSTarget->getNativeTargetVersion();
+  setTarget(Platform, Environment, Major, Minor, Micro, NativeTargetVersion);
 
   if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
     StringRef SDK = getSDKName(A->getValue());
@@ -2438,6 +2487,8 @@ void MachO::AddLinkRuntimeLibArgs(const ArgList &Args,
 bool Darwin::isAlignedAllocationUnavailable() const {
   llvm::Triple::OSType OS;
 
+  if (isTargetMacCatalyst())
+    return TargetVersion < alignedAllocMinVersion(llvm::Triple::MacOSX);
   switch (TargetPlatform) {
   case MacOS: // Earlier than 10.13.
     OS = llvm::Triple::MacOSX;
@@ -2469,10 +2520,24 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
   if (SDKInfo) {
     /// Pass the SDK version to the compiler when the SDK information is
     /// available.
-    std::string Arg;
-    llvm::raw_string_ostream OS(Arg);
-    OS << "-target-sdk-version=" << SDKInfo->getVersion();
-    CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
+    auto EmitTargetSDKVersionArg = [&](const VersionTuple &V) {
+      std::string Arg;
+      llvm::raw_string_ostream OS(Arg);
+      OS << "-target-sdk-version=" << V;
+      CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
+    };
+
+    if (isTargetMacCatalyst()) {
+      if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(
+              DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
+        Optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map(
+            SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(), None);
+        EmitTargetSDKVersionArg(
+            SDKVersion ? *SDKVersion : minimumMacCatalystDeploymentTarget());
+      }
+    } else {
+      EmitTargetSDKVersionArg(SDKInfo->getVersion());
+    }
   }
 
   // Enable compatibility mode for NSItemProviderCompletionHandler in
@@ -2608,7 +2673,7 @@ bool MachO::SupportsProfiling() const {
 
 void Darwin::addMinVersionArgs(const ArgList &Args,
                                ArgStringList &CmdArgs) const {
-  VersionTuple TargetVersion = getTargetVersion();
+  VersionTuple TargetVersion = getTripleTargetVersion();
 
   if (isTargetWatchOS())
     CmdArgs.push_back("-watchos_version_min");
@@ -2622,6 +2687,8 @@ void Darwin::addMinVersionArgs(const ArgList &Args,
     CmdArgs.push_back("-ios_simulator_version_min");
   else if (isTargetIOSBased())
     CmdArgs.push_back("-iphoneos_version_min");
+  else if (isTargetMacCatalyst())
+    CmdArgs.push_back("-maccatalyst_version_min");
   else {
     assert(isTargetMacOS() && "unexpected target");
     CmdArgs.push_back("-macosx_version_min");
@@ -2639,11 +2706,9 @@ static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,
   case Darwin::MacOS:
     return "macos";
   case Darwin::IPhoneOS:
-    if (Environment == Darwin::NativeEnvironment ||
-        Environment == Darwin::Simulator)
-      return "ios";
-    // FIXME: Add macCatalyst support here ("\"mac catalyst\"").
-    llvm_unreachable("macCatalyst isn't yet supported");
+    if (Environment == Darwin::MacCatalyst)
+      return "mac catalyst";
+    return "ios";
   case Darwin::TvOS:
     return "tvos";
   case Darwin::WatchOS:
@@ -2661,11 +2726,30 @@ void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
   if (TargetEnvironment == Darwin::Simulator)
     PlatformName += "-simulator";
   CmdArgs.push_back(Args.MakeArgString(PlatformName));
-  VersionTuple TargetVersion = getTargetVersion().withoutBuild();
+  VersionTuple TargetVersion = getTripleTargetVersion().withoutBuild();
   VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
   if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
     TargetVersion = MinTgtVers;
   CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+
+  if (isTargetMacCatalyst()) {
+    // Mac Catalyst programs must use the appropriate iOS SDK version
+    // that corresponds to the macOS SDK version used for the compilation.
+    Optional<VersionTuple> iOSSDKVersion;
+    if (SDKInfo) {
+      if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(
+              DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
+        iOSSDKVersion = MacOStoMacCatalystMapping->map(
+            SDKInfo->getVersion().withoutBuild(),
+            minimumMacCatalystDeploymentTarget(), None);
+      }
+    }
+    CmdArgs.push_back(Args.MakeArgString(
+        (iOSSDKVersion ? *iOSSDKVersion : minimumMacCatalystDeploymentTarget())
+            .getAsString()));
+    return;
+  }
+
   if (SDKInfo) {
     VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
     CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
@@ -2733,7 +2817,7 @@ static void addPgProfilingLinkArgs(const Darwin &D, const ArgList &Args,
       CmdArgs.push_back("-no_new_main");
   } else {
     D.getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin)
-        << D.isTargetMacOS();
+        << D.isTargetMacOSBased();
   }
 }
 
@@ -2786,7 +2870,7 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args,
 
 void Darwin::CheckObjCARC() const {
   if (isTargetIOSBased() || isTargetWatchOSBased() ||
-      (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
+      (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)))
     return;
   getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
 }
@@ -2807,11 +2891,11 @@ SanitizerMask Darwin::getSupportedSanitizers() const {
   // Prior to 10.9, macOS shipped a version of the C++ standard library without
   // C++11 support. The same is true of iOS prior to version 5. These OS'es are
   // incompatible with -fsanitize=vptr.
-  if (!(isTargetMacOS() && isMacosxVersionLT(10, 9))
-      && !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))
+  if (!(isTargetMacOSBased() && isMacosxVersionLT(10, 9)) &&
+      !(isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0)))
     Res |= SanitizerKind::Vptr;
 
-  if ((IsX86_64 || IsAArch64) && isTargetMacOS()) {
+  if ((IsX86_64 || IsAArch64) && isTargetMacOSBased()) {
     Res |= SanitizerKind::Thread;
   } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) {
     if (IsX86_64)

diff  --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 775336ee3158c..812e51344f470 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -284,13 +284,16 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
   enum DarwinEnvironmentKind {
     NativeEnvironment,
     Simulator,
+    MacCatalyst,
   };
 
   mutable DarwinPlatformKind TargetPlatform;
   mutable DarwinEnvironmentKind TargetEnvironment;
 
-  /// The OS version we are targeting.
+  /// The native OS version we are targeting.
   mutable VersionTuple TargetVersion;
+  /// The OS version we are targeting as specified in the triple.
+  mutable VersionTuple OSTargetVersion;
 
   /// The information about the darwin SDK that was used.
   mutable Optional<DarwinSDKInfo> SDKInfo;
@@ -337,12 +340,14 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
   // FIXME: Eliminate these ...Target functions and derive separate tool chains
   // for these targets and put version in constructor.
   void setTarget(DarwinPlatformKind Platform, DarwinEnvironmentKind Environment,
-                 unsigned Major, unsigned Minor, unsigned Micro) const {
+                 unsigned Major, unsigned Minor, unsigned Micro,
+                 VersionTuple NativeTargetVersion) const {
     // FIXME: For now, allow reinitialization as long as values don't
     // change. This will go away when we move away from argument translation.
     if (TargetInitialized && TargetPlatform == Platform &&
         TargetEnvironment == Environment &&
-        TargetVersion == VersionTuple(Major, Minor, Micro))
+        (Environment == MacCatalyst ? OSTargetVersion : TargetVersion) ==
+            VersionTuple(Major, Minor, Micro))
       return;
 
     assert(!TargetInitialized && "Target already initialized!");
@@ -352,6 +357,11 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
     TargetVersion = VersionTuple(Major, Minor, Micro);
     if (Environment == Simulator)
       const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::Simulator);
+    else if (Environment == MacCatalyst) {
+      const_cast<Darwin *>(this)->setTripleEnvironment(llvm::Triple::MacABI);
+      TargetVersion = NativeTargetVersion;
+      OSTargetVersion = VersionTuple(Major, Minor, Micro);
+    }
   }
 
 public:
@@ -402,6 +412,10 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
     return TargetPlatform == WatchOS;
   }
 
+  bool isTargetMacCatalyst() const {
+    return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
+  }
+
   bool isTargetMacOS() const {
     assert(TargetInitialized && "Target not initialized!");
     return TargetPlatform == MacOS;
@@ -409,8 +423,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
 
   bool isTargetMacOSBased() const {
     assert(TargetInitialized && "Target not initialized!");
-    // FIXME (Alex L): Add remaining MacCatalyst suppport.
-    return TargetPlatform == MacOS;
+    return TargetPlatform == MacOS || isTargetMacCatalyst();
   }
 
   bool isTargetAppleSiliconMac() const {
@@ -420,9 +433,13 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
 
   bool isTargetInitialized() const { return TargetInitialized; }
 
-  VersionTuple getTargetVersion() const {
+  /// The version of the OS that's used by the OS specified in the target
+  /// triple. It might be 
diff erent from the actual target OS on which the
+  /// program will run, e.g. MacCatalyst code runs on a macOS target, but its
+  /// target triple is iOS.
+  VersionTuple getTripleTargetVersion() const {
     assert(TargetInitialized && "Target not initialized!");
-    return TargetVersion;
+    return isTargetMacCatalyst() ? OSTargetVersion : TargetVersion;
   }
 
   bool isIPhoneOSVersionLT(unsigned V0, unsigned V1 = 0,
@@ -436,7 +453,8 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
   /// supported macOS version, the deployment target version is compared to the
   /// specifed version instead.
   bool isMacosxVersionLT(unsigned V0, unsigned V1 = 0, unsigned V2 = 0) const {
-    assert(isTargetMacOS() && getTriple().isMacOSX() &&
+    assert(isTargetMacOSBased() &&
+           (getTriple().isMacOSX() || getTriple().isMacCatalystEnvironment()) &&
            "Unexpected call for non OS X target!");
     // The effective triple might not be initialized yet, so construct a
     // pseudo-effective triple to get the minimum supported OS version.
@@ -490,7 +508,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
     // This is only used with the non-fragile ABI and non-legacy dispatch.
 
     // Mixed dispatch is used everywhere except OS X before 10.6.
-    return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
+    return !(isTargetMacOSBased() && isMacosxVersionLT(10, 6));
   }
 
   LangOptions::StackProtectorMode
@@ -499,9 +517,9 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
     // and for everything in 10.6 and beyond
     if (isTargetIOSBased() || isTargetWatchOSBased())
       return LangOptions::SSPOn;
-    else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
+    else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))
       return LangOptions::SSPOn;
-    else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
+    else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
       return LangOptions::SSPOn;
 
     return LangOptions::SSPOff;

diff  --git a/clang/test/Driver/Inputs/MacOSX10.15.versioned.sdk/SDKSettings.json b/clang/test/Driver/Inputs/MacOSX10.15.versioned.sdk/SDKSettings.json
new file mode 100644
index 0000000000000..b0769e9f86045
--- /dev/null
+++ b/clang/test/Driver/Inputs/MacOSX10.15.versioned.sdk/SDKSettings.json
@@ -0,0 +1,14 @@
+{
+  "Version":"10.15",
+  "MaximumDeploymentTarget": "10.15.99",
+  "VersionMap" : {
+      "macOS_iOSMac" : {
+          "10.15" : "13.1",
+          "10.15.1" : "13.2"
+      },
+      "iOSMac_macOS" : {
+          "13.1" : "10.15",
+          "13.2" : "10.15.1"
+      }
+  }
+}

diff  --git a/clang/test/Driver/darwin-ld-platform-version-maccatalyst.c b/clang/test/Driver/darwin-ld-platform-version-maccatalyst.c
new file mode 100644
index 0000000000000..9878376ec5e74
--- /dev/null
+++ b/clang/test/Driver/darwin-ld-platform-version-maccatalyst.c
@@ -0,0 +1,9 @@
+// RUN: touch %t.o
+
+// RUN: %clang -target x86_64-apple-ios13.3-macabi -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \
+// RUN:   | FileCheck %s
+// RUN: %clang -target x86_64-apple-ios13.3-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=520 -### %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MAPPED-SDK %s
+
+// CHECK: "-platform_version" "mac catalyst" "13.3.0" "13.1"
+// CHECK-MAPPED-SDK: "-platform_version" "mac catalyst" "13.3.0" "13.1"

diff  --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c
index 15e5d100afcbc..bd874d24e6c75 100644
--- a/clang/test/Driver/darwin-ld.c
+++ b/clang/test/Driver/darwin-ld.c
@@ -140,6 +140,13 @@
 // LINK_VERSION_MIN: {{ld(.exe)?"}}
 // LINK_VERSION_MIN: "-macosx_version_min" "10.7.0"
 
+// RUN: %clang -target x86_64-apple-ios13.1-macabi -mlinker-version=400 -### %t.o 2>> %t.log
+// RUN: FileCheck -check-prefix=LINK_VERSION_MIN_MACABI %s < %t.log
+// LINK_VERSION_MIN_MACABI: {{ld(.exe)?"}}
+// LINK_VERSION_MIN_MACABI: "-maccatalyst_version_min" "13.1.0"
+// LINK_VERSION_MIN_MACABI-NOT: macosx_version_min
+// LINK_VERSION_MIN_MACABI-NOT: macos_version_min
+
 // RUN: %clang -target x86_64-apple-darwin12 -### %t.o 2> %t.log
 // RUN: FileCheck -check-prefix=LINK_NO_CRT1 %s < %t.log
 // LINK_NO_CRT1-NOT: crt

diff  --git a/clang/test/Driver/darwin-mac-catalyst-32bit-not-supported.c b/clang/test/Driver/darwin-mac-catalyst-32bit-not-supported.c
new file mode 100644
index 0000000000000..cb7f2c2bfced7
--- /dev/null
+++ b/clang/test/Driver/darwin-mac-catalyst-32bit-not-supported.c
@@ -0,0 +1,4 @@
+// RUN: %clang --target=i386-apple-ios13.1-macabi -c -### %s 2>&1 \
+// RUN:   | FileCheck %s
+
+// CHECK: error: 32-bit targets are not supported when building for Mac Catalyst

diff  --git a/clang/test/Driver/darwin-maccatalyst.c b/clang/test/Driver/darwin-maccatalyst.c
new file mode 100644
index 0000000000000..0e388ea3abe67
--- /dev/null
+++ b/clang/test/Driver/darwin-maccatalyst.c
@@ -0,0 +1,9 @@
+// RUN: %clang -target x86_64-apple-ios13.1-macabi -c %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=CHECK-VERSION1 %s
+// RUN: %clang -target x86_64-apple-ios13.0-macabi -c %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: %clang -target x86_64-apple-ios12.0-macabi -c %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=CHECK-ERROR %s
+
+// CHECK-VERSION1: "x86_64-apple-ios13.1.0-macabi"
+// CHECK-ERROR: error: invalid version number in '-target x86_64-apple-ios

diff  --git a/clang/test/Driver/darwin-objc-defaults.m b/clang/test/Driver/darwin-objc-defaults.m
index 1b3f7a844445d..bbcb7e0c6690d 100644
--- a/clang/test/Driver/darwin-objc-defaults.m
+++ b/clang/test/Driver/darwin-objc-defaults.m
@@ -92,3 +92,11 @@
 // CHECK-CHECK-ARMV7_IPHONE3_0: -fobjc-runtime=ios-3.0
 // CHECK-CHECK-ARMV7_IPHONE3_0-NOT: -fobjc-dispatch-method
 // CHECK-CHECK-ARMV7_IPHONE3_0: darwin-objc-defaults
+
+// RUN: %clang -target x86_64-apple-ios13.1-macabi -S -### %s 2> %t
+// RUN: FileCheck --check-prefix CHECK-CHECK-MACCATALYST < %t %s
+
+// CHECK-CHECK-MACCATALYST: "-cc1"
+// CHECK-CHECK-MACCATALYST: -fobjc-runtime=macosx-10.15
+// CHECK-CHECK-MACCATALYST-NOT: -fobjc-dispatch-method
+// CHECK-CHECK-MACCATALYST: darwin-objc-defaults

diff  --git a/clang/test/Driver/darwin-objc-runtime-maccatalyst.m b/clang/test/Driver/darwin-objc-runtime-maccatalyst.m
new file mode 100644
index 0000000000000..1ed47b68a280e
--- /dev/null
+++ b/clang/test/Driver/darwin-objc-runtime-maccatalyst.m
@@ -0,0 +1,13 @@
+// RUN: %clang -target x86_64-apple-ios13.2-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
+// RUN:   | FileCheck %s
+// RUN: %clang -target x86_64-apple-ios13.2.0-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
+// RUN:   | FileCheck %s
+// RUN: %clang -target x86_64-apple-ios13.2-macabi -isysroot %S/Inputs/MacOSX10.14.sdk -c %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=FALLBACK-DEFAULT %s
+// RUN: %clang -target x86_64-apple-ios12.99.99-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=FALLBACK-DEFAULT %s
+// RUN: %clang -target x86_64-apple-ios-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=FALLBACK-DEFAULT %s
+
+// CHECK: -fobjc-runtime=macosx-10.15.1
+// FALLBACK-DEFAULT: -fobjc-runtime=macosx-10.15

diff  --git a/clang/test/Driver/darwin-sanitizer-ld.c b/clang/test/Driver/darwin-sanitizer-ld.c
index 53c7fce115e71..451977556789d 100644
--- a/clang/test/Driver/darwin-sanitizer-ld.c
+++ b/clang/test/Driver/darwin-sanitizer-ld.c
@@ -93,6 +93,18 @@
 // CHECK-ASAN-WATCHOSSIM: "-rpath" "@executable_path"
 // CHECK-ASAN-WATCHOSSIM: "-rpath" "{{.*}}lib{{.*}}darwin"
 
+// RUN: %clang -no-canonical-prefixes -### -target x86_64-apple-ios13.1-macabi \
+// RUN:   -stdlib=platform -fsanitize=address \
+// RUN:   -resource-dir %S/Inputs/resource_dir \
+// RUN:   %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ASAN-MACCATALYST %s
+
+// CHECK-ASAN-MACCATALYST: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ASAN-MACCATALYST-NOT: "-lstdc++"
+// CHECK-ASAN-MACCATALYST-NOT: "-lc++"
+// CHECK-ASAN-MACCATALYST: libclang_rt.asan_osx_dynamic.dylib"
+// CHECK-ASAN-MACCATALYST: "-rpath" "@executable_path"
+// CHECK-ASAN-MACCATALYST: "-rpath" "{{.*}}lib{{.*}}darwin"
+
 // RUN: %clang -no-canonical-prefixes -### -target armv7-apple-ios  \
 // RUN:   -stdlib=platform -fsanitize=address -miphoneos-version-min=7 \
 // RUN:   %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ASAN-IOS %s

diff  --git a/clang/test/Driver/darwin-sdk-version-maccatalyst.c b/clang/test/Driver/darwin-sdk-version-maccatalyst.c
new file mode 100644
index 0000000000000..2ec0b6dfc4ceb
--- /dev/null
+++ b/clang/test/Driver/darwin-sdk-version-maccatalyst.c
@@ -0,0 +1,6 @@
+// RUN: %clang -target x86_64-apple-ios13.1-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck %s
+// RUN: %clang -target x86_64-apple-ios13.99-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c -### %s 2>&1 \
+// RUN:   | FileCheck %s
+
+// CHECK: "-target-sdk-version=13.1"


        


More information about the cfe-commits mailing list