[lldb] [clang] [clang] Upstream XROS support in Clang (PR #78392)

Jonas Devlieghere via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 17 10:18:16 PST 2024


https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/78392

>From 6f6d93b6cc413d54dbdec050000f30ede00ffdb4 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Wed, 10 Jan 2024 17:35:47 -0800
Subject: [PATCH 1/2] [lldb] Upstream xros support in lldb

Upstream support for debugging xros applications through LLDB.
---
 lldb/include/lldb/Utility/XcodeSDK.h          |   2 +
 .../Host/macosx/objcxx/HostInfoMacOSX.mm      |   3 +
 .../DynamicLoaderDarwinKernel.cpp             |   1 +
 .../MacOSX-DYLD/DynamicLoaderMacOS.cpp        |   1 +
 .../MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp   |   1 +
 .../Instruction/ARM/EmulateInstructionARM.cpp |   1 +
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp     |  11 +-
 .../Plugins/Platform/MacOSX/CMakeLists.txt    |   1 +
 .../MacOSX/PlatformAppleSimulator.cpp         |  37 +++++
 .../Platform/MacOSX/PlatformDarwin.cpp        |  17 +-
 .../Platform/MacOSX/PlatformMacOSX.cpp        |   3 +
 .../Platform/MacOSX/PlatformRemoteAppleXR.cpp | 157 ++++++++++++++++++
 .../Platform/MacOSX/PlatformRemoteAppleXR.h   |  38 +++++
 ...PlatformiOSSimulatorCoreSimulatorSupport.h |   3 +-
 .../Process/MacOSX-Kernel/ProcessKDP.cpp      |   1 +
 .../GDBRemoteCommunicationClient.cpp          |   3 +-
 .../MacOSX/SystemRuntimeMacOSX.cpp            |   1 +
 lldb/source/Utility/XcodeSDK.cpp              |  23 +++
 .../debugserver/source/MacOSX/MachProcess.mm  |  12 ++
 lldb/tools/debugserver/source/RNBRemote.cpp   |  11 +-
 lldb/unittests/Utility/XcodeSDKTest.cpp       |  22 +++
 21 files changed, 340 insertions(+), 9 deletions(-)
 create mode 100644 lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.cpp
 create mode 100644 lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.h

diff --git a/lldb/include/lldb/Utility/XcodeSDK.h b/lldb/include/lldb/Utility/XcodeSDK.h
index f8528995d549c9..673ea578ffce85 100644
--- a/lldb/include/lldb/Utility/XcodeSDK.h
+++ b/lldb/include/lldb/Utility/XcodeSDK.h
@@ -34,6 +34,8 @@ class XcodeSDK {
     AppleTVOS,
     WatchSimulator,
     watchOS,
+    XRSimulator,
+    XROS,
     bridgeOS,
     Linux,
     unknown = -1
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 110a01732b2473..f96e2cf80c5fac 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -276,6 +276,9 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
 #elif defined(TARGET_OS_WATCHOS) && TARGET_OS_WATCHOS == 1
         arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
         arch_64.GetTriple().setOS(llvm::Triple::WatchOS);
+#elif defined(TARGET_OS_XR) && TARGET_OS_XR == 1
+        arch_32.GetTriple().setOS(llvm::Triple::XROS);
+        arch_64.GetTriple().setOS(llvm::Triple::XROS);
 #elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1
         arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
         arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 7df917d03ceeda..4128ac1cdf1bba 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -166,6 +166,7 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
     case llvm::Triple::IOS:
     case llvm::Triple::TvOS:
     case llvm::Triple::WatchOS:
+    case llvm::Triple::XROS:
     // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
       if (triple_ref.getVendor() != llvm::Triple::Apple) {
         return nullptr;
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 4451d8c7689a28..261592558095b4 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -55,6 +55,7 @@ DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
       case llvm::Triple::IOS:
       case llvm::Triple::TvOS:
       case llvm::Triple::WatchOS:
+      case llvm::Triple::XROS:
       // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
         create = triple_ref.getVendor() == llvm::Triple::Apple;
         break;
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 0bd465aba2d8a2..7e589b0d7af2c7 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -75,6 +75,7 @@ DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
       case llvm::Triple::IOS:
       case llvm::Triple::TvOS:
       case llvm::Triple::WatchOS:
+      case llvm::Triple::XROS:
       // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
         create = triple_ref.getVendor() == llvm::Triple::Apple;
         break;
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index ff5c79aa2455b0..b652ede9b1f518 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -830,6 +830,7 @@ uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
   case llvm::Triple::IOS:
   case llvm::Triple::TvOS:
   case llvm::Triple::WatchOS:
+  case llvm::Triple::XROS:
   // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
     is_apple = true;
     break;
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index e40ba8d3addb51..8cb9a5989d8984 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -4916,6 +4916,14 @@ struct OSEnv {
       environment =
           llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
       return;
+    case llvm::MachO::PLATFORM_XROS:
+      os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
+      return;
+    case llvm::MachO::PLATFORM_XROS_SIMULATOR:
+      os_type = llvm::Triple::getOSTypeName(llvm::Triple::XROS);
+      environment =
+          llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
+      return;
     default: {
       Log *log(GetLog(LLDBLog::Symbols | LLDBLog::Process));
       LLDB_LOGF(log, "unsupported platform in LC_BUILD_VERSION");
@@ -6483,7 +6491,8 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
       (target_triple.getOS() == llvm::Triple::MacOSX ||
        target_triple.getOS() == llvm::Triple::IOS ||
        target_triple.getOS() == llvm::Triple::WatchOS ||
-       target_triple.getOS() == llvm::Triple::TvOS)) {
+       target_triple.getOS() == llvm::Triple::TvOS ||
+       target_triple.getOS() == llvm::Triple::XROS)) {
     // NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS))
     // {
     bool make_core = false;
diff --git a/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt b/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
index fd3dffc948e814..8c1e9f4013fbb2 100644
--- a/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ b/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
@@ -14,6 +14,7 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
   PlatformRemoteAppleBridge.cpp
   PlatformRemoteAppleTV.cpp
   PlatformRemoteAppleWatch.cpp
+  PlatformRemoteAppleXR.cpp
   PlatformRemoteDarwinDevice.cpp
   PlatformRemoteMacOSX.cpp
   PlatformRemoteiOS.cpp
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index dc59d904c74d82..0c4b566b7d5356 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -675,6 +675,41 @@ struct PlatformAppleWatchSimulator {
   }
 };
 
+static const char *g_xros_plugin_name = "xros-simulator";
+static const char *g_xros_description = "XROS simulator platform plug-in.";
+
+/// XRSimulator Plugin.
+struct PlatformXRSimulator {
+  static void Initialize() {
+    PluginManager::RegisterPlugin(g_xros_plugin_name, g_xros_description,
+                                  PlatformXRSimulator::CreateInstance);
+  }
+
+  static void Terminate() {
+    PluginManager::UnregisterPlugin(PlatformXRSimulator::CreateInstance);
+  }
+
+  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
+    return PlatformAppleSimulator::CreateInstance(
+        "PlatformXRSimulator", g_xros_description,
+        ConstString(g_xros_plugin_name),
+        {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86},
+        llvm::Triple::XROS, {llvm::Triple::XROS},
+        {
+#ifdef __APPLE__
+#if __arm64__
+          "arm64e-apple-xros-simulator", "arm64-apple-xros-simulator",
+#else
+          "x86_64-apple-xros-simulator", "x86_64h-apple-xros-simulator",
+#endif
+#endif
+        },
+        "XRSimulator.Internal.sdk", "XRSimulator.sdk",
+        XcodeSDK::Type::XRSimulator,
+        CoreSimulatorSupport::DeviceType::ProductFamilyID::appleXR, force,
+        arch);
+  }
+};
 
 static unsigned g_initialize_count = 0;
 
@@ -685,12 +720,14 @@ void PlatformAppleSimulator::Initialize() {
     PlatformiOSSimulator::Initialize();
     PlatformAppleTVSimulator::Initialize();
     PlatformAppleWatchSimulator::Initialize();
+    PlatformXRSimulator::Initialize();
   }
 }
 
 void PlatformAppleSimulator::Terminate() {
   if (g_initialize_count > 0)
     if (--g_initialize_count == 0) {
+      PlatformXRSimulator::Terminate();
       PlatformAppleWatchSimulator::Terminate();
       PlatformAppleTVSimulator::Terminate();
       PlatformiOSSimulator::Terminate();
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index ca7ff5a99f9060..6fb5bbfbe417ba 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -796,6 +796,9 @@ FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) {
   case XcodeSDK::Type::AppleTVSimulator:
     sdks_spec.AppendPathComponent("AppleTVSimulator.platform");
     break;
+  case XcodeSDK::Type::XRSimulator:
+    sdks_spec.AppendPathComponent("XRSimulator.platform");
+    break;
   default:
     llvm_unreachable("unsupported sdk");
   }
@@ -1032,6 +1035,9 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
   case XcodeSDK::Type::watchOS:
     use_current_os_version = get_host_os() == llvm::Triple::WatchOS;
     break;
+  case XcodeSDK::Type::XROS:
+    use_current_os_version = get_host_os() == llvm::Triple::XROS;
+    break;
   default:
     break;
   }
@@ -1049,8 +1055,10 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
         version = object_file->GetMinimumOSVersion();
     }
   }
