diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 342af4bbc42b7..4366c1149e405 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 { 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 { 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 acc85165a470b..03fc0ec7ff54e 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 1889ea28079df..35d563b9a87fa 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(*this, Target, Args); break; diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 85f053dc8b6ea..0cf96bb5c9cb0 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 25470db2b6ceb..e6ee2f88a84ed 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 8f24e5287e198..9050c545cf544 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -219,7 +219,8 @@ static bool shouldLinkerNotDedup(bool IsLinkerOnlyAction, const ArgList &Args) { void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs, const InputInfoList &Inputs, - VersionTuple Version, bool LinkerIsLLD) const { + VersionTuple Version, bool LinkerIsLLD, + bool UsePlatformVersion) const { const Driver &D = getToolChain().getDriver(); const toolchains::MachO &MachOTC = getMachOToolChain(); @@ -355,7 +356,7 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, Args.AddAllArgs(CmdArgs, options::OPT_init); // Add the deployment target. - if (Version >= VersionTuple(520) || LinkerIsLLD) + if (Version >= VersionTuple(520) || LinkerIsLLD || UsePlatformVersion) MachOTC.addPlatformVersionArgs(Args, CmdArgs); else MachOTC.addMinVersionArgs(Args, CmdArgs); @@ -596,9 +597,13 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath(&LinkerIsLLD)); + // xrOS always uses -platform-version. + bool UsePlatformVersion = getToolChain().getTriple().isXROS(); + // I'm not sure why this particular decomposition exists in gcc, but // we follow suite for ease of comparison. - AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD); + AddLinkArgs(C, Args, CmdArgs, Inputs, Version, LinkerIsLLD, + UsePlatformVersion); if (willEmitRemarks(Args) && checkRemarksOptions(getToolChain().getDriver(), Args, @@ -954,6 +959,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 +973,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 +1104,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 +1188,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 +1325,8 @@ StringRef Darwin::getPlatformFamily() const { return "Watch"; case DarwinPlatformKind::DriverKit: return "DriverKit"; + case DarwinPlatformKind::XROS: + return "XR"; } llvm_unreachable("Unsupported platform"); } @@ -1340,6 +1358,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 +1670,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 +1818,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 +2001,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 +2043,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 +2139,7 @@ std::optional 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 +2355,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 +2684,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 +2902,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 +2925,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 +3049,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 +3143,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 +3204,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 +3402,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 815449ae8f379..fda3b1a3639a8 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -65,7 +65,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public MachOTool { void AddLinkArgs(Compilation &C, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfoList &Inputs, VersionTuple Version, - bool LinkerIsLLD) const; + bool LinkerIsLLD, bool UsePlatformVersion) const; public: Linker(const ToolChain &TC) : MachOTool("darwin::Linker", "linker", TC) {} @@ -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 ce05d2d3c9058..17af1aebd6d2a 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 0000000000000..dd2c55ed4e70c --- /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 0000000000000..68f69f3de7633 --- /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