https://github.com/ian-twilightcoder updated 
https://github.com/llvm/llvm-project/pull/176272

>From c8073729aedbc6dea7e5379675be03d280c76b78 Mon Sep 17 00:00:00 2001
From: Ian Anderson <[email protected]>
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        | 100 ++++++++++-------
 clang/lib/Driver/ToolChains/Darwin.h          |   8 +-
 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, 260 insertions(+), 57 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..dc1b5cf39e7ff 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";
+  case DarwinPlatformKind::Firmware:
+    return "Firmware";
   }
   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");
   }
@@ -2226,16 +2251,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 +2591,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 +3139,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 +3228,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 +3600,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..77f31825bcbc3 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -356,13 +356,17 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
   mutable bool TargetInitialized;
 
   enum DarwinPlatformKind {
+    // Platforms with associated *_DEPLOYMENT_TARGET environment variables.
     MacOS,
     IPhoneOS,
     TvOS,
     WatchOS,
     DriverKit,
     XROS,
-    LastDarwinPlatform = XROS
+    LastDarwinPlatform = XROS,
+
+    // Additional platforms.
+    Firmware,
   };
   enum DarwinEnvironmentKind {
     NativeEnvironment,
@@ -516,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 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 9c83abeeb3b19..08ffd93437921 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -252,7 +252,8 @@ class Triple {
     Serenity,
     Vulkan, // Vulkan SPIR-V
     CheriotRTOS,
-    LastOSType = CheriotRTOS
+    Firmware,
+    LastOSType = Firmware
   };
   enum EnvironmentType {
     UnknownEnvironment,
@@ -626,11 +627,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 {
@@ -892,6 +900,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 a4f9dd42c0fec..76020a92273f6 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -341,6 +341,8 @@ StringRef Triple::getOSTypeName(OSType Kind) {
   case Vulkan: return "vulkan";
   case CheriotRTOS:
     return "cheriotrtos";
+  case Firmware:
+    return "firmware";
   }
 
   llvm_unreachable("Invalid OSType");
@@ -754,6 +756,7 @@ static Triple::OSType parseOS(StringRef OSName) {
       .StartsWith("serenity", Triple::Serenity)
       .StartsWith("vulkan", Triple::Vulkan)
       .StartsWith("cheriotrtos", Triple::CheriotRTOS)
+      .StartsWith("firmware", Triple::Firmware)
       .Default(Triple::UnknownOS);
 }
 
@@ -1525,6 +1528,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;
 }
@@ -1575,6 +1580,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");
   }
 }
 
@@ -1600,6 +1607,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");
   }
 }
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to