-  // Only add the version-min options if we got a version from somewhere
-  if (!version.empty() && sdk_type != XcodeSDK::Type::Linux) {
+  // Only add the version-min options if we got a version from somewhere.
+  // clang has no version-min clang flag for XROS.
+  if (!version.empty() && sdk_type != XcodeSDK::Type::Linux &&
+      sdk_type != XcodeSDK::Type::XROS) {
 #define OPTION(PREFIX, NAME, VAR, ...)                                         \
   llvm::StringRef opt_##VAR = NAME;                                            \
   (void)opt_##VAR;
@@ -1079,6 +1087,9 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
     case XcodeSDK::Type::watchOS:
       minimum_version_option << opt_mwatchos_version_min_EQ;
       break;
+    case XcodeSDK::Type::XRSimulator:
+    case XcodeSDK::Type::XROS:
+      // FIXME: Pass the right argument once it exists.
     case XcodeSDK::Type::bridgeOS:
     case XcodeSDK::Type::Linux:
     case XcodeSDK::Type::unknown:
@@ -1343,6 +1354,8 @@ llvm::Triple::OSType PlatformDarwin::GetHostOSType() {
   return llvm::Triple::TvOS;
 #elif TARGET_OS_BRIDGE
   return llvm::Triple::BridgeOS;
+#elif TARGET_OS_XR
+  return llvm::Triple::XROS;
 #else
 #error "LLDB being compiled for an unrecognized Darwin OS"
 #endif
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index ba412da62e57b0..dad6dcd1339553 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -15,6 +15,7 @@
 #include "PlatformRemoteAppleBridge.h"
 #include "PlatformRemoteAppleTV.h"
 #include "PlatformRemoteAppleWatch.h"
+#include "PlatformRemoteAppleXR.h"
 #endif
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/Debugger.h"
@@ -53,6 +54,7 @@ void PlatformMacOSX::Initialize() {
   PlatformRemoteAppleTV::Initialize();
   PlatformRemoteAppleWatch::Initialize();
   PlatformRemoteAppleBridge::Initialize();
+  PlatformRemoteAppleXR::Initialize();
 #endif
 
   if (g_initialize_count++ == 0) {
@@ -75,6 +77,7 @@ void PlatformMacOSX::Terminate() {
   }
 
 #if defined(__APPLE__)
+  PlatformRemoteAppleXR::Terminate();
   PlatformRemoteAppleBridge::Terminate();
   PlatformRemoteAppleWatch::Terminate();
   PlatformRemoteAppleTV::Terminate();
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.cpp
new file mode 100644
index 00000000000000..c7e734a5a098d7
--- /dev/null
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.cpp
@@ -0,0 +1,157 @@
+//===-- PlatformRemoteAppleXR.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+#include <vector>
+
+#include "PlatformRemoteAppleXR.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// Static Variables
+static uint32_t g_xr_initialize_count = 0;
+
+// Static Functions
+void PlatformRemoteAppleXR::Initialize() {
+  PlatformDarwin::Initialize();
+
+  if (g_xr_initialize_count++ == 0) {
+    PluginManager::RegisterPlugin(PlatformRemoteAppleXR::GetPluginNameStatic(),
+                                  PlatformRemoteAppleXR::GetDescriptionStatic(),
+                                  PlatformRemoteAppleXR::CreateInstance);
+  }
+}
+
+void PlatformRemoteAppleXR::Terminate() {
+  if (g_xr_initialize_count > 0) {
+    if (--g_xr_initialize_count == 0) {
+      PluginManager::UnregisterPlugin(PlatformRemoteAppleXR::CreateInstance);
+    }
+  }
+
+  PlatformDarwin::Terminate();
+}
+
+PlatformSP PlatformRemoteAppleXR::CreateInstance(bool force,
+                                                 const ArchSpec *arch) {
+  Log *log = GetLog(LLDBLog::Platform);
+  if (log) {
+    const char *arch_name;
+    if (arch && arch->GetArchitectureName())
+      arch_name = arch->GetArchitectureName();
+    else
+      arch_name = "<null>";
+
+    const char *triple_cstr =
+        arch ? arch->GetTriple().getTriple().c_str() : "<null>";
+
+    LLDB_LOGF(log, "PlatformRemoteAppleXR::%s(force=%s, arch={%s,%s})",
+              __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
+  }
+
+  bool create = force;
+  if (!create && arch && arch->IsValid()) {
+    switch (arch->GetMachine()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::aarch64:
+    case llvm::Triple::aarch64_32:
+    case llvm::Triple::thumb: {
+      const llvm::Triple &triple = arch->GetTriple();
+      llvm::Triple::VendorType vendor = triple.getVendor();
+      switch (vendor) {
+      case llvm::Triple::Apple:
+        create = true;
+        break;
+
+#if defined(__APPLE__)
+      // Only accept "unknown" for the vendor if the host is Apple and
+      // "unknown" wasn't specified (it was just returned because it was NOT
+      // specified)
+      case llvm::Triple::UnknownVendor:
+        create = !arch->TripleVendorWasSpecified();
+        break;
+
+#endif
+      default:
+        break;
+      }
+      if (create) {
+        switch (triple.getOS()) {
+        case llvm::Triple::XROS: // This is the right triple value for Apple
+                                 // XR debugging
+          break;
+
+        default:
+          create = false;
+          break;
+        }
+      }
+    } break;
+    default:
+      break;
+    }
+  }
+
+#if defined(TARGET_OS_XR) && TARGET_OS_XR == 1
+  // If lldb is running on a XR device, this isn't a RemoteXR.
+  if (force == false) {
+    create = false;
+  }
+#endif
+
+  if (create) {
+    LLDB_LOGF(log, "PlatformRemoteAppleXR::%s() creating platform",
+              __FUNCTION__);
+
+    return lldb::PlatformSP(new PlatformRemoteAppleXR());
+  }
+
+  LLDB_LOGF(log, "PlatformRemoteAppleXR::%s() aborting creation of platform",
+            __FUNCTION__);
+
+  return lldb::PlatformSP();
+}
+
+llvm::StringRef PlatformRemoteAppleXR::GetPluginNameStatic() {
+  return "remote-xros";
+}
+
+llvm::StringRef PlatformRemoteAppleXR::GetDescriptionStatic() {
+  return "Remote Apple XR platform plug-in.";
+}
+
+/// Default Constructor
+PlatformRemoteAppleXR::PlatformRemoteAppleXR() : PlatformRemoteDarwinDevice() {}
+
+std::vector<lldb_private::ArchSpec>
+PlatformRemoteAppleXR::GetSupportedArchitectures(
+    const ArchSpec &process_host_arch) {
+  std::vector<ArchSpec> result;
+  result.push_back(ArchSpec("arm64-apple-xros"));
+  result.push_back(ArchSpec("arm64-apple-xros"));
+  return result;
+}
+
+llvm::StringRef PlatformRemoteAppleXR::GetDeviceSupportDirectoryName() {
+  return "XROS DeviceSupport";
+}
+
+llvm::StringRef PlatformRemoteAppleXR::GetPlatformName() {
+  return "XROS.platform";
+}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.h
new file mode 100644
index 00000000000000..4fed6e15eda31c
--- /dev/null
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteAppleXR.h
@@ -0,0 +1,38 @@
+//===-- PlatformRemoteAppleXR.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "PlatformRemoteDarwinDevice.h"
+
+namespace lldb_private {
+class PlatformRemoteAppleXR : public PlatformRemoteDarwinDevice {
+public:
+  PlatformRemoteAppleXR();
+
+  static lldb::PlatformSP CreateInstance(bool force,
+                                         const lldb_private::ArchSpec *arch);
+
+  static void Initialize();
+
+  static void Terminate();
+
+  static llvm::StringRef GetPluginNameStatic();
+
+  static llvm::StringRef GetDescriptionStatic();
+
+  llvm::StringRef GetDescription() override { return GetDescriptionStatic(); }
+
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+  std::vector<lldb_private::ArchSpec> GetSupportedArchitectures(
+      const lldb_private::ArchSpec &process_host_arch) override;
+
+protected:
+  llvm::StringRef GetDeviceSupportDirectoryName() override;
+  llvm::StringRef GetPlatformName() override;
+};
+} // namespace lldb_private
diff --git a/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h b/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
index 1889be65e196d7..b2956054d50bf4 100644
--- a/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
+++ b/lldb/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
@@ -73,7 +73,8 @@ class DeviceType {
     iPhone = 1,
     iPad = 2,
     appleTV = 3,
-    appleWatch = 4
+    appleWatch = 4,
+    appleXR = 7,
   };
 
   DeviceType();
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index de739acf5b2a52..755b3a773692e3 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -125,6 +125,7 @@ bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
     case llvm::Triple::IOS:    // For arm targets
     case llvm::Triple::TvOS:
     case llvm::Triple::WatchOS:
+    case llvm::Triple::XROS:
       if (triple_ref.getVendor() == llvm::Triple::Apple) {
         ObjectFile *exe_objfile = exe_module->GetObjectFile();
         if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index ad72b3d121e673..7bb44984185139 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1180,7 +1180,8 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
 static void ParseOSType(llvm::StringRef value, std::string &os_name,
                         std::string &environment) {
   if (value.equals("iossimulator") || value.equals("tvossimulator") ||
-      value.equals("watchossimulator")) {
+      value.equals("watchossimulator") || value.equals("xrossimulator") ||
+      value.equals("visionossimulator")) {
     environment = "simulator";
     os_name = value.drop_back(environment.size()).str();
   } else if (value.equals("maccatalyst")) {
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index dbceaf0ed4f441..a97e51cc7b7d0a 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -61,6 +61,7 @@ SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
       case llvm::Triple::IOS:
       case llvm::Triple::TvOS:
       case llvm::Triple::WatchOS:
+      case llvm::Triple::XROS:
       // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
         create = triple_ref.getVendor() == llvm::Triple::Apple;
         break;
diff --git a/lldb/source/Utility/XcodeSDK.cpp b/lldb/source/Utility/XcodeSDK.cpp
index d744336373b23b..712d611db28f83 100644
--- a/lldb/source/Utility/XcodeSDK.cpp
+++ b/lldb/source/Utility/XcodeSDK.cpp
@@ -34,6 +34,10 @@ static llvm::StringRef GetName(XcodeSDK::Type type) {
     return "WatchSimulator";
   case XcodeSDK::watchOS:
     return "WatchOS";
+  case XcodeSDK::XRSimulator:
+    return "XRSimulator";
+  case XcodeSDK::XROS:
+    return "XROS";
   case XcodeSDK::bridgeOS:
     return "bridgeOS";
   case XcodeSDK::Linux:
@@ -75,6 +79,10 @@ static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) {
     return XcodeSDK::WatchSimulator;
   if (name.consume_front("WatchOS"))
     return XcodeSDK::watchOS;
+  if (name.consume_front("XRSimulator"))
+    return XcodeSDK::XRSimulator;
+  if (name.consume_front("XROS"))
+    return XcodeSDK::XROS;
   if (name.consume_front("bridgeOS"))
     return XcodeSDK::bridgeOS;
   if (name.consume_front("Linux"))
@@ -183,6 +191,12 @@ std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) {
   case watchOS:
     name = "watchos";
     break;
+  case XRSimulator:
+    name = "xrsimulator";
+    break;
+  case XROS:
+    name = "xros";
+    break;
   case bridgeOS:
     name = "bridgeos";
     break;
@@ -212,6 +226,9 @@ bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type,
   case Type::watchOS:
   case Type::WatchSimulator:
     return version >= llvm::VersionTuple(6);
+  case Type::XROS:
+  case Type::XRSimulator:
+    return true;
   default:
     return false;
   }
@@ -233,6 +250,8 @@ bool XcodeSDK::SupportsSwift() const {
   case Type::WatchSimulator:
   case Type::watchOS:
     return info.version.empty() || info.version >= llvm::VersionTuple(2);
+  case Type::XROS:
+  case Type::XRSimulator:
   case Type::Linux:
     return true;
   default:
@@ -276,6 +295,10 @@ XcodeSDK::Type XcodeSDK::GetSDKTypeForTriple(const llvm::Triple &triple) {
     if (triple.getEnvironment() == Triple::Simulator)
       return XcodeSDK::WatchSimulator;
     return XcodeSDK::watchOS;
+  case Triple::XROS:
+    if (triple.getEnvironment() == Triple::Simulator)
+      return XcodeSDK::XRSimulator;
+    return XcodeSDK::XROS;
   case Triple::Linux:
     return XcodeSDK::Linux;
   default:
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
index 93b976127ba45c..3a4dfb9ea6ea22 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.mm
@@ -72,6 +72,14 @@
 #define PLATFORM_DRIVERKIT 10
 #endif
 
+#ifndef PLATFORM_XROS
+#define PLATFORM_XROS 11
+#endif
+
+#ifndef PLATFORM_XR_SIMULATOR
+#define PLATFORM_XR_SIMULATOR 12
+#endif
+
 #ifdef WITH_SPRINGBOARD
 
 #include <CoreFoundation/CoreFoundation.h>
@@ -746,6 +754,10 @@ static bool FBSAddEventDataToOptions(NSMutableDictionary *options,
     return "bridgeos";
   case PLATFORM_DRIVERKIT:
     return "driverkit";
+  case PLATFORM_XROS:
+    return "xros";
+  case PLATFORM_XR_SIMULATOR:
+    return "xrossimulator";
   default:
     DNBLogError("Unknown platform %u found for one binary", platform);
     return std::nullopt;
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 4e9086b0411f2d..224ed033fc4217 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -3565,10 +3565,11 @@ rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) {
   bool enable_compression = false;
   (void)enable_compression;
 
-#if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1) \
-    || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) \
-    || (defined (TARGET_OS_TV) && TARGET_OS_TV == 1) \
-    || (defined (TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1)
+#if (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1) ||                      \
+    (defined(TARGET_OS_IOS) && TARGET_OS_IOS == 1) ||                          \
+    (defined(TARGET_OS_TV) && TARGET_OS_TV == 1) ||                            \
+    (defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1) ||                    \
+    (defined(TARGET_OS_XR) && TARGET_OS_XR == 1)
   enable_compression = true;
 #endif
 
@@ -4866,6 +4867,8 @@ rnb_err_t RNBRemote::HandlePacket_qHostInfo(const char *p) {
     strm << "ostype:bridgeos;";
 #elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1
     strm << "ostype:macosx;";
+#elif defined(TARGET_OS_XR) && TARGET_OS_XR == 1
+    strm << "ostype:xros;";
 #else
     strm << "ostype:ios;";
 #endif
diff --git a/lldb/unittests/Utility/XcodeSDKTest.cpp b/lldb/unittests/Utility/XcodeSDKTest.cpp
index 88371a48a8b18b..8bf7ee1be1dba7 100644
--- a/lldb/unittests/Utility/XcodeSDKTest.cpp
+++ b/lldb/unittests/Utility/XcodeSDKTest.cpp
@@ -27,6 +27,8 @@ TEST(XcodeSDKTest, ParseTest) {
   EXPECT_EQ(XcodeSDK("AppleTVOS.sdk").GetType(), XcodeSDK::AppleTVOS);
   EXPECT_EQ(XcodeSDK("WatchSimulator.sdk").GetType(), XcodeSDK::WatchSimulator);
   EXPECT_EQ(XcodeSDK("WatchOS.sdk").GetType(), XcodeSDK::watchOS);
+  EXPECT_EQ(XcodeSDK("XRSimulator.sdk").GetType(), XcodeSDK::XRSimulator);
+  EXPECT_EQ(XcodeSDK("XROS.sdk").GetType(), XcodeSDK::XROS);
   EXPECT_EQ(XcodeSDK("Linux.sdk").GetType(), XcodeSDK::Linux);
   EXPECT_EQ(XcodeSDK("MacOSX.sdk").GetVersion(), llvm::VersionTuple());
   EXPECT_EQ(XcodeSDK("MacOSX10.9.sdk").GetVersion(), llvm::VersionTuple(10, 9));
@@ -127,6 +129,14 @@ TEST(XcodeSDKTest, GetCanonicalNameAndConstruct) {
   EXPECT_EQ("watchos", XcodeSDK::GetCanonicalName(info));
   EXPECT_EQ(XcodeSDK(info).Parse(), info);
 
+  info.type = XcodeSDK::Type::XRSimulator;
+  EXPECT_EQ("xrsimulator", XcodeSDK::GetCanonicalName(info));
+  EXPECT_EQ(XcodeSDK(info).Parse(), info);
+
+  info.type = XcodeSDK::Type::XROS;
+  EXPECT_EQ("xros", XcodeSDK::GetCanonicalName(info));
+  EXPECT_EQ(XcodeSDK(info).Parse(), info);
+
   info.type = XcodeSDK::Type::Linux;
   EXPECT_EQ("linux", XcodeSDK::GetCanonicalName(info));
   EXPECT_EQ(XcodeSDK(info).Parse(), info);
@@ -164,6 +174,13 @@ TEST(XcodeSDKTest, GetCanonicalNameAndConstruct) {
   EXPECT_EQ("watchos.internal", XcodeSDK::GetCanonicalName(info));
   EXPECT_EQ(XcodeSDK(info).Parse(), info);
 
+  info.type = XcodeSDK::Type::XRSimulator;
+  EXPECT_EQ("xrsimulator.internal", XcodeSDK::GetCanonicalName(info));
+  EXPECT_EQ(XcodeSDK(info).Parse(), info);
+
+  info.type = XcodeSDK::Type::XROS;
+  EXPECT_EQ("xros.internal", XcodeSDK::GetCanonicalName(info));
+  EXPECT_EQ(XcodeSDK(info).Parse(), info);
   info.type = XcodeSDK::Type::MacOSX;
   info.version = llvm::VersionTuple(10, 9);
   EXPECT_EQ("macosx10.9.internal", XcodeSDK::GetCanonicalName(info));
@@ -199,6 +216,11 @@ TEST(XcodeSDKTest, GetSDKTypeForTriple) {
             XcodeSDK::Type::WatchSimulator);
   EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64-apple-watchos")),
             XcodeSDK::Type::watchOS);
+  EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(
+                llvm::Triple("arm64e-apple-xros-simulator")),
+            XcodeSDK::Type::XRSimulator);
+  EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("arm64e-apple-xros")),
+            XcodeSDK::Type::XROS);
   EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("x86_64-unknown-linux")),
             XcodeSDK::Type::Linux);
   EXPECT_EQ(XcodeSDK::GetSDKTypeForTriple(llvm::Triple("i386-unknown-netbsd")),

>From 868dd57be1d046d2f66823662bca10323aec05a3 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Tue, 16 Jan 2024 20:36:47 -0800
Subject: [PATCH 2/2] [clang] Upstream XROS support in Clang

Upstream XROS support in the clang frontend and driver.
---
 clang/lib/Basic/Targets/OSTargets.h           |  6 +-
 clang/lib/CodeGen/CGObjC.cpp                  |  5 ++
 clang/lib/Driver/Driver.cpp                   |  1 +
 clang/lib/Driver/ToolChains/Arch/AArch64.cpp  |  5 ++
 clang/lib/Driver/ToolChains/Arch/ARM.cpp      |  5 +-
 clang/lib/Driver/ToolChains/Darwin.cpp        | 56 ++++++++++++++++++-
 clang/lib/Driver/ToolChains/Darwin.h          | 14 ++++-
 .../Checkers/CheckSecuritySyntaxOnly.cpp      |  2 +
 clang/test/Driver/xros-driver.c               | 41 ++++++++++++++
 clang/test/Frontend/xros-version.c            |  3 +
 10 files changed, 131 insertions(+), 7 deletions(-)
 create mode 100644 clang/test/Driver/xros-driver.c
 create mode 100644 clang/test/Frontend/xros-version.c

diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index 342af4bbc42b7b..4366c1149e4053 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -74,7 +74,8 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> {
         this->TLSSupported = !Triple.isOSVersionLT(3);
     } else if (Triple.isDriverKit()) {
       // No TLS on DriverKit.
-    }
+    } else if (Triple.isXROS())
+      this->TLSSupported = true;
 
     this->MCountName = "\01mcount";
   }
@@ -109,6 +110,9 @@ class LLVM_LIBRARY_VISIBILITY DarwinTargetInfo : public OSTargetInfo<Target> {
     case llvm::Triple::WatchOS: // Earliest supporting version is 5.0.0.
       MinVersion = llvm::VersionTuple(5U);
       break;
+    case llvm::Triple::XROS:
+      MinVersion = llvm::VersionTuple(0);
+      break;
     default:
       // Conservatively return 8 bytes if OS is unknown.
       return 64;
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index acc85165a470be..03fc0ec7ff54e1 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -3941,6 +3941,8 @@ static unsigned getBaseMachOPlatformID(const llvm::Triple &TT) {
     return llvm::MachO::PLATFORM_TVOS;
   case llvm::Triple::WatchOS:
     return llvm::MachO::PLATFORM_WATCHOS;
+  case llvm::Triple::XROS:
+    return llvm::MachO::PLATFORM_XROS;
   case llvm::Triple::DriverKit:
     return llvm::MachO::PLATFORM_DRIVERKIT;
   default:
@@ -4024,6 +4026,9 @@ static bool isFoundationNeededForDarwinAvailabilityCheck(
   case llvm::Triple::MacOSX:
     FoundationDroppedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/15);
     break;
+  case llvm::Triple::XROS:
+    // XROS doesn't need Foundation.
+    return false;
   case llvm::Triple::DriverKit:
     // DriverKit doesn't need Foundation.
     return false;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1889ea28079df1..35d563b9a87fac 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6213,6 +6213,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
     case llvm::Triple::IOS:
     case llvm::Triple::TvOS:
     case llvm::Triple::WatchOS:
+    case llvm::Triple::XROS:
     case llvm::Triple::DriverKit:
       TC = std::make_unique<toolchains::DarwinClang>(*this, Target, Args);
       break;
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 912df79417ae21..e73ffcfa4e343a 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -53,6 +53,11 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
     return "apple-m1";
   }
 
+  if (Triple.isXROS()) {
+    // The xrOS simulator runs on M1 as well, it should have been covered above.
+    assert(!Triple.isSimulatorEnvironment() && "xrossim should be mac-like");
+    return "apple-a12";
+  }
   // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
   if (Triple.isArm64e())
     return "apple-a12";
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index 25470db2b6cebd..e6ee2f88a84edf 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -367,6 +367,7 @@ arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) {
   case llvm::Triple::IOS:
   case llvm::Triple::TvOS:
   case llvm::Triple::DriverKit:
+  case llvm::Triple::XROS:
     // Darwin defaults to "softfp" for v6 and v7.
     if (Triple.isWatchABI())
       return FloatABI::Hard;
@@ -836,8 +837,8 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
     if (A->getOption().matches(options::OPT_mlong_calls))
       Features.push_back("+long-calls");
   } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
-             !Triple.isWatchOS()) {
-      Features.push_back("+long-calls");
+             !Triple.isWatchOS() && !Triple.isXROS()) {
+    Features.push_back("+long-calls");
   }
 
   // Generate execute-only output (no data access to code sections).
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 8f24e5287e198c..a4985f10117b94 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -954,6 +954,13 @@ ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
     return ObjCRuntime(ObjCRuntime::WatchOS, TargetVersion);
   if (isTargetIOSBased())
     return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
+  if (isTargetXROS()) {
+    // XROS uses the iOS runtime.
+    auto T = llvm::Triple(Twine("arm64-apple-") +
+                          llvm::Triple::getOSTypeName(llvm::Triple::XROS) +
+                          TargetVersion.getAsString());
+    return ObjCRuntime(ObjCRuntime::iOS, T.getiOSVersion());
+  }
   if (isNonFragile)
     return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
   return ObjCRuntime(ObjCRuntime::FragileMacOSX, TargetVersion);
@@ -961,7 +968,7 @@ ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
 
 /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
 bool Darwin::hasBlocksRuntime() const {
-  if (isTargetWatchOSBased() || isTargetDriverKit())
+  if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS())
     return true;
   else if (isTargetIOSBased())
     return !isIPhoneOSVersionLT(3, 2);
@@ -1092,6 +1099,8 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
     Str += "driverkit";
   else if (isTargetIOSBased() || isTargetMacCatalyst())
     Str += "ios";
+  else if (isTargetXROS())
+    Str += llvm::Triple::getOSTypeName(llvm::Triple::XROS);
   else
     Str += "macosx";
   Str += getTripleTargetVersion().getAsString();
@@ -1174,6 +1183,8 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args,
   // ARC runtime is supported everywhere on arm64e.
   if (getTriple().isArm64e())
     return;
+  if (isTargetXROS())
+    return;
 
   ObjCRuntime runtime = getDefaultObjCRuntime(/*nonfragile*/ true);
 
@@ -1309,6 +1320,8 @@ StringRef Darwin::getPlatformFamily() const {
       return "Watch";
     case DarwinPlatformKind::DriverKit:
       return "DriverKit";
+    case DarwinPlatformKind::XROS:
+      return "XR";
   }
   llvm_unreachable("Unsupported platform");
 }
@@ -1340,6 +1353,9 @@ StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {
   case DarwinPlatformKind::WatchOS:
     return TargetEnvironment == NativeEnvironment || IgnoreSim ? "watchos"
                                                                : "watchossim";
+  case DarwinPlatformKind::XROS:
+    return TargetEnvironment == NativeEnvironment || IgnoreSim ? "xros"
+                                                               : "xrossim";
   case DarwinPlatformKind::DriverKit:
     return "driverkit";
   }
@@ -1649,6 +1665,9 @@ struct DarwinPlatform {
     case DarwinPlatformKind::WatchOS:
       Opt = options::OPT_mwatchos_version_min_EQ;
       break;
+    case DarwinPlatformKind::XROS:
+      // xrOS always explicitly provides a version in the triple.
+      return;
     case DarwinPlatformKind::DriverKit:
       // DriverKit always explicitly provides a version in the triple.
       return;
@@ -1794,6 +1813,8 @@ struct DarwinPlatform {
       return DarwinPlatformKind::TvOS;
     case llvm::Triple::WatchOS:
       return DarwinPlatformKind::WatchOS;
+    case llvm::Triple::XROS:
+      return DarwinPlatformKind::XROS;
     case llvm::Triple::DriverKit:
       return DarwinPlatformKind::DriverKit;
     default:
@@ -1975,6 +1996,10 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
       return DarwinPlatform::createFromSDK(
           Darwin::TvOS, Version,
           /*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
+    else if (SDK.starts_with("XR"))
+      return DarwinPlatform::createFromSDK(
+          Darwin::XROS, Version,
+          /*IsSimulator=*/SDK.contains("Simulator"));
     else if (SDK.starts_with("DriverKit"))
       return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version);
     return std::nullopt;
@@ -2013,6 +2038,11 @@ std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
   case llvm::Triple::WatchOS:
     OsVersion = Triple.getWatchOSVersion();
     break;
+  case llvm::Triple::XROS:
+    OsVersion = Triple.getOSVersion();
+    if (!OsVersion.getMajor())
+      OsVersion = OsVersion.withMajorReplaced(1);
+    break;
   case llvm::Triple::DriverKit:
     OsVersion = Triple.getDriverKitVersion();
     break;
@@ -2104,6 +2134,7 @@ std::optional<DarwinPlatform> getDeploymentTargetFromMTargetOSArg(
   case llvm::Triple::IOS:
   case llvm::Triple::TvOS:
   case llvm::Triple::WatchOS:
+  case llvm::Triple::XROS:
     break;
   default:
     TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
@@ -2319,6 +2350,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
         Micro >= 100)
       getDriver().Diag(diag::err_drv_invalid_version_number)
           << OSTarget->getAsString(Args, Opts);
+  } else if (Platform == XROS) {
+    if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
+                                   Micro, HadExtra) ||
+        HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 ||
+        Micro >= 100)
+      getDriver().Diag(diag::err_drv_invalid_version_number)
+          << OSTarget->getAsString(Args, Opts);
   } else
     llvm_unreachable("unknown kind of Darwin platform");
 
@@ -2641,6 +2679,10 @@ void DarwinClang::AddCCKextLibArgs(const ArgList &Args,
     llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a");
   } else if (isTargetDriverKit()) {
     // DriverKit doesn't want extra runtime support.
+  } else if (isTargetXROSDevice()) {
+    llvm::sys::path::append(
+        P, llvm::Twine("libclang_rt.cc_kext_") +
+               llvm::Triple::getOSTypeName(llvm::Triple::XROS) + ".a");
   } else {
     llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
   }
@@ -2855,6 +2897,8 @@ bool Darwin::isAlignedAllocationUnavailable() const {
   case WatchOS: // Earlier than 4.0.
     OS = llvm::Triple::WatchOS;
     break;
+  case XROS: // Always available.
+    return false;
   case DriverKit: // Always available.
     return false;
   }
@@ -2876,6 +2920,8 @@ static bool sdkSupportsBuiltinModules(const Darwin::DarwinPlatformKind &TargetPl
     return SDKVersion >= VersionTuple(99U);
   case Darwin::WatchOS:
     return SDKVersion >= VersionTuple(99U);
+  case Darwin::XROS:
+    return SDKVersion >= VersionTuple(99U);
   default:
     return true;
   }
@@ -2998,7 +3044,7 @@ Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
   // FIXME: It would be far better to avoid inserting those -static arguments,
   // but we can't check the deployment target in the translation code until
   // it is set here.
-  if (isTargetWatchOSBased() || isTargetDriverKit() ||
+  if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS() ||
       (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) {
     for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
       Arg *A = *it;
@@ -3092,6 +3138,8 @@ void Darwin::addMinVersionArgs(const ArgList &Args,
                                ArgStringList &CmdArgs) const {
   VersionTuple TargetVersion = getTripleTargetVersion();
 
+  assert(!isTargetXROS() && "xrOS always uses -platform-version");
+
   if (isTargetWatchOS())
     CmdArgs.push_back("-watchos_version_min");
   else if (isTargetWatchOSSimulator())
@@ -3151,6 +3199,8 @@ static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,
     return "tvos";
   case Darwin::WatchOS:
     return "watchos";
+  case Darwin::XROS:
+    return "xros";
   case Darwin::DriverKit:
     return "driverkit";
   }
@@ -3347,7 +3397,7 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args,
 }
 
 void Darwin::CheckObjCARC() const {
-  if (isTargetIOSBased() || isTargetWatchOSBased() ||
+  if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetXROS() ||
       (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)))
     return;
   getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 815449ae8f3792..0866725acc5c5a 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -298,6 +298,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
     TvOS,
     WatchOS,
     DriverKit,
+    XROS,
     LastDarwinPlatform = DriverKit
   };
   enum DarwinEnvironmentKind {
@@ -404,6 +405,16 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
     return isTargetIPhoneOS() || isTargetIOSSimulator();
   }
 
+  bool isTargetXROSDevice() const {
+    return TargetPlatform == XROS && TargetEnvironment == NativeEnvironment;
+  }
+
+  bool isTargetXROSSimulator() const {
+    return TargetPlatform == XROS && TargetEnvironment == Simulator;
+  }
+
+  bool isTargetXROS() const { return TargetPlatform == XROS; }
+
   bool isTargetTvOS() const {
     assert(TargetInitialized && "Target not initialized!");
     return TargetPlatform == TvOS && TargetEnvironment == NativeEnvironment;
@@ -546,7 +557,8 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
   GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
     // Stack protectors default to on for user code on 10.5,
     // and for everything in 10.6 and beyond
-    if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit())
+    if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit() ||
+        isTargetXROS())
       return LangOptions::SSPOn;
     else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6))
       return LangOptions::SSPOn;
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index ce05d2d3c90585..17af1aebd6d2a0 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -973,6 +973,8 @@ void WalkAST::checkMsg_decodeValueOfObjCType(const ObjCMessageExpr *ME) {
     if (VT < VersionTuple(11, 0))
       return;
     break;
+  case llvm::Triple::XROS:
+    break;
   default:
     return;
   }
diff --git a/clang/test/Driver/xros-driver.c b/clang/test/Driver/xros-driver.c
new file mode 100644
index 00000000000000..dd2c55ed4e70cd
--- /dev/null
+++ b/clang/test/Driver/xros-driver.c
@@ -0,0 +1,41 @@
+// RUN: %clang -target arm64-apple-xros1 -c -### %s 2>&1 | FileCheck --check-prefix=VERSION1 %s
+// RUN: %clang -target arm64-apple-xros -c -### %s 2>&1 | FileCheck --check-prefix=VERSION1 %s
+
+// RUN: %clang -target arm64-apple-xros1-simulator -c -### %s 2>&1 | FileCheck --check-prefix=VERSION1_ASi %s
+
+// RUN: not %clang -target arm64-apple-xros1000 -c -### %s 2>&1 | FileCheck --check-prefix=INVALID-VERSION %s
+
+// RUN: %clang -target arm64-apple-xros1  -### %s 2>&1 | FileCheck --check-prefix=LINK %s
+// RUN: %clang -target arm64-apple-xros1-simulator  -### %s 2>&1 | FileCheck --check-prefix=LINK-SIM %s
+
+// RUN: %clang -target arm64-apple-xros1 -c -x objective-c -fobjc-arc -### %s 2>&1 | FileCheck --check-prefix=ARC %s
+// RUN: %clang -target arm64-apple-xros -c -x objective-c -fobjc-arc -### %s 2>&1 | FileCheck --check-prefix=OBJC-RUNTIME %s
+// RUN: %clang -target arm64-apple-xros2 -c -x objective-c -fobjc-arc -### %s 2>&1 | FileCheck --check-prefix=OBJC-RUNTIME2 %s
+
+// RUN: %clang -target arm64-apple-xros1 -c -x objective-c -fobjc-arc -### %s 2>&1 | FileCheck --check-prefix=ARC %s
+// RUN: %clang -target arm64-apple-xros1-simulator -c -x objective-c -fobjc-arc -### %s 2>&1 | FileCheck --check-prefix=ARC %s
+
+// RUN: %clang -target arm64-apple-xros -c -### %s 2>&1 | FileCheck --check-prefix=SSP_ON %s
+
+// RUN: %clang -target arm64e-apple-xros -c -### %s 2>&1 | FileCheck --check-prefix=CPU-ARM64E %s
+// RUN: %clang -target arm64-apple-xros -c -### %s 2>&1 | FileCheck --check-prefix=CPU-ARM64 %s
+// RUN: %clang -target arm64-apple-xros-simulator -c -### %s 2>&1 | FileCheck --check-prefix=CPU-ARM64-SIM %s
+
+// VERSION1: "-cc1"{{.*}} "-triple" "arm64-apple-xros1.0.0"
+// VERSION1_ASi: "-cc1"{{.*}} "-triple" "arm64-apple-xros1.0.0-simulator"
+// INVALID-VERSION: error: invalid version number in
+
+// VERSION1-NOT: -faligned-alloc-unavailable
+
+// LINK: "-platform_version" "xros" "1.0.0" "1.0.0"
+// LINK-SIM: "-platform_version" "xros-simulator" "1.0.0" "1.0.0"
+
+// OBJC-RUNTIME: "-fobjc-runtime=ios-17.0.0.0"
+// OBJC-RUNTIME2: "-fobjc-runtime=ios-18.0.0.0"
+// ARC-NOT: error:
+
+// SSP_ON: "-stack-protector" "1"
+
+// CPU-ARM64E: "-cc1"{{.*}} "-triple" "arm64e-apple-xros1.0.0"{{.*}} "-target-cpu" "apple-a12"{{.*}}
+// CPU-ARM64: "-cc1"{{.*}} "-triple" "arm64-apple-xros1.0.0"{{.*}} "-target-cpu" "apple-a12"
+// CPU-ARM64-SIM: "-cc1"{{.*}} "-triple" "arm64-apple-xros1.0.0-simulator"{{.*}} "-target-cpu" "apple-m1"
diff --git a/clang/test/Frontend/xros-version.c b/clang/test/Frontend/xros-version.c
new file mode 100644
index 00000000000000..68f69f3de76337
--- /dev/null
+++ b/clang/test/Frontend/xros-version.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -triple arm64-apple-xros1 -dM -E -o - %s | FileCheck %s
+
+// CHECK: __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ 10000



More information about the cfe-commits mailing list