@@ -1681,7 +1681,8 @@ static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
16811681
16821682namespace {
16831683
1684- // / The Darwin OS that was selected or inferred from arguments / environment.
1684+ // / The Darwin OS and version that was selected or inferred from arguments or
1685+ // / environment.
16851686struct DarwinPlatform {
16861687 enum SourceKind {
16871688 // / The OS was specified using the -target argument.
@@ -1709,16 +1710,29 @@ struct DarwinPlatform {
17091710 Environment = Kind;
17101711 InferSimulatorFromArch = false ;
17111712 }
1712- const VersionTuple &getOSVersion () const { return ResolvedOSVersion; }
1713+
1714+ const VersionTuple getOSVersion () const {
1715+ return UnderlyingOSVersion.value_or (VersionTuple ());
1716+ }
1717+
1718+ VersionTuple takeOSVersion () {
1719+ assert (UnderlyingOSVersion.has_value () &&
1720+ " attempting to get an unset OS version" );
1721+ VersionTuple Result = *UnderlyingOSVersion;
1722+ UnderlyingOSVersion.reset ();
1723+ return Result;
1724+ }
17131725
17141726 VersionTuple getCanonicalOSVersion () const {
17151727 return llvm::Triple::getCanonicalVersionForOS (getOSFromPlatform (Platform),
1716- ResolvedOSVersion );
1728+ getOSVersion () );
17171729 }
17181730
1719- void setOSVersion (VersionTuple Version) { ResolvedOSVersion = Version; }
1731+ void setOSVersion (const VersionTuple &Version) {
1732+ UnderlyingOSVersion = Version;
1733+ }
17201734
1721- bool providedOSVersion () const { return ProvidedOSVersion ; }
1735+ bool hasOSVersion () const { return UnderlyingOSVersion. has_value () ; }
17221736
17231737 VersionTuple getZipperedOSVersion () const {
17241738 assert (Environment == DarwinEnvironmentKind::MacCatalyst &&
@@ -1738,7 +1752,8 @@ struct DarwinPlatform {
17381752
17391753 // / Adds the -m<os>-version-min argument to the compiler invocation.
17401754 void addOSVersionMinArgument (DerivedArgList &Args, const OptTable &Opts) {
1741- if (Argument)
1755+ auto &[Arg, OSVersionStr] = Arguments;
1756+ if (Arg)
17421757 return ;
17431758 assert (Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
17441759 " Invalid kind" );
@@ -1763,25 +1778,24 @@ struct DarwinPlatform {
17631778 // DriverKit always explicitly provides a version in the triple.
17641779 return ;
17651780 }
1766- Argument = Args.MakeJoinedArg (nullptr , Opts.getOption (Opt),
1767- ResolvedOSVersion.getAsString ());
1768- Args.append (Argument);
1781+ Arg = Args.MakeJoinedArg (nullptr , Opts.getOption (Opt), OSVersionStr);
1782+ Args.append (Arg);
17691783 }
17701784
17711785 // / Returns the OS version with the argument / environment variable that
17721786 // / specified it.
17731787 std::string getAsString (DerivedArgList &Args, const OptTable &Opts) {
1788+ auto &[Arg, OSVersionStr] = Arguments;
17741789 switch (Kind) {
17751790 case TargetArg:
17761791 case MTargetOSArg:
17771792 case OSVersionArg:
17781793 case InferredFromSDK:
17791794 case InferredFromArch:
1780- assert (Argument && " OS version argument not yet inferred" );
1781- return Argument ->getAsString (Args);
1795+ assert (Arg && " OS version argument not yet inferred" );
1796+ return Arg ->getAsString (Args);
17821797 case DeploymentTargetEnv:
1783- return (llvm::Twine (EnvVarName) + " =" + ResolvedOSVersion.getAsString ())
1784- .str ();
1798+ return (llvm::Twine (EnvVarName) + " =" + OSVersionStr).str ();
17851799 }
17861800 llvm_unreachable (" Unsupported Darwin Source Kind" );
17871801 }
@@ -1797,7 +1811,7 @@ struct DarwinPlatform {
17971811 Environment = DarwinEnvironmentKind::MacCatalyst;
17981812 // The minimum native macOS target for MacCatalyst is macOS 10.15.
17991813 ZipperedOSVersion = VersionTuple (10 , 15 );
1800- if (providedOSVersion () && SDKInfo) {
1814+ if (hasOSVersion () && SDKInfo) {
18011815 if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping (
18021816 DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair ())) {
18031817 if (auto MacOSVersion = MacCatalystToMacOSMapping->map (
@@ -1879,19 +1893,23 @@ struct DarwinPlatform {
18791893 // / the platform from the SDKPath.
18801894 DarwinSDKInfo inferSDKInfo () {
18811895 assert (Kind == InferredFromSDK && " can infer SDK info only" );
1882- return DarwinSDKInfo (ResolvedOSVersion ,
1896+ return DarwinSDKInfo (getOSVersion () ,
18831897 /* MaximumDeploymentTarget=*/
1884- VersionTuple (ResolvedOSVersion .getMajor (), 0 , 99 ),
1898+ VersionTuple (getOSVersion () .getMajor (), 0 , 99 ),
18851899 getOSFromPlatform (Platform));
18861900 }
18871901
18881902private:
18891903 DarwinPlatform (SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
1890- : Kind(Kind), Platform(Platform), Argument(Argument) {}
1904+ : Kind(Kind), Platform(Platform),
1905+ Arguments ({Argument, VersionTuple ().getAsString ()}) {}
18911906 DarwinPlatform (SourceKind Kind, DarwinPlatformKind Platform,
18921907 VersionTuple Value, Arg *Argument = nullptr )
1893- : Kind(Kind), Platform(Platform), ResolvedOSVersion(Value),
1894- ProvidedOSVersion (!Value.empty()), Argument(Argument) {}
1908+ : Kind(Kind), Platform(Platform),
1909+ Arguments({Argument, Value.getAsString ()}) {
1910+ if (!Value.empty ())
1911+ UnderlyingOSVersion = Value;
1912+ }
18951913
18961914 static VersionTuple getVersionFromString (const StringRef Input) {
18971915 llvm::VersionTuple Version;
@@ -1947,14 +1965,12 @@ struct DarwinPlatform {
19471965 // OSVersion tied to the main target value.
19481966 VersionTuple ZipperedOSVersion;
19491967 // We allow multiple ways to set or default the OS
1950- // version used for compilation. The ResolvedOSVersion always represents what
1951- // will be used.
1952- VersionTuple ResolvedOSVersion;
1953- // Track whether the OS deployment version was explicitly set on creation.
1954- // This can be used for overidding the resolved version or error reporting.
1955- bool ProvidedOSVersion = false ;
1968+ // version used for compilation. When set, UnderlyingOSVersion represents
1969+ // the intended version to match the platform information computed from
1970+ // arguments.
1971+ std::optional<VersionTuple> UnderlyingOSVersion;
19561972 bool InferSimulatorFromArch = true ;
1957- Arg *Argument ;
1973+ std::pair< Arg *, std::string> Arguments ;
19581974 StringRef EnvVarName;
19591975 // When compiling for a zippered target, this value represents the target
19601976 // triple encoded in the target variant.
@@ -2151,9 +2167,10 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
21512167 // The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
21522168 return CreatePlatformFromSDKName (dropSDKNamePrefix (SDK));
21532169}
2154-
2155- VersionTuple getOSVersion (llvm::Triple::OSType OS, const llvm::Triple &Triple,
2156- const Driver &TheDriver) {
2170+ // Compute & get the OS Version when the target triple omitted one.
2171+ VersionTuple getInferredOSVersion (llvm::Triple::OSType OS,
2172+ const llvm::Triple &Triple,
2173+ const Driver &TheDriver) {
21572174 VersionTuple OsVersion;
21582175 llvm::Triple SystemTriple (llvm::sys::getProcessTriple ());
21592176 switch (OS) {
@@ -2215,8 +2232,8 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
22152232 OSTy = llvm::Triple::MacOSX;
22162233 if (OSTy == llvm::Triple::UnknownOS)
22172234 return std::nullopt ;
2218- return DarwinPlatform::createFromArch (OSTy,
2219- getOSVersion (OSTy, Triple, TheDriver));
2235+ return DarwinPlatform::createFromArch (
2236+ OSTy, getInferredOSVersion (OSTy, Triple, TheDriver));
22202237}
22212238
22222239// / Returns the deployment target that's specified using the -target option.
@@ -2228,7 +2245,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
22282245 if (Triple.getOS () == llvm::Triple::Darwin ||
22292246 Triple.getOS () == llvm::Triple::UnknownOS)
22302247 return std::nullopt ;
2231- VersionTuple OSVersion = getOSVersion (Triple.getOS (), Triple, TheDriver);
22322248 std::optional<llvm::Triple> TargetVariantTriple;
22332249 for (const Arg *A : Args.filtered (options::OPT_darwin_target_variant)) {
22342250 llvm::Triple TVT (A->getValue ());
@@ -2258,9 +2274,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
22582274 Triple, Args.getLastArg (options::OPT_target), TargetVariantTriple,
22592275 SDKInfo);
22602276
2261- // Override the OSVersion if it doesn't match the one from the triple.
2262- if (Triple.getOSVersion () != OSVersion)
2263- PlatformAndVersion.setOSVersion (OSVersion);
22642277 return PlatformAndVersion;
22652278}
22662279
@@ -2350,6 +2363,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
23502363 getDriver ().Diag (diag::err_drv_cannot_mix_options)
23512364 << TargetArgStr << MTargetOSArgStr;
23522365 }
2366+ // Implicitly allow resolving the OS version when it wasn't explicitly set.
2367+ bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion ();
2368+ if (!TripleProvidedOSVersion)
2369+ PlatformAndVersion->setOSVersion (
2370+ getInferredOSVersion (getTriple ().getOS (), getTriple (), getDriver ()));
2371+
23532372 std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
23542373 getDeploymentTargetFromOSVersionArg (Args, getDriver ());
23552374 if (PlatformAndVersionFromOSVersionArg) {
@@ -2372,7 +2391,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
23722391 // the -target does not include an OS version.
23732392 if (PlatformAndVersion->getPlatform () ==
23742393 PlatformAndVersionFromOSVersionArg->getPlatform () &&
2375- !PlatformAndVersion-> providedOSVersion () ) {
2394+ !TripleProvidedOSVersion ) {
23762395 PlatformAndVersion->setOSVersion (
23772396 PlatformAndVersionFromOSVersionArg->getOSVersion ());
23782397 } else {
@@ -2451,8 +2470,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
24512470 bool HadExtra;
24522471 // The major version should not be over this number.
24532472 const unsigned MajorVersionLimit = 1000 ;
2454- const std::string OSVersionStr =
2455- PlatformAndVersion-> getOSVersion () .getAsString ();
2473+ const VersionTuple OSVersion = PlatformAndVersion-> takeOSVersion ();
2474+ const std::string OSVersionStr = OSVersion .getAsString ();
24562475 // Set the tool chain target information.
24572476 if (Platform == MacOS) {
24582477 if (!Driver::GetReleaseVersion (OSVersionStr, Major, Minor, Micro,
0 commit comments