@@ -1681,7 +1681,8 @@ static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
1681
1681
1682
1682
namespace {
1683
1683
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.
1685
1686
struct DarwinPlatform {
1686
1687
enum SourceKind {
1687
1688
// / The OS was specified using the -target argument.
@@ -1709,16 +1710,27 @@ struct DarwinPlatform {
1709
1710
Environment = Kind;
1710
1711
InferSimulatorFromArch = false ;
1711
1712
}
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
+ }
1713
1725
1714
1726
VersionTuple getCanonicalOSVersion () const {
1715
1727
return llvm::Triple::getCanonicalVersionForOS (getOSFromPlatform (Platform),
1716
- ResolvedOSVersion );
1728
+ getOSVersion () );
1717
1729
}
1718
1730
1719
- void setOSVersion (VersionTuple Version) { ResolvedOSVersion = Version; }
1731
+ void setOSVersion (VersionTuple Version) { UnderlyingOSVersion = Version; }
1720
1732
1721
- bool providedOSVersion () const { return ProvidedOSVersion ; }
1733
+ bool hasOSVersion () const { return UnderlyingOSVersion. has_value () ; }
1722
1734
1723
1735
VersionTuple getZipperedOSVersion () const {
1724
1736
assert (Environment == DarwinEnvironmentKind::MacCatalyst &&
@@ -1738,7 +1750,8 @@ struct DarwinPlatform {
1738
1750
1739
1751
// / Adds the -m<os>-version-min argument to the compiler invocation.
1740
1752
void addOSVersionMinArgument (DerivedArgList &Args, const OptTable &Opts) {
1741
- if (Argument)
1753
+ auto [Arg, OSVersionStr] = Arguments;
1754
+ if (Arg)
1742
1755
return ;
1743
1756
assert (Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1744
1757
" Invalid kind" );
@@ -1763,25 +1776,24 @@ struct DarwinPlatform {
1763
1776
// DriverKit always explicitly provides a version in the triple.
1764
1777
return ;
1765
1778
}
1766
- Argument = Args.MakeJoinedArg (nullptr , Opts.getOption (Opt),
1767
- ResolvedOSVersion.getAsString ());
1768
- Args.append (Argument);
1779
+ Arg = Args.MakeJoinedArg (nullptr , Opts.getOption (Opt), OSVersionStr);
1780
+ Args.append (Arg);
1769
1781
}
1770
1782
1771
1783
// / Returns the OS version with the argument / environment variable that
1772
1784
// / specified it.
1773
1785
std::string getAsString (DerivedArgList &Args, const OptTable &Opts) {
1786
+ auto [Arg, OSVersionStr] = Arguments;
1774
1787
switch (Kind) {
1775
1788
case TargetArg:
1776
1789
case MTargetOSArg:
1777
1790
case OSVersionArg:
1778
1791
case InferredFromSDK:
1779
1792
case InferredFromArch:
1780
- assert (Argument && " OS version argument not yet inferred" );
1781
- return Argument ->getAsString (Args);
1793
+ assert (Arg && " OS version argument not yet inferred" );
1794
+ return Arg ->getAsString (Args);
1782
1795
case DeploymentTargetEnv:
1783
- return (llvm::Twine (EnvVarName) + " =" + ResolvedOSVersion.getAsString ())
1784
- .str ();
1796
+ return (llvm::Twine (EnvVarName) + " =" + OSVersionStr).str ();
1785
1797
}
1786
1798
llvm_unreachable (" Unsupported Darwin Source Kind" );
1787
1799
}
@@ -1797,7 +1809,7 @@ struct DarwinPlatform {
1797
1809
Environment = DarwinEnvironmentKind::MacCatalyst;
1798
1810
// The minimum native macOS target for MacCatalyst is macOS 10.15.
1799
1811
ZipperedOSVersion = VersionTuple (10 , 15 );
1800
- if (providedOSVersion () && SDKInfo) {
1812
+ if (hasOSVersion () && SDKInfo) {
1801
1813
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping (
1802
1814
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair ())) {
1803
1815
if (auto MacOSVersion = MacCatalystToMacOSMapping->map (
@@ -1879,19 +1891,23 @@ struct DarwinPlatform {
1879
1891
// / the platform from the SDKPath.
1880
1892
DarwinSDKInfo inferSDKInfo () {
1881
1893
assert (Kind == InferredFromSDK && " can infer SDK info only" );
1882
- return DarwinSDKInfo (ResolvedOSVersion ,
1894
+ return DarwinSDKInfo (getOSVersion () ,
1883
1895
/* MaximumDeploymentTarget=*/
1884
- VersionTuple (ResolvedOSVersion .getMajor (), 0 , 99 ),
1896
+ VersionTuple (getOSVersion () .getMajor (), 0 , 99 ),
1885
1897
getOSFromPlatform (Platform));
1886
1898
}
1887
1899
1888
1900
private:
1889
1901
DarwinPlatform (SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
1890
- : Kind(Kind), Platform(Platform), Argument(Argument) {}
1902
+ : Kind(Kind), Platform(Platform),
1903
+ Arguments ({Argument, VersionTuple ().getAsString ()}) {}
1891
1904
DarwinPlatform (SourceKind Kind, DarwinPlatformKind Platform,
1892
1905
VersionTuple Value, Arg *Argument = nullptr )
1893
- : Kind(Kind), Platform(Platform), ResolvedOSVersion(Value),
1894
- ProvidedOSVersion (!Value.empty()), Argument(Argument) {}
1906
+ : Kind(Kind), Platform(Platform),
1907
+ Arguments({Argument, Value.getAsString ()}) {
1908
+ if (!Value.empty ())
1909
+ UnderlyingOSVersion = Value;
1910
+ }
1895
1911
1896
1912
static VersionTuple getVersionFromString (const StringRef Input) {
1897
1913
llvm::VersionTuple Version;
@@ -1947,14 +1963,12 @@ struct DarwinPlatform {
1947
1963
// OSVersion tied to the main target value.
1948
1964
VersionTuple ZipperedOSVersion;
1949
1965
// 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 ;
1966
+ // version used for compilation. When set, UnderlyingOSVersion represents
1967
+ // the intended version to match the platform information computed from
1968
+ // arguments.
1969
+ std::optional<VersionTuple> UnderlyingOSVersion;
1956
1970
bool InferSimulatorFromArch = true ;
1957
- Arg *Argument ;
1971
+ std::pair< Arg *, std::string> Arguments ;
1958
1972
StringRef EnvVarName;
1959
1973
// When compiling for a zippered target, this value represents the target
1960
1974
// triple encoded in the target variant.
@@ -2151,9 +2165,10 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
2151
2165
// The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
2152
2166
return CreatePlatformFromSDKName (dropSDKNamePrefix (SDK));
2153
2167
}
2154
-
2155
- VersionTuple getOSVersion (llvm::Triple::OSType OS, const llvm::Triple &Triple,
2156
- const Driver &TheDriver) {
2168
+ // Compute & get the OS Version when the target triple omitted one.
2169
+ VersionTuple getInferredOSVersion (llvm::Triple::OSType OS,
2170
+ const llvm::Triple &Triple,
2171
+ const Driver &TheDriver) {
2157
2172
VersionTuple OsVersion;
2158
2173
llvm::Triple SystemTriple (llvm::sys::getProcessTriple ());
2159
2174
switch (OS) {
@@ -2215,8 +2230,8 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
2215
2230
OSTy = llvm::Triple::MacOSX;
2216
2231
if (OSTy == llvm::Triple::UnknownOS)
2217
2232
return std::nullopt;
2218
- return DarwinPlatform::createFromArch (OSTy,
2219
- getOSVersion (OSTy, Triple, TheDriver));
2233
+ return DarwinPlatform::createFromArch (
2234
+ OSTy, getInferredOSVersion (OSTy, Triple, TheDriver));
2220
2235
}
2221
2236
2222
2237
// / Returns the deployment target that's specified using the -target option.
@@ -2228,7 +2243,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2228
2243
if (Triple.getOS () == llvm::Triple::Darwin ||
2229
2244
Triple.getOS () == llvm::Triple::UnknownOS)
2230
2245
return std::nullopt;
2231
- VersionTuple OSVersion = getOSVersion (Triple.getOS (), Triple, TheDriver);
2232
2246
std::optional<llvm::Triple> TargetVariantTriple;
2233
2247
for (const Arg *A : Args.filtered (options::OPT_darwin_target_variant)) {
2234
2248
llvm::Triple TVT (A->getValue ());
@@ -2258,9 +2272,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2258
2272
Triple, Args.getLastArg (options::OPT_target), TargetVariantTriple,
2259
2273
SDKInfo);
2260
2274
2261
- // Override the OSVersion if it doesn't match the one from the triple.
2262
- if (Triple.getOSVersion () != OSVersion)
2263
- PlatformAndVersion.setOSVersion (OSVersion);
2264
2275
return PlatformAndVersion;
2265
2276
}
2266
2277
@@ -2350,6 +2361,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2350
2361
getDriver ().Diag (diag::err_drv_cannot_mix_options)
2351
2362
<< TargetArgStr << MTargetOSArgStr;
2352
2363
}
2364
+ // Implicitly allow resolving the OS version when it wasn't explicitly set.
2365
+ bool TripleProvidedOSVersion = PlatformAndVersion->hasOSVersion ();
2366
+ if (!TripleProvidedOSVersion)
2367
+ PlatformAndVersion->setOSVersion (
2368
+ getInferredOSVersion (getTriple ().getOS (), getTriple (), getDriver ()));
2369
+
2353
2370
std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2354
2371
getDeploymentTargetFromOSVersionArg (Args, getDriver ());
2355
2372
if (PlatformAndVersionFromOSVersionArg) {
@@ -2372,7 +2389,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2372
2389
// the -target does not include an OS version.
2373
2390
if (PlatformAndVersion->getPlatform () ==
2374
2391
PlatformAndVersionFromOSVersionArg->getPlatform () &&
2375
- !PlatformAndVersion-> providedOSVersion () ) {
2392
+ !TripleProvidedOSVersion ) {
2376
2393
PlatformAndVersion->setOSVersion (
2377
2394
PlatformAndVersionFromOSVersionArg->getOSVersion ());
2378
2395
} else {
@@ -2451,8 +2468,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2451
2468
bool HadExtra;
2452
2469
// The major version should not be over this number.
2453
2470
const unsigned MajorVersionLimit = 1000 ;
2454
- const std::string OSVersionStr =
2455
- PlatformAndVersion-> getOSVersion () .getAsString ();
2471
+ const VersionTuple OSVersion = PlatformAndVersion-> takeOSVersion ();
2472
+ const std::string OSVersionStr = OSVersion .getAsString ();
2456
2473
// Set the tool chain target information.
2457
2474
if (Platform == MacOS) {
2458
2475
if (!Driver::GetReleaseVersion (OSVersionStr, Major, Minor, Micro,
0 commit comments