Skip to content

[clang] Upstream XROS support in Clang #78392

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion clang/lib/Basic/Targets/OSTargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CGObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Driver/ToolChains/Arch/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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).
Expand Down
67 changes: 61 additions & 6 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -954,14 +959,21 @@ 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);
}

/// 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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -1309,6 +1325,8 @@ StringRef Darwin::getPlatformFamily() const {
return "Watch";
case DarwinPlatformKind::DriverKit:
return "DriverKit";
case DarwinPlatformKind::XROS:
return "XR";
}
llvm_unreachable("Unsupported platform");
}
Expand Down Expand Up @@ -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";
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2104,6 +2139,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)
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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";
}
Expand Down Expand Up @@ -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);
Expand Down
16 changes: 14 additions & 2 deletions clang/lib/Driver/ToolChains/Darwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand Down Expand Up @@ -298,6 +298,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
TvOS,
WatchOS,
DriverKit,
XROS,
LastDarwinPlatform = DriverKit
};
enum DarwinEnvironmentKind {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
41 changes: 41 additions & 0 deletions clang/test/Driver/xros-driver.c
Original file line number Diff line number Diff line change
@@ -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"
3 changes: 3 additions & 0 deletions clang/test/Frontend/xros-version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// RUN: %clang_cc1 -triple arm64-apple-xros1 -dM -E -o - %s | FileCheck %s

// CHECK: __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ 10000