Skip to content

Commit

Permalink
[clang] Upstream XROS support in Clang (#78392)
Browse files Browse the repository at this point in the history
Upstream XROS support in the clang frontend and driver.
  • Loading branch information
JDevlieghere committed Jan 18, 2024
1 parent bd9e145 commit a4fe6a1
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 11 deletions.
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

0 comments on commit a4fe6a1

Please sign in to comment.