@@ -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,29 @@ 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 (const VersionTuple &Version) {
1732
+ UnderlyingOSVersion = Version;
1733
+ }
1720
1734
1721
- bool providedOSVersion () const { return ProvidedOSVersion ; }
1735
+ bool hasOSVersion () const { return UnderlyingOSVersion. has_value () ; }
1722
1736
1723
1737
VersionTuple getZipperedOSVersion () const {
1724
1738
assert (Environment == DarwinEnvironmentKind::MacCatalyst &&
@@ -1738,7 +1752,8 @@ struct DarwinPlatform {
1738
1752
1739
1753
// / Adds the -m<os>-version-min argument to the compiler invocation.
1740
1754
void addOSVersionMinArgument (DerivedArgList &Args, const OptTable &Opts) {
1741
- if (Argument)
1755
+ auto &[Arg, OSVersionStr] = Arguments;
1756
+ if (Arg)
1742
1757
return ;
1743
1758
assert (Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1744
1759
" Invalid kind" );
@@ -1763,25 +1778,24 @@ struct DarwinPlatform {
1763
1778
// DriverKit always explicitly provides a version in the triple.
1764
1779
return ;
1765
1780
}
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);
1769
1783
}
1770
1784
1771
1785
// / Returns the OS version with the argument / environment variable that
1772
1786
// / specified it.
1773
1787
std::string getAsString (DerivedArgList &Args, const OptTable &Opts) {
1788
+ auto &[Arg, OSVersionStr] = Arguments;
1774
1789
switch (Kind) {
1775
1790
case TargetArg:
1776
1791
case MTargetOSArg:
1777
1792
case OSVersionArg:
1778
1793
case InferredFromSDK:
1779
1794
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);
1782
1797
case DeploymentTargetEnv:
1783
- return (llvm::Twine (EnvVarName) + " =" + ResolvedOSVersion.getAsString ())
1784
- .str ();
1798
+ return (llvm::Twine (EnvVarName) + " =" + OSVersionStr).str ();
1785
1799
}
1786
1800
llvm_unreachable (" Unsupported Darwin Source Kind" );
1787
1801
}
@@ -1797,7 +1811,7 @@ struct DarwinPlatform {
1797
1811
Environment = DarwinEnvironmentKind::MacCatalyst;
1798
1812
// The minimum native macOS target for MacCatalyst is macOS 10.15.
1799
1813
ZipperedOSVersion = VersionTuple (10 , 15 );
1800
- if (providedOSVersion () && SDKInfo) {
1814
+ if (hasOSVersion () && SDKInfo) {
1801
1815
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping (
1802
1816
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair ())) {
1803
1817
if (auto MacOSVersion = MacCatalystToMacOSMapping->map (
@@ -1879,19 +1893,23 @@ struct DarwinPlatform {
1879
1893
// / the platform from the SDKPath.
1880
1894
DarwinSDKInfo inferSDKInfo () {
1881
1895
assert (Kind == InferredFromSDK && " can infer SDK info only" );
1882
- return DarwinSDKInfo (ResolvedOSVersion ,
1896
+ return DarwinSDKInfo (getOSVersion () ,
1883
1897
/* MaximumDeploymentTarget=*/
1884
- VersionTuple (ResolvedOSVersion .getMajor (), 0 , 99 ),
1898
+ VersionTuple (getOSVersion () .getMajor (), 0 , 99 ),
1885
1899
getOSFromPlatform (Platform));
1886
1900
}
1887
1901
1888
1902
private:
1889
1903
DarwinPlatform (SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
1890
- : Kind(Kind), Platform(Platform), Argument(Argument) {}
1904
+ : Kind(Kind), Platform(Platform),
1905
+ Arguments ({Argument, VersionTuple ().getAsString ()}) {}
1891
1906
DarwinPlatform (SourceKind Kind, DarwinPlatformKind Platform,
1892
1907
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
+ }
1895
1913
1896
1914
static VersionTuple getVersionFromString (const StringRef Input) {
1897
1915
llvm::VersionTuple Version;
@@ -1947,14 +1965,12 @@ struct DarwinPlatform {
1947
1965
// OSVersion tied to the main target value.
1948
1966
VersionTuple ZipperedOSVersion;
1949
1967
// 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;
1956
1972
bool InferSimulatorFromArch = true ;
1957
- Arg *Argument ;
1973
+ std::pair< Arg *, std::string> Arguments ;
1958
1974
StringRef EnvVarName;
1959
1975
// When compiling for a zippered target, this value represents the target
1960
1976
// triple encoded in the target variant.
@@ -2151,9 +2167,10 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
2151
2167
// The SDK can be an SDK variant with a name like `<prefix>.<platform>`.
2152
2168
return CreatePlatformFromSDKName (dropSDKNamePrefix (SDK));
2153
2169
}
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) {
2157
2174
VersionTuple OsVersion;
2158
2175
llvm::Triple SystemTriple (llvm::sys::getProcessTriple ());
2159
2176
switch (OS) {
@@ -2215,8 +2232,8 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
2215
2232
OSTy = llvm::Triple::MacOSX;
2216
2233
if (OSTy == llvm::Triple::UnknownOS)
2217
2234
return std::nullopt;
2218
- return DarwinPlatform::createFromArch (OSTy,
2219
- getOSVersion (OSTy, Triple, TheDriver));
2235
+ return DarwinPlatform::createFromArch (
2236
+ OSTy, getInferredOSVersion (OSTy, Triple, TheDriver));
2220
2237
}
2221
2238
2222
2239
// / Returns the deployment target that's specified using the -target option.
@@ -2228,7 +2245,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2228
2245
if (Triple.getOS () == llvm::Triple::Darwin ||
2229
2246
Triple.getOS () == llvm::Triple::UnknownOS)
2230
2247
return std::nullopt;
2231
- VersionTuple OSVersion = getOSVersion (Triple.getOS (), Triple, TheDriver);
2232
2248
std::optional<llvm::Triple> TargetVariantTriple;
2233
2249
for (const Arg *A : Args.filtered (options::OPT_darwin_target_variant)) {
2234
2250
llvm::Triple TVT (A->getValue ());
@@ -2258,9 +2274,6 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
2258
2274
Triple, Args.getLastArg (options::OPT_target), TargetVariantTriple,
2259
2275
SDKInfo);
2260
2276
2261
- // Override the OSVersion if it doesn't match the one from the triple.
2262
- if (Triple.getOSVersion () != OSVersion)
2263
- PlatformAndVersion.setOSVersion (OSVersion);
2264
2277
return PlatformAndVersion;
2265
2278
}
2266
2279
@@ -2350,6 +2363,12 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2350
2363
getDriver ().Diag (diag::err_drv_cannot_mix_options)
2351
2364
<< TargetArgStr << MTargetOSArgStr;
2352
2365
}
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
+
2353
2372
std::optional<DarwinPlatform> PlatformAndVersionFromOSVersionArg =
2354
2373
getDeploymentTargetFromOSVersionArg (Args, getDriver ());
2355
2374
if (PlatformAndVersionFromOSVersionArg) {
@@ -2372,7 +2391,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2372
2391
// the -target does not include an OS version.
2373
2392
if (PlatformAndVersion->getPlatform () ==
2374
2393
PlatformAndVersionFromOSVersionArg->getPlatform () &&
2375
- !PlatformAndVersion-> providedOSVersion () ) {
2394
+ !TripleProvidedOSVersion ) {
2376
2395
PlatformAndVersion->setOSVersion (
2377
2396
PlatformAndVersionFromOSVersionArg->getOSVersion ());
2378
2397
} else {
@@ -2451,8 +2470,8 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
2451
2470
bool HadExtra;
2452
2471
// The major version should not be over this number.
2453
2472
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 ();
2456
2475
// Set the tool chain target information.
2457
2476
if (Platform == MacOS) {
2458
2477
if (!Driver::GetReleaseVersion (OSVersionStr, Major, Minor, Micro,
0 commit comments