[clang] [clang][Darwin] Simplify deployment version assignment in the Driver (PR #142013)
Cyndy Ishida via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 4 14:58:49 PDT 2025
https://github.com/cyndyishida updated https://github.com/llvm/llvm-project/pull/142013
>From a12e45e0b3025126dc112c6f8dd552b2670e88f9 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Thu, 29 May 2025 12:19:09 -0700
Subject: [PATCH 1/3] [clang][Darwin] Simply deployment version assignment in
the Driver
To be able to handle all of the ways the platform & deployment version can be represented in command line flags, the Darwin toolchain holds a type DarwinPlatform to help represent them. This patch simplifies the logic by:
reducing the amount of work done between string & version tuples conversions
renaming variables to reduce confusion about what target triple information is being manipulated.
allowing implicit transformation of macOS10.16 -> 11, there are other places in the compiler where this happens, and it was a bit confusing that the driver didn't do that for the cc1 call.
This is not a major refactor, but more simple & common tweaks across the file, in hopes to make it more readable.
---
.../clang/Basic/DiagnosticDriverKinds.td | 4 +
clang/lib/Driver/ToolChains/Darwin.cpp | 291 ++++++++++--------
clang/test/Driver/darwin-debug-flags.c | 2 +-
clang/test/Driver/darwin-version.c | 8 +-
4 files changed, 173 insertions(+), 132 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 4da8f80345ddc..20fb47237c56f 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -206,6 +206,7 @@ def err_drv_cannot_open_randomize_layout_seed_file : Error<
"cannot read randomize layout seed file '%0'">;
def err_drv_invalid_version_number : Error<
"invalid version number in '%0'">;
+def err_drv_missing_version_number : Error<"missing version number in '%0'">;
def err_drv_kcfi_arity_unsupported_target : Error<
"target '%0' is unsupported by -fsanitize-kcfi-arity">;
def err_drv_no_linker_llvm_support : Error<
@@ -478,6 +479,9 @@ def warn_ignoring_ftabstop_value : Warning<
def warn_drv_overriding_option : Warning<
"overriding '%0' option with '%1'">,
InGroup<DiagGroup<"overriding-option">>;
+def warn_drv_overriding_deployment_version
+ : Warning<"overriding deployment version from '%0' to '%1'">,
+ InGroup<DiagGroup<"overriding-deployment-version">>;
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 26e24ad0ab17c..522393c37a7b1 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1709,24 +1709,21 @@ struct DarwinPlatform {
Environment = Kind;
InferSimulatorFromArch = false;
}
+ const VersionTuple &getOSVersion() const { return ResolvedOSVersion; }
- StringRef getOSVersion() const {
- if (Kind == OSVersionArg)
- return Argument->getValue();
- return OSVersion;
+ VersionTuple getCanonicalOSVersion() const {
+ return llvm::Triple::getCanonicalVersionForOS(getOSFromPlatform(Platform),
+ ResolvedOSVersion);
}
- void setOSVersion(StringRef S) {
- assert(Kind == TargetArg && "Unexpected kind!");
- OSVersion = std::string(S);
- }
+ void setOSVersion(VersionTuple Version) { ResolvedOSVersion = Version; }
- bool hasOSVersion() const { return HasOSVersion; }
+ bool providedOSVersion() const { return ProvidedOSVersion; }
- VersionTuple getNativeTargetVersion() const {
+ VersionTuple getZipperedOSVersion() const {
assert(Environment == DarwinEnvironmentKind::MacCatalyst &&
- "native target version is specified only for Mac Catalyst");
- return NativeTargetVersion;
+ "zippered target version is specified only for Mac Catalyst");
+ return ZipperedOSVersion;
}
/// Returns true if the target OS was explicitly specified.
@@ -1766,7 +1763,8 @@ struct DarwinPlatform {
// DriverKit always explicitly provides a version in the triple.
return;
}
- Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion);
+ Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt),
+ ResolvedOSVersion.getAsString());
Args.append(Argument);
}
@@ -1782,7 +1780,8 @@ struct DarwinPlatform {
assert(Argument && "OS version argument not yet inferred");
return Argument->getAsString(Args);
case DeploymentTargetEnv:
- return (llvm::Twine(EnvVarName) + "=" + OSVersion).str();
+ return (llvm::Twine(EnvVarName) + "=" + ResolvedOSVersion.getAsString())
+ .str();
}
llvm_unreachable("Unsupported Darwin Source Kind");
}
@@ -1797,13 +1796,13 @@ struct DarwinPlatform {
case llvm::Triple::MacABI: {
Environment = DarwinEnvironmentKind::MacCatalyst;
// The minimum native macOS target for MacCatalyst is macOS 10.15.
- NativeTargetVersion = VersionTuple(10, 15);
- if (HasOSVersion && SDKInfo) {
+ ZipperedOSVersion = VersionTuple(10, 15);
+ if (providedOSVersion() && SDKInfo) {
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
- OSVersion, NativeTargetVersion, std::nullopt)) {
- NativeTargetVersion = *MacOSVersion;
+ OSVersion, ZipperedOSVersion, std::nullopt)) {
+ ZipperedOSVersion = *MacOSVersion;
}
}
}
@@ -1813,8 +1812,8 @@ struct DarwinPlatform {
if (TargetVariantTriple) {
auto TargetVariantVersion = TargetVariantTriple->getOSVersion();
if (TargetVariantVersion.getMajor()) {
- if (TargetVariantVersion < NativeTargetVersion)
- NativeTargetVersion = TargetVariantVersion;
+ if (TargetVariantVersion < ZipperedOSVersion)
+ ZipperedOSVersion = TargetVariantVersion;
}
}
break;
@@ -1825,14 +1824,12 @@ struct DarwinPlatform {
}
static DarwinPlatform
- createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
+ createFromTarget(const llvm::Triple &TT, Arg *A,
std::optional<llvm::Triple> TargetVariantTriple,
const std::optional<DarwinSDKInfo> &SDKInfo) {
- DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
- A);
+ DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()),
+ TT.getOSVersion(), A);
VersionTuple OsVersion = TT.getOSVersion();
- if (OsVersion.getMajor() == 0)
- Result.HasOSVersion = false;
Result.TargetVariantTriple = TargetVariantTriple;
Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo);
return Result;
@@ -1841,38 +1838,40 @@ struct DarwinPlatform {
createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
llvm::Triple::EnvironmentType Environment, Arg *A,
const std::optional<DarwinSDKInfo> &SDKInfo) {
- DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS),
- OSVersion.getAsString(), A);
+ DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS), OSVersion, A);
Result.InferSimulatorFromArch = false;
Result.setEnvironment(Environment, OSVersion, SDKInfo);
return Result;
}
static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform, Arg *A,
bool IsSimulator) {
- DarwinPlatform Result{OSVersionArg, Platform, A};
+ DarwinPlatform Result{OSVersionArg, Platform,
+ getVersionFromString(A->getValue()), A};
if (IsSimulator)
Result.Environment = DarwinEnvironmentKind::Simulator;
return Result;
}
static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform,
StringRef EnvVarName,
- StringRef Value) {
- DarwinPlatform Result(DeploymentTargetEnv, Platform, Value);
+ StringRef OSVersion) {
+ DarwinPlatform Result(DeploymentTargetEnv, Platform,
+ getVersionFromString(OSVersion));
Result.EnvVarName = EnvVarName;
return Result;
}
static DarwinPlatform createFromSDK(DarwinPlatformKind Platform,
StringRef Value,
bool IsSimulator = false) {
- DarwinPlatform Result(InferredFromSDK, Platform, Value);
+ DarwinPlatform Result(InferredFromSDK, Platform,
+ getVersionFromString(Value));
if (IsSimulator)
Result.Environment = DarwinEnvironmentKind::Simulator;
Result.InferSimulatorFromArch = false;
return Result;
}
static DarwinPlatform createFromArch(llvm::Triple::OSType OS,
- StringRef Value) {
- return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value);
+ VersionTuple Version) {
+ return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
}
/// Constructs an inferred SDKInfo value based on the version inferred from
@@ -1880,22 +1879,27 @@ struct DarwinPlatform {
/// the platform from the SDKPath.
DarwinSDKInfo inferSDKInfo() {
assert(Kind == InferredFromSDK && "can infer SDK info only");
- llvm::VersionTuple Version;
- bool IsValid = !Version.tryParse(OSVersion);
- (void)IsValid;
- assert(IsValid && "invalid SDK version");
- return DarwinSDKInfo(
- Version,
- /*MaximumDeploymentTarget=*/VersionTuple(Version.getMajor(), 0, 99),
- getOSFromPlatform(Platform));
+ return DarwinSDKInfo(ResolvedOSVersion,
+ /*MaximumDeploymentTarget=*/
+ VersionTuple(ResolvedOSVersion.getMajor(), 0, 99),
+ getOSFromPlatform(Platform));
}
private:
DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
: Kind(Kind), Platform(Platform), Argument(Argument) {}
- DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value,
- Arg *Argument = nullptr)
- : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(Argument) {}
+ DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform,
+ VersionTuple Value, Arg *Argument = nullptr)
+ : Kind(Kind), Platform(Platform), ResolvedOSVersion(Value),
+ ProvidedOSVersion(!Value.empty()), Argument(Argument) {}
+
+ static VersionTuple getVersionFromString(const StringRef Input) {
+ llvm::VersionTuple Version;
+ bool IsValid = !Version.tryParse(Input);
+ assert(IsValid && "unable to convert input version to version tuple");
+ (void)IsValid;
+ return Version;
+ }
static DarwinPlatformKind getPlatformFromOS(llvm::Triple::OSType OS) {
switch (OS) {
@@ -1938,11 +1942,22 @@ struct DarwinPlatform {
SourceKind Kind;
DarwinPlatformKind Platform;
DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment;
- VersionTuple NativeTargetVersion;
- std::string OSVersion;
- bool HasOSVersion = true, InferSimulatorFromArch = true;
+ // When compiling for a zippered target, this means both target &
+ // target variant is set on the command line, ZipperedOSVersion holds the
+ // OSVersion tied to the main target value.
+ VersionTuple ZipperedOSVersion;
+ // We allow multiple ways to set or default the OS
+ // version used for compilation. The ResolvedOSVersion always represents what
+ // will be used.
+ VersionTuple ResolvedOSVersion;
+ // Track whether the OS deployment version was explicitly set on creation.
+ // This can be used for overidding the resolved version or error reporting.
+ bool ProvidedOSVersion = false;
+ bool InferSimulatorFromArch = true;
Arg *Argument;
StringRef EnvVarName;
+ // When compiling for a zippered target, this value represents the target
+ // triple encoded in the target variant.
std::optional<llvm::Triple> TargetVariantTriple;
};
@@ -1960,6 +1975,19 @@ getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
Arg *WatchOSVersion =
Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
options::OPT_mwatchos_simulator_version_min_EQ);
+
+ auto GetDarwinPlatform =
+ [&](DarwinPlatform::DarwinPlatformKind Platform, Arg *VersionArg,
+ bool IsSimulator) -> std::optional<DarwinPlatform> {
+ if (StringRef(VersionArg->getValue()).empty()) {
+ TheDriver.Diag(diag::err_drv_missing_version_number)
+ << VersionArg->getAsString(Args);
+ return std::nullopt;
+ }
+ return DarwinPlatform::createOSVersionArg(Platform, VersionArg,
+ /*IsSimulator=*/IsSimulator);
+ };
+
if (macOSVersion) {
if (iOSVersion || TvOSVersion || WatchOSVersion) {
TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
@@ -1968,30 +1996,29 @@ getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
: TvOSVersion ? TvOSVersion : WatchOSVersion)
->getAsString(Args);
}
- return DarwinPlatform::createOSVersionArg(Darwin::MacOS, macOSVersion,
- /*IsSimulator=*/false);
+ return GetDarwinPlatform(Darwin::MacOS, macOSVersion,
+ /*IsSimulator=*/false);
+
} else if (iOSVersion) {
if (TvOSVersion || WatchOSVersion) {
TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
<< iOSVersion->getAsString(Args)
<< (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
}
- return DarwinPlatform::createOSVersionArg(
- Darwin::IPhoneOS, iOSVersion,
- iOSVersion->getOption().getID() ==
- options::OPT_mios_simulator_version_min_EQ);
+ return GetDarwinPlatform(Darwin::IPhoneOS, iOSVersion,
+ iOSVersion->getOption().getID() ==
+ options::OPT_mios_simulator_version_min_EQ);
} else if (TvOSVersion) {
if (WatchOSVersion) {
TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
<< TvOSVersion->getAsString(Args)
<< WatchOSVersion->getAsString(Args);
}
- return DarwinPlatform::createOSVersionArg(
- Darwin::TvOS, TvOSVersion,
- TvOSVersion->getOption().getID() ==
- options::OPT_mtvos_simulator_version_min_EQ);
+ return GetDarwinPlatform(Darwin::TvOS, TvOSVersion,
+ TvOSVersion->getOption().getID() ==
+ options::OPT_mtvos_simulator_version_min_EQ);
} else if (WatchOSVersion)
- return DarwinPlatform::createOSVersionArg(
+ return GetDarwinPlatform(
Darwin::WatchOS, WatchOSVersion,
WatchOSVersion->getOption().getID() ==
options::OPT_mwatchos_simulator_version_min_EQ);
@@ -2125,8 +2152,8 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK));
}
-std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
- const Driver &TheDriver) {
+VersionTuple getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
+ const Driver &TheDriver) {
VersionTuple OsVersion;
llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
switch (OS) {
@@ -2165,12 +2192,7 @@ std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
llvm_unreachable("Unexpected OS type");
break;
}
-
- std::string OSVersion;
- llvm::raw_string_ostream(OSVersion)
- << OsVersion.getMajor() << '.' << OsVersion.getMinor().value_or(0) << '.'
- << OsVersion.getSubminor().value_or(0);
- return OSVersion;
+ return OsVersion;
}
/// Tries to infer the target OS from the -arch.
@@ -2206,7 +2228,7 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
if (Triple.getOS() == llvm::Triple::Darwin ||
Triple.getOS() == llvm::Triple::UnknownOS)
return std::nullopt;
- std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
+ VersionTuple OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
std::optional<llvm::Triple> TargetVariantTriple;
for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {
llvm::Triple TVT(A->getValue());
@@ -2232,9 +2254,14 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
<< A->getSpelling() << A->getValue();
}
}
- return DarwinPlatform::createFromTarget(Triple, OSVersion,
- Args.getLastArg(options::OPT_target),
- TargetVariantTriple, SDKInfo);
+ DarwinPlatform DP = DarwinPlatform::createFromTarget(
+ Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,
+ SDKInfo);
+
+ // Override the OSVersion if it doesn't match the one from the triple.
+ if (Triple.getOSVersion() != OSVersion)
+ DP.setOSVersion(OSVersion);
+ return DP;
}
/// Returns the deployment target that's specified using the -mtargetos option.
@@ -2313,12 +2340,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
// The OS and the version can be specified using the -target argument.
- std::optional<DarwinPlatform> OSTarget =
+ std::optional<DarwinPlatform> DP =
getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
- if (OSTarget) {
+ if (DP) {
// Disallow mixing -target and -mtargetos=.
if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
- std::string TargetArgStr = OSTarget->getAsString(Args, Opts);
+ std::string TargetArgStr = DP->getAsString(Args, Opts);
std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< TargetArgStr << MTargetOSArgStr;
@@ -2330,102 +2357,112 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
bool TargetExtra;
unsigned ArgMajor, ArgMinor, ArgMicro;
bool ArgExtra;
- if (OSTarget->getPlatform() != OSVersionArgTarget->getPlatform() ||
- (Driver::GetReleaseVersion(OSTarget->getOSVersion(), TargetMajor,
- TargetMinor, TargetMicro, TargetExtra) &&
- Driver::GetReleaseVersion(OSVersionArgTarget->getOSVersion(),
- ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&
+ if (DP->getPlatform() != OSVersionArgTarget->getPlatform() ||
+ (Driver::GetReleaseVersion(DP->getOSVersion().getAsString(),
+ TargetMajor, TargetMinor, TargetMicro,
+ TargetExtra) &&
+ Driver::GetReleaseVersion(
+ OSVersionArgTarget->getOSVersion().getAsString(), ArgMajor,
+ ArgMinor, ArgMicro, ArgExtra) &&
(VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
TargetExtra != ArgExtra))) {
// Select the OS version from the -m<os>-version-min argument when
// the -target does not include an OS version.
- if (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() &&
- !OSTarget->hasOSVersion()) {
- OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion());
+ if (DP->getPlatform() == OSVersionArgTarget->getPlatform() &&
+ !DP->providedOSVersion()) {
+ DP->setOSVersion(OSVersionArgTarget->getOSVersion());
} else {
// Warn about -m<os>-version-min that doesn't match the OS version
// that's specified in the target.
std::string OSVersionArg =
OSVersionArgTarget->getAsString(Args, Opts);
- std::string TargetArg = OSTarget->getAsString(Args, Opts);
+ std::string TargetArg = DP->getAsString(Args, Opts);
getDriver().Diag(clang::diag::warn_drv_overriding_option)
<< OSVersionArg << TargetArg;
}
}
}
- } else if ((OSTarget = getDeploymentTargetFromMTargetOSArg(Args, getDriver(),
- SDKInfo))) {
+ } else if ((DP = getDeploymentTargetFromMTargetOSArg(Args, getDriver(),
+ SDKInfo))) {
// The OS target can be specified using the -mtargetos= argument.
// Disallow mixing -mtargetos= and -m<os>version-min=.
std::optional<DarwinPlatform> OSVersionArgTarget =
getDeploymentTargetFromOSVersionArg(Args, getDriver());
if (OSVersionArgTarget) {
- std::string MTargetOSArgStr = OSTarget->getAsString(Args, Opts);
+ std::string MTargetOSArgStr = DP->getAsString(Args, Opts);
std::string OSVersionArgStr = OSVersionArgTarget->getAsString(Args, Opts);
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< MTargetOSArgStr << OSVersionArgStr;
}
} else {
// The OS target can be specified using the -m<os>version-min argument.
- OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver());
+ DP = getDeploymentTargetFromOSVersionArg(Args, getDriver());
// If no deployment target was specified on the command line, check for
// environment defines.
- if (!OSTarget) {
- OSTarget =
+ if (!DP) {
+ DP =
getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
- if (OSTarget) {
+ if (DP) {
// Don't infer simulator from the arch when the SDK is also specified.
std::optional<DarwinPlatform> SDKTarget =
inferDeploymentTargetFromSDK(Args, SDKInfo);
if (SDKTarget)
- OSTarget->setEnvironment(SDKTarget->getEnvironment());
+ DP->setEnvironment(SDKTarget->getEnvironment());
}
}
// If there is no command-line argument to specify the Target version and
// no environment variable defined, see if we can set the default based
// on -isysroot using SDKSettings.json if it exists.
- if (!OSTarget) {
- OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo);
+ if (!DP) {
+ DP = inferDeploymentTargetFromSDK(Args, SDKInfo);
/// If the target was successfully constructed from the SDK path, try to
/// infer the SDK info if the SDK doesn't have it.
- if (OSTarget && !SDKInfo)
- SDKInfo = OSTarget->inferSDKInfo();
+ if (DP && !SDKInfo)
+ SDKInfo = DP->inferSDKInfo();
}
// If no OS targets have been specified, try to guess platform from -target
// or arch name and compute the version from the triple.
- if (!OSTarget)
- OSTarget =
- inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
+ if (!DP)
+ DP = inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
+ }
+
+ assert(DP && "Unable to infer Darwin variant");
+ // After the deployment OS version has been resolved, set it to the canonical
+ // version before further error detection and converting to a proper target
+ // triple.
+ VersionTuple CanonicalVersion = DP->getCanonicalOSVersion();
+ if (CanonicalVersion != DP->getOSVersion()) {
+ getDriver().Diag(diag::warn_drv_overriding_deployment_version)
+ << DP->getOSVersion().getAsString() << CanonicalVersion.getAsString();
+ DP->setOSVersion(CanonicalVersion);
}
- assert(OSTarget && "Unable to infer Darwin variant");
- OSTarget->addOSVersionMinArgument(Args, Opts);
- DarwinPlatformKind Platform = OSTarget->getPlatform();
+ DP->addOSVersionMinArgument(Args, Opts);
+ DarwinPlatformKind Platform = DP->getPlatform();
unsigned Major, Minor, Micro;
bool HadExtra;
// The major version should not be over this number.
const unsigned MajorVersionLimit = 1000;
+ const std::string DPVersion = DP->getOSVersion().getAsString();
// Set the tool chain target information.
if (Platform == MacOS) {
- if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
- Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 ||
Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
} else if (Platform == IPhoneOS) {
- if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
- Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
;
- if (OSTarget->getEnvironment() == MacCatalyst &&
+ if (DP->getEnvironment() == MacCatalyst &&
(Major < 13 || (Major == 13 && Minor < 1))) {
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
Major = 13;
Minor = 1;
Micro = 0;
@@ -2434,12 +2471,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// iOS 11.
if (getTriple().isArch32Bit() && Major >= 11) {
// If the deployment target is explicitly specified, print a diagnostic.
- if (OSTarget->isExplicitlySpecified()) {
- if (OSTarget->getEnvironment() == MacCatalyst)
+ if (DP->isExplicitlySpecified()) {
+ if (DP->getEnvironment() == MacCatalyst)
getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);
else
getDriver().Diag(diag::warn_invalid_ios_deployment_target)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
// Otherwise, set it to 10.99.99.
} else {
Major = 10;
@@ -2448,46 +2485,42 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
} else if (Platform == TvOS) {
- if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
- Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
} else if (Platform == WatchOS) {
- if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
- Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
} else if (Platform == DriverKit) {
- if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
- Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 ||
Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSTarget->getAsString(Args, Opts);
+ << DP->getAsString(Args, Opts);
} else if (Platform == XROS) {
- if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
- Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(DPVersion, 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);
+ << DP->getAsString(Args, Opts);
} else
llvm_unreachable("unknown kind of Darwin platform");
- DarwinEnvironmentKind Environment = OSTarget->getEnvironment();
+ DarwinEnvironmentKind Environment = DP->getEnvironment();
// Recognize iOS targets with an x86 architecture as the iOS simulator.
if (Environment == NativeEnvironment && Platform != MacOS &&
- Platform != DriverKit && OSTarget->canInferSimulatorFromArch() &&
+ Platform != DriverKit && DP->canInferSimulatorFromArch() &&
getTriple().isX86())
Environment = Simulator;
- VersionTuple NativeTargetVersion;
+ VersionTuple ZipperedOSVersion;
if (Environment == MacCatalyst)
- NativeTargetVersion = OSTarget->getNativeTargetVersion();
- setTarget(Platform, Environment, Major, Minor, Micro, NativeTargetVersion);
- TargetVariantTriple = OSTarget->getTargetVariantTriple();
+ ZipperedOSVersion = DP->getZipperedOSVersion();
+ setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion);
+ TargetVariantTriple = DP->getTargetVariantTriple();
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
StringRef SDK = getSDKName(A->getValue());
diff --git a/clang/test/Driver/darwin-debug-flags.c b/clang/test/Driver/darwin-debug-flags.c
index 918ee345658a0..90209bb179bfc 100644
--- a/clang/test/Driver/darwin-debug-flags.c
+++ b/clang/test/Driver/darwin-debug-flags.c
@@ -7,7 +7,7 @@
// CHECK-SAME: flags:
// CHECK-SAME: -I path\\ with\\ \\\\spaces
// CHECK-SAME: -g -Os
-// CHECK-SAME: -mmacos-version-min=10.7.0
+// CHECK-SAME: -mmacos-version-min=10.7
int x;
diff --git a/clang/test/Driver/darwin-version.c b/clang/test/Driver/darwin-version.c
index a00bd832dc802..9b9c6034bb75d 100644
--- a/clang/test/Driver/darwin-version.c
+++ b/clang/test/Driver/darwin-version.c
@@ -86,7 +86,7 @@
// RUN: FileCheck --check-prefix=CHECK-VERSION-MISSING %s
// RUN: not %clang -target x86_64-apple-darwin -mmacos-version-min= -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-MISSING %s
-// CHECK-VERSION-MISSING: invalid version number
+// CHECK-VERSION-MISSING: missing version number
// RUN: %clang -target armv7k-apple-darwin -mwatchos-version-min=2.0 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOS20 %s
// RUN: %clang -target armv7-apple-darwin -mtvos-version-min=8.3 -c %s -### 2>&1 | \
@@ -330,9 +330,13 @@
// RUN: FileCheck --check-prefix=CHECK-MACOS11 %s
// RUN: %clang -target x86_64-apple-darwin -mmacos-version-min=11 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-MACOS11 %s
-
// CHECK-MACOS11: "x86_64-apple-macosx11.0.0"
+// RUN: %clang -target arm64-apple-macosx10.16 -c %s -### 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-IMPLICIT-MACOS11 %s
+// CHECK-IMPLICIT-MACOS11: warning: overriding deployment version
+// CHECK-IMPLICIT-MACOS11: "arm64-apple-macosx11.0.0"
+
// RUN: %clang -target arm64-apple-macos999 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-MACOS999 %s
>From 335e31025af415eb50bf5cbb5d2f378288c72605 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Thu, 29 May 2025 15:54:49 -0700
Subject: [PATCH 2/3] Rename DP to PlatformAndVersion
---
clang/lib/Driver/ToolChains/Darwin.cpp | 145 ++++++++++++++-----------
1 file changed, 79 insertions(+), 66 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 522393c37a7b1..28c26ad880cfd 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -2254,14 +2254,14 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
<< A->getSpelling() << A->getValue();
}
}
- DarwinPlatform DP = DarwinPlatform::createFromTarget(
+ DarwinPlatform PlatformAndVersion = DarwinPlatform::createFromTarget(
Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,
SDKInfo);
// Override the OSVersion if it doesn't match the one from the triple.
if (Triple.getOSVersion() != OSVersion)
- DP.setOSVersion(OSVersion);
- return DP;
+ PlatformAndVersion.setOSVersion(OSVersion);
+ return PlatformAndVersion;
}
/// Returns the deployment target that's specified using the -mtargetos option.
@@ -2340,129 +2340,138 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
SDKInfo = parseSDKSettings(getVFS(), Args, getDriver());
// The OS and the version can be specified using the -target argument.
- std::optional<DarwinPlatform> DP =
+ std::optional<DarwinPlatform> PlatformAndVersion =
getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
- if (DP) {
+ if (PlatformAndVersion) {
// Disallow mixing -target and -mtargetos=.
if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
- std::string TargetArgStr = DP->getAsString(Args, Opts);
+ std::string TargetArgStr = PlatformAndVersion->getAsString(Args, Opts);
std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< TargetArgStr << MTargetOSArgStr;
}
- std::optional<DarwinPlatform> OSVersionArgTarget =
+ std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
getDeploymentTargetFromOSVersionArg(Args, getDriver());
- if (OSVersionArgTarget) {
+ if (PlatformAndVersionFromOSVersionArg) {
unsigned TargetMajor, TargetMinor, TargetMicro;
bool TargetExtra;
unsigned ArgMajor, ArgMinor, ArgMicro;
bool ArgExtra;
- if (DP->getPlatform() != OSVersionArgTarget->getPlatform() ||
- (Driver::GetReleaseVersion(DP->getOSVersion().getAsString(),
- TargetMajor, TargetMinor, TargetMicro,
- TargetExtra) &&
+ if (PlatformAndVersion->getPlatform() !=
+ PlatformAndVersionFromOSVersionArg->getPlatform() ||
+ (Driver::GetReleaseVersion(
+ PlatformAndVersion->getOSVersion().getAsString(), TargetMajor,
+ TargetMinor, TargetMicro, TargetExtra) &&
Driver::GetReleaseVersion(
- OSVersionArgTarget->getOSVersion().getAsString(), ArgMajor,
- ArgMinor, ArgMicro, ArgExtra) &&
+ PlatformAndVersionFromOSVersionArg->getOSVersion().getAsString(),
+ ArgMajor, ArgMinor, ArgMicro, ArgExtra) &&
(VersionTuple(TargetMajor, TargetMinor, TargetMicro) !=
VersionTuple(ArgMajor, ArgMinor, ArgMicro) ||
TargetExtra != ArgExtra))) {
// Select the OS version from the -m<os>-version-min argument when
// the -target does not include an OS version.
- if (DP->getPlatform() == OSVersionArgTarget->getPlatform() &&
- !DP->providedOSVersion()) {
- DP->setOSVersion(OSVersionArgTarget->getOSVersion());
+ if (PlatformAndVersion->getPlatform() ==
+ PlatformAndVersionFromOSVersionArg->getPlatform() &&
+ !PlatformAndVersion->providedOSVersion()) {
+ PlatformAndVersion->setOSVersion(
+ PlatformAndVersionFromOSVersionArg->getOSVersion());
} else {
// Warn about -m<os>-version-min that doesn't match the OS version
// that's specified in the target.
std::string OSVersionArg =
- OSVersionArgTarget->getAsString(Args, Opts);
- std::string TargetArg = DP->getAsString(Args, Opts);
+ PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
+ std::string TargetArg = PlatformAndVersion->getAsString(Args, Opts);
getDriver().Diag(clang::diag::warn_drv_overriding_option)
<< OSVersionArg << TargetArg;
}
}
}
- } else if ((DP = getDeploymentTargetFromMTargetOSArg(Args, getDriver(),
- SDKInfo))) {
+ } else if ((PlatformAndVersion = getDeploymentTargetFromMTargetOSArg(
+ Args, getDriver(), SDKInfo))) {
// The OS target can be specified using the -mtargetos= argument.
// Disallow mixing -mtargetos= and -m<os>version-min=.
- std::optional<DarwinPlatform> OSVersionArgTarget =
+ std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
getDeploymentTargetFromOSVersionArg(Args, getDriver());
- if (OSVersionArgTarget) {
- std::string MTargetOSArgStr = DP->getAsString(Args, Opts);
- std::string OSVersionArgStr = OSVersionArgTarget->getAsString(Args, Opts);
+ if (PlatformAndVersionFromOSVersionArg) {
+ std::string MTargetOSArgStr = PlatformAndVersion->getAsString(Args, Opts);
+ std::string OSVersionArgStr =
+ PlatformAndVersionFromOSVersionArg->getAsString(Args, Opts);
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< MTargetOSArgStr << OSVersionArgStr;
}
} else {
// The OS target can be specified using the -m<os>version-min argument.
- DP = getDeploymentTargetFromOSVersionArg(Args, getDriver());
+ PlatformAndVersion = getDeploymentTargetFromOSVersionArg(Args, getDriver());
// If no deployment target was specified on the command line, check for
// environment defines.
- if (!DP) {
- DP =
+ if (!PlatformAndVersion) {
+ PlatformAndVersion =
getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
- if (DP) {
+ if (PlatformAndVersion) {
// Don't infer simulator from the arch when the SDK is also specified.
std::optional<DarwinPlatform> SDKTarget =
inferDeploymentTargetFromSDK(Args, SDKInfo);
if (SDKTarget)
- DP->setEnvironment(SDKTarget->getEnvironment());
+ PlatformAndVersion->setEnvironment(SDKTarget->getEnvironment());
}
}
// If there is no command-line argument to specify the Target version and
// no environment variable defined, see if we can set the default based
// on -isysroot using SDKSettings.json if it exists.
- if (!DP) {
- DP = inferDeploymentTargetFromSDK(Args, SDKInfo);
+ if (!PlatformAndVersion) {
+ PlatformAndVersion = inferDeploymentTargetFromSDK(Args, SDKInfo);
/// If the target was successfully constructed from the SDK path, try to
/// infer the SDK info if the SDK doesn't have it.
- if (DP && !SDKInfo)
- SDKInfo = DP->inferSDKInfo();
+ if (PlatformAndVersion && !SDKInfo)
+ SDKInfo = PlatformAndVersion->inferSDKInfo();
}
// If no OS targets have been specified, try to guess platform from -target
// or arch name and compute the version from the triple.
- if (!DP)
- DP = inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
+ if (!PlatformAndVersion)
+ PlatformAndVersion =
+ inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
}
- assert(DP && "Unable to infer Darwin variant");
+ assert(PlatformAndVersion && "Unable to infer Darwin variant");
// After the deployment OS version has been resolved, set it to the canonical
// version before further error detection and converting to a proper target
// triple.
- VersionTuple CanonicalVersion = DP->getCanonicalOSVersion();
- if (CanonicalVersion != DP->getOSVersion()) {
+ VersionTuple CanonicalVersion = PlatformAndVersion->getCanonicalOSVersion();
+ if (CanonicalVersion != PlatformAndVersion->getOSVersion()) {
getDriver().Diag(diag::warn_drv_overriding_deployment_version)
- << DP->getOSVersion().getAsString() << CanonicalVersion.getAsString();
- DP->setOSVersion(CanonicalVersion);
+ << PlatformAndVersion->getOSVersion().getAsString()
+ << CanonicalVersion.getAsString();
+ PlatformAndVersion->setOSVersion(CanonicalVersion);
}
- DP->addOSVersionMinArgument(Args, Opts);
- DarwinPlatformKind Platform = DP->getPlatform();
+ PlatformAndVersion->addOSVersionMinArgument(Args, Opts);
+ DarwinPlatformKind Platform = PlatformAndVersion->getPlatform();
unsigned Major, Minor, Micro;
bool HadExtra;
// The major version should not be over this number.
const unsigned MajorVersionLimit = 1000;
- const std::string DPVersion = DP->getOSVersion().getAsString();
+ const std::string OSVersionStr =
+ PlatformAndVersion->getOSVersion().getAsString();
// Set the tool chain target information.
if (Platform == MacOS) {
- if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
+ HadExtra) ||
HadExtra || Major < 10 || Major >= MajorVersionLimit || Minor >= 100 ||
Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
} else if (Platform == IPhoneOS) {
- if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
+ HadExtra) ||
HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
;
- if (DP->getEnvironment() == MacCatalyst &&
+ if (PlatformAndVersion->getEnvironment() == MacCatalyst &&
(Major < 13 || (Major == 13 && Minor < 1))) {
getDriver().Diag(diag::err_drv_invalid_version_number)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
Major = 13;
Minor = 1;
Micro = 0;
@@ -2471,12 +2480,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// iOS 11.
if (getTriple().isArch32Bit() && Major >= 11) {
// If the deployment target is explicitly specified, print a diagnostic.
- if (DP->isExplicitlySpecified()) {
- if (DP->getEnvironment() == MacCatalyst)
+ if (PlatformAndVersion->isExplicitlySpecified()) {
+ if (PlatformAndVersion->getEnvironment() == MacCatalyst)
getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target);
else
getDriver().Diag(diag::warn_invalid_ios_deployment_target)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
// Otherwise, set it to 10.99.99.
} else {
Major = 10;
@@ -2485,42 +2494,46 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
} else if (Platform == TvOS) {
- if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
+ HadExtra) ||
HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
} else if (Platform == WatchOS) {
- if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
+ HadExtra) ||
HadExtra || Major >= MajorVersionLimit || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
} else if (Platform == DriverKit) {
- if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
+ HadExtra) ||
HadExtra || Major < 19 || Major >= MajorVersionLimit || Minor >= 100 ||
Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
} else if (Platform == XROS) {
- if (!Driver::GetReleaseVersion(DPVersion, Major, Minor, Micro, HadExtra) ||
+ 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)
- << DP->getAsString(Args, Opts);
+ << PlatformAndVersion->getAsString(Args, Opts);
} else
llvm_unreachable("unknown kind of Darwin platform");
- DarwinEnvironmentKind Environment = DP->getEnvironment();
+ DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment();
// Recognize iOS targets with an x86 architecture as the iOS simulator.
if (Environment == NativeEnvironment && Platform != MacOS &&
- Platform != DriverKit && DP->canInferSimulatorFromArch() &&
- getTriple().isX86())
+ Platform != DriverKit &&
+ PlatformAndVersion->canInferSimulatorFromArch() && getTriple().isX86())
Environment = Simulator;
VersionTuple ZipperedOSVersion;
if (Environment == MacCatalyst)
- ZipperedOSVersion = DP->getZipperedOSVersion();
+ ZipperedOSVersion = PlatformAndVersion->getZipperedOSVersion();
setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion);
- TargetVariantTriple = DP->getTargetVariantTriple();
+ TargetVariantTriple = PlatformAndVersion->getTargetVariantTriple();
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
StringRef SDK = getSDKName(A->getValue());
>From e71aee0b89b8918dc0162135c4c033cbcc64fc47 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Wed, 4 Jun 2025 13:59:46 -0700
Subject: [PATCH 3/3] Address review comments
---
clang/lib/Driver/ToolChains/Darwin.cpp | 96 ++++++++++++++++----------
1 file changed, 58 insertions(+), 38 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 28c26ad880cfd..926d6bc01f3f4 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1681,7 +1681,8 @@ static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
namespace {
-/// The Darwin OS that was selected or inferred from arguments / environment.
+/// The Darwin OS and version that was selected or inferred from arguments or
+/// environment.
struct DarwinPlatform {
enum SourceKind {
/// The OS was specified using the -target argument.
@@ -1709,16 +1710,27 @@ struct DarwinPlatform {
Environment = Kind;
InferSimulatorFromArch = false;
}
- const VersionTuple &getOSVersion() const { return ResolvedOSVersion; }
+
+ const VersionTuple getOSVersion() const {
+ return UnderlyingOSVersion.value_or(VersionTuple());
+ }
+
+ VersionTuple takeOSVersion() {
+ assert(UnderlyingOSVersion.has_value() &&
+ "attempting to get an unset OS version");
+ VersionTuple Result = *UnderlyingOSVersion;
+ UnderlyingOSVersion.reset();
+ return Result;
+ }
VersionTuple getCanonicalOSVersion() const {
return llvm::Triple::getCanonicalVersionForOS(getOSFromPlatform(Platform),
- ResolvedOSVersion);
+ getOSVersion());
}
- void setOSVersion(VersionTuple Version) { ResolvedOSVersion = Version; }
+ void setOSVersion(VersionTuple Version) { UnderlyingOSVersion = Version; }
- bool providedOSVersion() const { return ProvidedOSVersion; }
+ bool hasOSVersion() const { return UnderlyingOSVersion.has_value(); }
VersionTuple getZipperedOSVersion() const {
assert(Environment == DarwinEnvironmentKind::MacCatalyst &&
@@ -1738,7 +1750,8 @@ struct DarwinPlatform {
/// Adds the -m<os>-version-min argument to the compiler invocation.
void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
- if (Argument)
+ auto [Arg, OSVersionStr] = Arguments;
+ if (Arg)
return;
assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
"Invalid kind");
@@ -1763,25 +1776,24 @@ struct DarwinPlatform {
// DriverKit always explicitly provides a version in the triple.
return;
}
- Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt),
- ResolvedOSVersion.getAsString());
- Args.append(Argument);
+ Arg = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersionStr);
+ Args.append(Arg);
}
/// Returns the OS version with the argument / environment variable that
/// specified it.
std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
+ auto [Arg, OSVersionStr] = Arguments;
switch (Kind) {
case TargetArg:
case MTargetOSArg:
case OSVersionArg:
case InferredFromSDK:
case InferredFromArch:
- assert(Argument && "OS version argument not yet inferred");
- return Argument->getAsString(Args);
+ assert(Arg && "OS version argument not yet inferred");
+ return Arg->getAsString(Args);
case DeploymentTargetEnv:
- return (llvm::Twine(EnvVarName) + "=" + ResolvedOSVersion.getAsString())
- .str();
+ return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();
}
llvm_unreachable("Unsupported Darwin Source Kind");
}
@@ -1797,7 +1809,7 @@ struct DarwinPlatform {
Environment = DarwinEnvironmentKind::MacCatalyst;
// The minimum native macOS target for MacCatalyst is macOS 10.15.
ZipperedOSVersion = VersionTuple(10, 15);
- if (providedOSVersion() && SDKInfo) {
+ if (hasOSVersion() && SDKInfo) {
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
@@ -1879,19 +1891,23 @@ struct DarwinPlatform {
/// the platform from the SDKPath.
DarwinSDKInfo inferSDKInfo() {
assert(Kind == InferredFromSDK && "can infer SDK info only");
- return DarwinSDKInfo(ResolvedOSVersion,
+ return DarwinSDKInfo(getOSVersion(),
/*MaximumDeploymentTarget=*/
- VersionTuple(ResolvedOSVersion.getMajor(), 0, 99),
+ VersionTuple(getOSVersion().getMajor(), 0, 99),
getOSFromPlatform(Platform));
}
private:
DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
- : Kind(Kind), Platform(Platform), Argument(Argument) {}
+ : Kind(Kind), Platform(Platform),
+ Arguments({Argument, VersionTuple().getAsString()}) {}
DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform,
VersionTuple Value, Arg *Argument = nullptr)
- : Kind(Kind), Platform(Platform), ResolvedOSVersion(Value),
- ProvidedOSVersion(!Value.empty()), Argument(Argument) {}
+ : Kind(Kind), Platform(Platform),
+ Arguments({Argument, Value.getAsString()}) {
+ if (!Value.empty())
+ UnderlyingOSVersion = Value;
+ }
static VersionTuple getVersionFromString(const StringRef Input) {
llvm::VersionTuple Version;
@@ -1947,14 +1963,12 @@ struct DarwinPlatform {
// OSVersion tied to the main target value.
VersionTuple ZipperedOSVersion;
// We allow multiple ways to set or default the OS
- // version used for compilation. The ResolvedOSVersion always represents what
- // will be used.
- VersionTuple ResolvedOSVersion;
- // Track whether the OS deployment version was explicitly set on creation.
- // This can be used for overidding the resolved version or error reporting.
- bool ProvidedOSVersion = false;
+ // version used for compilation. When set, UnderlyingOSVersion represents
+ // the intended version to match the platform information computed from
+ // arguments.
+ std::optional<VersionTuple> UnderlyingOSVersion;
bool InferSimulatorFromArch = true;
- Arg *Argument;
+ std::pair<Arg *, std::string> Arguments;
StringRef EnvVarName;
// When compiling for a zippered target, this value represents the target
// triple encoded in the target variant.
@@ -2151,9 +2165,10 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
// The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK));
}
-
-VersionTuple getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
- const Driver &TheDriver) {
+// Compute & get the OS Version when the target triple omitted one.
+VersionTuple getInferredOSVersion(llvm::Triple::OSType OS,
+ const llvm::Triple &Triple,
+ const Driver &TheDriver) {
VersionTuple OsVersion;
llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
switch (OS) {
@@ -2215,8 +2230,8 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
OSTy = llvm::Triple::MacOSX;
if (OSTy == llvm::Triple::UnknownOS)
return std::nullopt;
- return DarwinPlatform::createFromArch(OSTy,
- getOSVersion(OSTy, Triple, TheDriver));
+ return DarwinPlatform::createFromArch(
+ OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
}
/// Returns the deployment target that's specified using the -target option.
@@ -2228,7 +2243,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
if (Triple.getOS() == llvm::Triple::Darwin ||
Triple.getOS() == llvm::Triple::UnknownOS)
return std::nullopt;
- VersionTuple OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
std::optional<llvm::Triple> TargetVariantTriple;
for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {
llvm::Triple TVT(A->getValue());
@@ -2258,9 +2272,9 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple,
SDKInfo);
- // Override the OSVersion if it doesn't match the one from the triple.
- if (Triple.getOSVersion() != OSVersion)
- PlatformAndVersion.setOSVersion(OSVersion);
+ //// Override the OSVersion if it doesn't match the one from the triple.
+ // if (Triple.getOSVersion() != OSVersion)
+ // PlatformAndVersion.setOSVersion(OSVersion);
return PlatformAndVersion;
}
@@ -2350,6 +2364,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< TargetArgStr << MTargetOSArgStr;
}
+ // Implicitly allow resolving the OS version when it wasn't explicitly set.
+ bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion();
+ if (!TripleProvidedOSVersion)
+ PlatformAndVersion->setOSVersion(
+ getInferredOSVersion(getTriple().getOS(), getTriple(), getDriver()));
+
std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
getDeploymentTargetFromOSVersionArg(Args, getDriver());
if (PlatformAndVersionFromOSVersionArg) {
@@ -2372,7 +2392,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
// the -target does not include an OS version.
if (PlatformAndVersion->getPlatform() ==
PlatformAndVersionFromOSVersionArg->getPlatform() &&
- !PlatformAndVersion->providedOSVersion()) {
+ !TripleProvidedOSVersion) {
PlatformAndVersion->setOSVersion(
PlatformAndVersionFromOSVersionArg->getOSVersion());
} else {
@@ -2451,8 +2471,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
bool HadExtra;
// The major version should not be over this number.
const unsigned MajorVersionLimit = 1000;
- const std::string OSVersionStr =
- PlatformAndVersion->getOSVersion().getAsString();
+ const VersionTuple OSVersion = PlatformAndVersion->takeOSVersion();
+ const std::string OSVersionStr = OSVersion.getAsString();
// Set the tool chain target information.
if (Platform == MacOS) {
if (!Driver::GetReleaseVersion(OSVersionStr, Major, Minor, Micro,
More information about the cfe-commits
mailing list