[clang] [llvm] [Triple] Make an target triple "os" for firmware (PR #176272)
Ian Anderson via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 26 00:35:29 PST 2026
https://github.com/ian-twilightcoder updated https://github.com/llvm/llvm-project/pull/176272
>From ab72e1913660e3f18bf5afdf7eea8690bef54dcb 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 an 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 | 6 +
clang/lib/Driver/ToolChains/Arch/ARM.cpp | 3 +-
clang/lib/Driver/ToolChains/Darwin.cpp | 104 ++++++++++-------
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 | 105 ++++++++++++++++++
llvm/include/llvm/TargetParser/Triple.h | 14 ++-
llvm/lib/TargetParser/Triple.cpp | 9 ++
10 files changed, 257 insertions(+), 60 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 f4f3276ad1c25..45999b926fdc5 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 eb3f9cbea2845..41353b77a1f31 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -681,6 +681,10 @@ static llvm::Triple computeTargetTriple(const Driver &D,
if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64)
D.Diag(diag::err_target_unknown_triple) << Target.str();
+ // Currently the firmware OS is an Apple specific concept.
+ if (Target.isOSFirmware() && (Target.getVendor() != llvm::Triple::Apple))
+ D.Diag(diag::err_target_unknown_triple) << Target.str();
+
// The `-maix[32|64]` flags are only valid for AIX targets.
if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64);
A && !Target.isOSAIX())
@@ -7010,6 +7014,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 55eb2dcf7ddf4..7d9c1f0bd3d40 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 fb75739360328..7d7a29fbc3753 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 {
@@ -1138,6 +1145,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();
@@ -1365,6 +1374,11 @@ 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");
@@ -1384,20 +1398,22 @@ std::string Darwin::getCompilerRT(const ArgList &Args, StringRef Component,
StringRef Darwin::getPlatformFamily() const {
switch (TargetPlatform) {
- case DarwinPlatformKind::MacOS:
+ case DarwinPlatformKind::MacOS:
+ return "MacOSX";
+ case DarwinPlatformKind::IPhoneOS:
+ if (TargetEnvironment == MacCatalyst)
return "MacOSX";
- case DarwinPlatformKind::IPhoneOS:
- if (TargetEnvironment == MacCatalyst)
- return "MacOSX";
- return "iPhone";
- case DarwinPlatformKind::TvOS:
- return "AppleTV";
- case DarwinPlatformKind::WatchOS:
- return "Watch";
- case DarwinPlatformKind::DriverKit:
- return "DriverKit";
- case DarwinPlatformKind::XROS:
- return "XR";
+ return "iPhone";
+ case DarwinPlatformKind::TvOS:
+ return "AppleTV";
+ case DarwinPlatformKind::WatchOS:
+ return "Watch";
+ case DarwinPlatformKind::DriverKit:
+ return "DriverKit";
+ case DarwinPlatformKind::XROS:
+ return "XR";
+ default:
+ break;
}
llvm_unreachable("Unsupported platform");
}
@@ -1434,6 +1450,9 @@ StringRef Darwin::getOSLibraryNameSuffix(bool IgnoreSim) const {
: "xrossim";
case DarwinPlatformKind::DriverKit:
return "driverkit";
+
+ case DarwinPlatformKind::Firmware:
+ break;
}
llvm_unreachable("Unsupported platform");
}
@@ -1534,6 +1553,11 @@ 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);
@@ -1779,11 +1803,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);
@@ -1959,6 +1980,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");
}
@@ -1978,6 +2001,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");
}
@@ -2074,7 +2099,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",
@@ -2083,8 +2107,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;
@@ -2226,16 +2249,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;
@@ -2569,15 +2589,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.
@@ -3118,9 +3137,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;
}
@@ -3209,9 +3226,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;
}
@@ -3582,12 +3598,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 4a3b75be3c258..62532317df8c1 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -362,7 +362,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
WatchOS,
DriverKit,
XROS,
- LastDarwinPlatform = XROS
+ Firmware,
};
enum DarwinEnvironmentKind {
NativeEnvironment,
@@ -516,6 +516,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 394f583331d74..4861304b3fc99 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 a4de51e8e7244..07755d01f9a52 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 0000000000000..95676daaca42d
--- /dev/null
+++ b/clang/test/Driver/unsupported-target-vendor.c
@@ -0,0 +1,105 @@
+// Tests that clang does not crash with invalid vendors in target triples.
+//
+// RUN: not %clang --target=arm-none-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-NONE %s
+// RUN: not %clang_cl --target=arm-none-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-NONE %s
+// CHECK-NONE: error: unknown target triple 'arm-none-firmware'{{$}}
+
+// RUN: not %clang --target=arm-unknown-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-UNKNOWN %s
+// RUN: not %clang_cl --target=arm-unknown-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-UNKNOWN %s
+// CHECK-UNKNOWN: error: unknown target triple 'arm-unknown-firmware'{{$}}
+
+// *-apple-firmware is valid
+
+// RUN: not %clang --target=arm-pc-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-PC %s
+// RUN: not %clang_cl --target=arm-pc-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-PC %s
+// CHECK-PC: error: unknown target triple 'arm-pc-firmware'{{$}}
+
+// RUN: not %clang --target=arm-scei-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-SCEI %s
+// RUN: not %clang_cl --target=arm-scei-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-SCEI %s
+// CHECK-SCEI: error: unknown target triple 'arm-scei-firmware'{{$}}
+
+// RUN: not %clang --target=arm-sie-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-SIE %s
+// RUN: not %clang_cl --target=arm-sie-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-SIE %s
+// CHECK-SIE: error: unknown target triple 'arm-sie-firmware'{{$}}
+
+// RUN: not %clang --target=arm-fsl-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-FSL %s
+// RUN: not %clang_cl --target=arm-fsl-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-FSL %s
+// CHECK-FSL: error: unknown target triple 'arm-fsl-firmware'{{$}}
+
+// RUN: not %clang --target=arm-ibm-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-IBM %s
+// RUN: not %clang_cl --target=arm-ibm-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-IBM %s
+// CHECK-IBM: error: unknown target triple 'arm-ibm-firmware'{{$}}
+
+// RUN: not %clang --target=arm-img-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-IMG %s
+// RUN: not %clang_cl --target=arm-img-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-IMG %s
+// CHECK-IMG: error: unknown target triple 'arm-img-firmware'{{$}}
+
+// RUN: not %clang --target=arm-mti-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-MTI %s
+// RUN: not %clang_cl --target=arm-mti-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-MTI %s
+// CHECK-MTI: error: unknown target triple 'arm-mti-firmware'{{$}}
+
+// RUN: not %clang --target=arm-nvidia-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-NVIDIA %s
+// RUN: not %clang_cl --target=arm-nvidia-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-NVIDIA %s
+// CHECK-NVIDIA: error: unknown target triple 'arm-nvidia-firmware'{{$}}
+
+// RUN: not %clang --target=arm-csr-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-CSR %s
+// RUN: not %clang_cl --target=arm-csr-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-CSR %s
+// CHECK-CSR: error: unknown target triple 'arm-csr-firmware'{{$}}
+
+// RUN: not %clang --target=arm-amd-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-AMD %s
+// RUN: not %clang_cl --target=arm-amd-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-AMD %s
+// CHECK-AMD: error: unknown target triple 'arm-amd-firmware'{{$}}
+
+// RUN: not %clang --target=arm-mesa-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-MESA %s
+// RUN: not %clang_cl --target=arm-mesa-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-MESA %s
+// CHECK-MESA: error: unknown target triple 'arm-mesa-firmware'{{$}}
+
+// RUN: not %clang --target=arm-suse-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-SUSE %s
+// RUN: not %clang_cl --target=arm-suse-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-SUSE %s
+// CHECK-SUSE: error: unknown target triple 'arm-suse-firmware'{{$}}
+
+// RUN: not %clang --target=arm-oe-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-OE %s
+// RUN: not %clang_cl --target=arm-oe-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-OE %s
+// CHECK-OE: error: unknown target triple 'arm-oe-firmware'{{$}}
+
+// RUN: not %clang --target=arm-intel-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-INTEL %s
+// RUN: not %clang_cl --target=arm-intel-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-INTEL %s
+// CHECK-INTEL: error: unknown target triple 'arm-intel-firmware'{{$}}
+
+// RUN: not %clang --target=arm-meta-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-META %s
+// RUN: not %clang_cl --target=arm-meta-firmware -o %t.o %s 2> %t.err
+// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-META %s
+// CHECK-META: error: unknown target triple 'arm-meta-firmware'{{$}}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 8559d7b088ee1..afbf464310a8d 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 e6a9eedab5954..5f47d872abdd3 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);
}
@@ -1528,6 +1531,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 +1583,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 +1610,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");
}
}
More information about the cfe-commits
mailing list