[clang] [llvm] [Triple] Make a target triple "os" for firmware (PR #176272)
Ian Anderson via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 30 01:56:37 PST 2026
https://github.com/ian-twilightcoder updated https://github.com/llvm/llvm-project/pull/176272
>From 8a080fc253f9f987407ef95204dc143924e7a069 Mon Sep 17 00:00:00 2001
From: Ian Anderson <iana at apple.com>
Date: Thu, 15 Jan 2026 15:13:59 -0800
Subject: [PATCH] [Triple] Make a target triple "os" for firmware
Make a Triple::OSType to represent a generic Apple firmware platform that isn't bare metal, but isn't tied to a specific hardware platform like macOS or iOS. Hook up support for the new OSType in the Darwin toolchain.
---
clang/include/clang/Basic/TargetOSMacros.def | 3 +
clang/lib/Driver/Driver.cpp | 2 +
clang/lib/Driver/ToolChains/Arch/ARM.cpp | 3 +-
clang/lib/Driver/ToolChains/Darwin.cpp | 74 ++++++++++++-------
clang/lib/Driver/ToolChains/Darwin.h | 4 +-
clang/test/Driver/darwin-fapple-link-rtlib.c | 3 +
clang/test/Driver/fdefine-target-os-macros.c | 66 +++++++++++++----
clang/test/Driver/unsupported-target-vendor.c | 60 +++++++++++++++
llvm/include/llvm/TargetParser/Triple.h | 14 +++-
llvm/lib/TargetParser/Triple.cpp | 15 ++++
llvm/unittests/TargetParser/TripleTest.cpp | 20 +++++
11 files changed, 217 insertions(+), 47 deletions(-)
create mode 100644 clang/test/Driver/unsupported-target-vendor.c
diff --git a/clang/include/clang/Basic/TargetOSMacros.def b/clang/include/clang/Basic/TargetOSMacros.def
index f4f3276ad1c256..45999b926fdc53 100644
--- a/clang/include/clang/Basic/TargetOSMacros.def
+++ b/clang/include/clang/Basic/TargetOSMacros.def
@@ -56,4 +56,7 @@ TARGET_OS(TARGET_OS_UIKITFORMAC, Triple.isMacCatalystEnvironment())
// UEFI target.
TARGET_OS(TARGET_OS_UEFI, Triple.isUEFI())
+// General targets.
+TARGET_OS(TARGET_OS_FIRMWARE, Triple.isOSFirmware())
+
#undef TARGET_OS
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index eb3f9cbea2845a..5df1a3a25b8ab5 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -7010,6 +7010,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
TC = std::make_unique<toolchains::BareMetal>(*this, Target, Args);
else if (Target.isOSBinFormatELF())
TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args);
+ else if (Target.isAppleFirmware())
+ TC = std::make_unique<toolchains::DarwinClang>(*this, Target, Args);
else if (Target.isAppleMachO())
TC = std::make_unique<toolchains::AppleMachO>(*this, Target, Args);
else if (Target.isOSBinFormatMachO())
diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index 55eb2dcf7ddf46..7d9c1f0bd3d404 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -517,7 +517,8 @@ arm::FloatABI arm::getARMFloatABI(const Driver &D, const llvm::Triple &Triple,
else
ABI = FloatABI::Soft;
- if (Triple.getOS() != llvm::Triple::UnknownOS ||
+ if (((Triple.getOS() != llvm::Triple::UnknownOS) &&
+ !Triple.isOSFirmware()) ||
!Triple.isOSBinFormatMachO())
D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
}
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index c2dea22670df45..d65cec759f1bc2 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -78,9 +78,13 @@ void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str,
if (Arch != llvm::Triple::UnknownArch)
T.setArchName(Str);
- if (ArchKind == llvm::ARM::ArchKind::ARMV6M ||
- ArchKind == llvm::ARM::ArchKind::ARMV7M ||
- ArchKind == llvm::ARM::ArchKind::ARMV7EM) {
+ // Standalone/bare metal compiles often unintentionally come out as
+ // armv6m-apple-ios (-target not specified, or set from Xcode). Change these
+ // cases to armv6m-unknown-macho to better reflect intent.
+ if ((T.getOS() != llvm::Triple::Firmware) &&
+ (ArchKind == llvm::ARM::ArchKind::ARMV6M ||
+ ArchKind == llvm::ARM::ArchKind::ARMV7M ||
+ ArchKind == llvm::ARM::ArchKind::ARMV7EM)) {
// Don't reject these -version-min= if we have the appropriate triple.
if (T.getOS() == llvm::Triple::IOS)
for (Arg *A : Args.filtered(options::OPT_mios_version_min_EQ))
@@ -590,8 +594,9 @@ 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();
+ // Newer triples always use -platform-version.
+ llvm::Triple Triple = getToolChain().getTriple();
+ bool UsePlatformVersion = Triple.isXROS() || Triple.isOSFirmware();
// I'm not sure why this particular decomposition exists in gcc, but
// we follow suite for ease of comparison.
@@ -1000,6 +1005,8 @@ ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
bool Darwin::hasBlocksRuntime() const {
if (isTargetWatchOSBased() || isTargetDriverKit() || isTargetXROS())
return true;
+ else if (isTargetFirmware())
+ return false;
else if (isTargetIOSBased())
return !isIPhoneOSVersionLT(3, 2);
else {
@@ -1172,6 +1179,8 @@ std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
Str += "ios";
else if (isTargetXROS())
Str += llvm::Triple::getOSTypeName(llvm::Triple::XROS);
+ else if (isTargetFirmware())
+ Str += llvm::Triple::getOSTypeName(llvm::Triple::Firmware);
else
Str += "macosx";
Str += getTripleTargetVersion().getAsString();
@@ -1401,6 +1410,10 @@ std::string MachO::getCompilerRT(const ArgList &Args, StringRef Component,
std::string Darwin::getCompilerRT(const ArgList &Args, StringRef Component,
FileType Type, bool IsFortran) const {
+ // Firmware uses the "bare metal" RT.
+ if (TargetPlatform == DarwinPlatformKind::Firmware)
+ return MachO::getCompilerRT(Args, Component, Type, IsFortran);
+
assert(Type != ToolChain::FT_Object &&
"it doesn't make sense to ask for the compiler-rt library name as an "
"object file");
@@ -1450,6 +1463,9 @@ StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {
: "xrossim";
case DarwinPlatformKind::DriverKit:
return "driverkit";
+
+ case DarwinPlatformKind::Firmware:
+ break;
}
llvm_unreachable("Unsupported platform");
}
@@ -1550,6 +1566,10 @@ ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(
void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs,
bool ForceLinkBuiltinRT) const {
+ // Firmware uses the "bare metal" runtime lib.
+ if (TargetPlatform == DarwinPlatformKind::Firmware)
+ return MachO::AddLinkRuntimeLibArgs(Args, CmdArgs, ForceLinkBuiltinRT);
+
// Call once to ensure diagnostic is printed if wrong value was specified
GetRuntimeLibType(Args);
@@ -1795,11 +1815,8 @@ 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.
+ default:
+ // New platforms always explicitly provide a version in the triple.
return;
}
Arg = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersionStr);
@@ -1990,6 +2007,8 @@ struct DarwinPlatform {
return DarwinPlatformKind::XROS;
case llvm::Triple::DriverKit:
return DarwinPlatformKind::DriverKit;
+ case llvm::Triple::Firmware:
+ return DarwinPlatformKind::Firmware;
default:
llvm_unreachable("Unable to infer Darwin variant");
}
@@ -2009,6 +2028,8 @@ struct DarwinPlatform {
return llvm::Triple::DriverKit;
case DarwinPlatformKind::XROS:
return llvm::Triple::XROS;
+ case DarwinPlatformKind::Firmware:
+ return llvm::Triple::Firmware;
}
llvm_unreachable("Unknown DarwinPlatformKind enum");
}
@@ -2172,7 +2193,6 @@ getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
std::optional<DarwinPlatform>
getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
const llvm::Triple &Triple) {
- std::string Targets[Darwin::LastDarwinPlatform + 1];
const char *EnvVars[] = {
"MACOSX_DEPLOYMENT_TARGET",
"IPHONEOS_DEPLOYMENT_TARGET",
@@ -2181,8 +2201,7 @@ getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
"DRIVERKIT_DEPLOYMENT_TARGET",
"XROS_DEPLOYMENT_TARGET"
};
- static_assert(std::size(EnvVars) == Darwin::LastDarwinPlatform + 1,
- "Missing platform");
+ std::string Targets[std::size(EnvVars)];
for (const auto &I : llvm::enumerate(llvm::ArrayRef(EnvVars))) {
if (char *Env = ::getenv(I.value()))
Targets[I.index()] = Env;
@@ -2301,16 +2320,13 @@ VersionTuple getInferredOSVersion(llvm::Triple::OSType OS,
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;
default:
- llvm_unreachable("Unexpected OS type");
+ OsVersion = Triple.getOSVersion();
+ if (!OsVersion.getMajor())
+ OsVersion = OsVersion.withMajorReplaced(1);
break;
}
return OsVersion;
@@ -2644,15 +2660,14 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
<< PlatformAndVersion->getAsString(Args, Opts);
- } else if (Platform == XROS) {
+ } else {
if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
HadExtra) ||
HadExtra || Major < 1 || Major >= MajorVersionLimit || Minor >= 100 ||
Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
<< PlatformAndVersion->getAsString(Args, Opts);
- } else
- llvm_unreachable("unknown kind of Darwin platform");
+ }
DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment();
// Recognize iOS targets with an x86 architecture as the iOS simulator.
@@ -3181,9 +3196,7 @@ 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.
+ default: // Always available on newer platforms.
return false;
}
@@ -3266,9 +3279,8 @@ bool Darwin::isSizedDeallocationUnavailable() const {
case WatchOS: // Earlier than 3.0.
OS = llvm::Triple::WatchOS;
break;
- case DriverKit:
- case XROS:
- // Always available.
+ default:
+ // Always available on newer platforms.
return false;
}
@@ -3649,12 +3661,18 @@ static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,
return "xros";
case Darwin::DriverKit:
return "driverkit";
+ default:
+ break;
}
llvm_unreachable("invalid platform");
}
void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const {
+ // Firmware doesn't use -platform_version.
+ if (TargetPlatform == DarwinPlatformKind::Firmware)
+ return MachO::addPlatformVersionArgs(Args, CmdArgs);
+
auto EmitPlatformVersionArg =
[&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform,
Darwin::DarwinEnvironmentKind TargetEnvironment,
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 05762596fefbae..14a80c973485a8 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -363,7 +363,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
WatchOS,
DriverKit,
XROS,
- LastDarwinPlatform = XROS
+ Firmware,
};
enum DarwinEnvironmentKind {
NativeEnvironment,
@@ -520,6 +520,8 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
return TargetPlatform == DriverKit;
}
+ bool isTargetFirmware() const { return TargetPlatform == Firmware; }
+
bool isTargetMacCatalyst() const {
return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst;
}
diff --git a/clang/test/Driver/darwin-fapple-link-rtlib.c b/clang/test/Driver/darwin-fapple-link-rtlib.c
index 394f583331d74d..4861304b3fc99b 100644
--- a/clang/test/Driver/darwin-fapple-link-rtlib.c
+++ b/clang/test/Driver/darwin-fapple-link-rtlib.c
@@ -1,6 +1,9 @@
// RUN: %clang -target arm64-apple-ios12.0 %s -nostdlib -fapple-link-rtlib -resource-dir=%S/Inputs/resource_dir -### 2>&1 | FileCheck %s
// RUN: %clang -target arm64-apple-ios12.0 %s -static -fapple-link-rtlib -resource-dir=%S/Inputs/resource_dir -### 2>&1 | FileCheck %s
// RUN: %clang -target arm64-apple-ios12.0 %s -fapple-link-rtlib -resource-dir=%S/Inputs/resource_dir -### 2>&1 | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang -target arm64-apple-firmware %s -static -fapple-link-rtlib -resource-dir=%S/Inputs/resource_dir -### 2>&1 | FileCheck %s --check-prefix=FIRMWARE
// CHECK-NOT: "-lSystem"
// DEFAULT: "-lSystem"
// CHECK: libclang_rt.ios.a
+// FIRMWARE-NOT: "-lSystem"
+// FIRMWARE: libclang_rt.soft_static.a
diff --git a/clang/test/Driver/fdefine-target-os-macros.c b/clang/test/Driver/fdefine-target-os-macros.c
index a4de51e8e7244b..07755d01f9a527 100644
--- a/clang/test/Driver/fdefine-target-os-macros.c
+++ b/clang/test/Driver/fdefine-target-os-macros.c
@@ -19,7 +19,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-ios %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -35,7 +36,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-ios-macabi %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -51,7 +53,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-ios-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -67,7 +70,8 @@
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-tvos %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -83,7 +87,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-tvos-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -99,7 +104,8 @@
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-watchos %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -115,7 +121,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-watchos-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -131,7 +138,8 @@
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-xros %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -147,7 +155,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-xros-simulator %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -163,7 +172,8 @@
// RUN: -DSIMULATOR=1 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=arm64-apple-driverkit %s 2>&1 \
// RUN: | FileCheck %s -DMAC=1 \
@@ -179,7 +189,25 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
+
+// RUN: %clang -dM -E --target=arm64-apple-firmware %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DVISION=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=1
// RUN: %clang -dM -E --target=x86_64-pc-linux-gnu \
// RUN: -fdefine-target-os-macros %s 2>&1 \
@@ -196,7 +224,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=1 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=x86_64-pc-win32 \
// RUN: -fdefine-target-os-macros %s 2>&1 \
@@ -213,7 +242,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=1 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=x86_64-pc-windows-gnu \
// RUN: -fdefine-target-os-macros %s 2>&1 \
@@ -230,7 +260,8 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=1 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=0
+// RUN: -DUNIX=0 \
+// RUN: -DFIRMWARE=0
// RUN: %clang -dM -E --target=sparc-none-solaris \
// RUN: -fdefine-target-os-macros %s 2>&1 \
@@ -247,7 +278,11 @@
// RUN: -DSIMULATOR=0 \
// RUN: -DWINDOWS=0 \
// RUN: -DLINUX=0 \
-// RUN: -DUNIX=1
+// RUN: -DUNIX=1 \
+// RUN: -DFIRMWARE=0
+
+// If the firmware OS was valid for a non-Apple vendor,
+// it would be TARGET_OS_MAC=0, TARGET_OS_FIRMWARE=1.
// RUN: %clang -dM -E --target=arm64-apple-macos \
// RUN: -fno-define-target-os-macros %s 2>&1 \
@@ -285,3 +320,4 @@
// CHECK-DAG: #define TARGET_OS_WINDOWS [[WINDOWS]]
// CHECK-DAG: #define TARGET_OS_LINUX [[LINUX]]
// CHECK-DAG: #define TARGET_OS_UNIX [[UNIX]]
+// CHECK-DAG: #define TARGET_OS_FIRMWARE [[FIRMWARE]]
diff --git a/clang/test/Driver/unsupported-target-vendor.c b/clang/test/Driver/unsupported-target-vendor.c
new file mode 100644
index 00000000000000..a4c5f999a03977
--- /dev/null
+++ b/clang/test/Driver/unsupported-target-vendor.c
@@ -0,0 +1,60 @@
+// Tests that clang does not crash with invalid vendors in target triples.
+//
+// RUN: %clang --target=arm-apple-firmware -E %s 2>&1 | FileCheck -check-prefix CHECK_APPLE %s
+// RUN: %clang_cl --target=arm-apple-firmware -E %s 2>&1 | FileCheck -check-prefix CHECK_APPLE %s
+
+// CHECK_APPLE-NOT: LLVM ERROR: the firmware target os is only supported for the apple vendor
+
+
+// RUN: not %clang --target=arm-none-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-none-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-unknown-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-unknown-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-pc-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-pc-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-scei-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-scei-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-sie-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-sie-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-fsl-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-fsl-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-ibm-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-ibm-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-img-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-img-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-mti-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-mti-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-nvidia-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-nvidia-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-csr-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-csr-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-amd-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-amd-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-mesa-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-mesa-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-suse-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-suse-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-oe-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-oe-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-intel-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-intel-firmware -E %s 2>&1 | FileCheck %s
+
+// RUN: not %clang --target=arm-meta-firmware -E %s 2>&1 | FileCheck %s
+// RUN: not %clang_cl --target=arm-meta-firmware -E %s 2>&1 | FileCheck %s
+
+// CHECK: LLVM ERROR: the firmware target os is only supported for the apple vendor
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8559d7b088ee1a..afbf464310a8d8 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -253,7 +253,8 @@ class Triple {
Vulkan, // Vulkan SPIR-V
CheriotRTOS,
ChipStar,
- LastOSType = ChipStar
+ Firmware,
+ LastOSType = Firmware
};
enum EnvironmentType {
UnknownEnvironment,
@@ -627,11 +628,18 @@ class Triple {
return (getVendor() == Triple::Apple) && isOSBinFormatMachO();
}
+ /// Is this an Apple firmware triple.
+ bool isAppleFirmware() const {
+ return (getVendor() == Triple::Apple) && isOSFirmware();
+ }
+
/// Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, DriverKit, XROS, or
/// bridgeOS).
bool isOSDarwin() const {
return isMacOSX() || isiOS() || isWatchOS() || isDriverKit() || isXROS() ||
- isBridgeOS();
+ isBridgeOS() || isAppleFirmware();
+ // Apple firmware isn't necessarily a Darwin based OS, but for most intents
+ // and purposes it can be treated like a Darwin OS in the compiler.
}
bool isSimulatorEnvironment() const {
@@ -893,6 +901,8 @@ class Triple {
bool isOSManagarm() const { return getOS() == Triple::Managarm; }
+ bool isOSFirmware() const { return getOS() == Triple::Firmware; }
+
bool isShaderStageEnvironment() const {
EnvironmentType Env = getEnvironment();
return Env == Triple::Pixel || Env == Triple::Vertex ||
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index e6a9eedab59543..a3ea5d823033d7 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -343,6 +343,8 @@ StringRef Triple::getOSTypeName(OSType Kind) {
return "cheriotrtos";
case ChipStar:
return "chipstar";
+ case Firmware:
+ return "firmware";
}
llvm_unreachable("Invalid OSType");
@@ -757,6 +759,7 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("vulkan", Triple::Vulkan)
.StartsWith("cheriotrtos", Triple::CheriotRTOS)
.StartsWith("chipstar", Triple::ChipStar)
+ .StartsWith("firmware", Triple::Firmware)
.Default(Triple::UnknownOS);
}
@@ -1395,6 +1398,12 @@ std::string Triple::normalize(StringRef Str, CanonicalForm Form) {
}
}
+ // Currently the firmware OS is an Apple specific concept.
+ if ((Components.size() > 2) && (Components[2] == "firmware") &&
+ (Components[1] != "apple"))
+ llvm::reportFatalUsageError(
+ "the firmware target os is only supported for the apple vendor");
+
// Canonicalize the components if necessary.
switch (Form) {
case CanonicalForm::ANY:
@@ -1528,6 +1537,8 @@ bool Triple::getMacOSXVersion(VersionTuple &Version) const {
llvm_unreachable("OSX version isn't relevant for xrOS");
case DriverKit:
llvm_unreachable("OSX version isn't relevant for DriverKit");
+ case Firmware:
+ llvm_unreachable("OSX version isn't relevant for Firmware");
}
return true;
}
@@ -1578,6 +1589,8 @@ VersionTuple Triple::getiOSVersion() const {
llvm_unreachable("conflicting triple info");
case DriverKit:
llvm_unreachable("DriverKit doesn't have an iOS version");
+ case Firmware:
+ llvm_unreachable("iOS version isn't relevant for Firmware");
}
}
@@ -1603,6 +1616,8 @@ VersionTuple Triple::getWatchOSVersion() const {
llvm_unreachable("watchOS version isn't relevant for xrOS");
case DriverKit:
llvm_unreachable("DriverKit doesn't have a WatchOS version");
+ case Firmware:
+ llvm_unreachable("watchOS version isn't relevant for Firmware");
}
}
diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index 762b464cfec5bd..7070193c0a1296 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -1748,6 +1748,26 @@ TEST(TripleTest, Normalization) {
Triple::normalize("wasm32-wasi")); // wasm32-unknown-wasi
EXPECT_EQ("wasm64-unknown-wasi",
Triple::normalize("wasm64-wasi")); // wasm64-unknown-wasi
+
+ // Firmware should only be allowed for the Apple vendor
+ EXPECT_DEATH(Triple::normalize("arm-none-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-unknown-firmware"), "");
+ EXPECT_EQ("arm-apple-firmware", Triple::normalize("arm-apple-firmware"));
+ EXPECT_DEATH(Triple::normalize("arm-pc-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-scei-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-sie-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-fsl-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-ibm-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-img-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-mti-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-nvidia-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-csr-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-amd-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-mesa-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-suse-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-oe-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-intel-firmware"), "");
+ EXPECT_DEATH(Triple::normalize("arm-meta-firmware"), "");
}
TEST(TripleTest, MutateName) {
More information about the cfe-commits
mailing list