Author: Cyndy Ishida Date: 2025-06-05T11:37:51-07:00 New Revision: 752adc36ef5ae4d0924675f4e5a43c3ec380b35b
URL: https://github.com/llvm/llvm-project/commit/752adc36ef5ae4d0924675f4e5a43c3ec380b35b DIFF: https://github.com/llvm/llvm-project/commit/752adc36ef5ae4d0924675f4e5a43c3ec380b35b.diff LOG: [clang][Darwin] Simplify deployment version assignment in the Driver (#142013) 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. Added: Modified: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/lib/Driver/ToolChains/Darwin.cpp clang/test/Driver/darwin-debug-flags.c clang/test/Driver/darwin-version.c Removed: ################################################################################ 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 0be7180098359..70737927145bf 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -1678,7 +1678,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. @@ -1707,23 +1708,33 @@ struct DarwinPlatform { InferSimulatorFromArch = false; } - StringRef getOSVersion() const { - if (Kind == OSVersionArg) - return Argument->getValue(); - return OSVersion; + const VersionTuple getOSVersion() const { + return UnderlyingOSVersion.value_or(VersionTuple()); } - void setOSVersion(StringRef S) { - assert(Kind == TargetArg && "Unexpected kind!"); - OSVersion = std::string(S); + 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), + getOSVersion()); } - bool hasOSVersion() const { return HasOSVersion; } + void setOSVersion(const VersionTuple &Version) { + UnderlyingOSVersion = Version; + } + + bool hasOSVersion() const { return UnderlyingOSVersion.has_value(); } - 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. @@ -1738,7 +1749,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,23 +1775,24 @@ struct DarwinPlatform { // DriverKit always explicitly provides a version in the triple. return; } - Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion); - 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) + "=" + OSVersion).str(); + return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str(); } llvm_unreachable("Unsupported Darwin Source Kind"); } @@ -1794,13 +1807,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 (hasOSVersion() && 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; } } } @@ -1810,8 +1823,8 @@ struct DarwinPlatform { if (TargetVariantTriple) { auto TargetVariantVersion = TargetVariantTriple->getOSVersion(); if (TargetVariantVersion.getMajor()) { - if (TargetVariantVersion < NativeTargetVersion) - NativeTargetVersion = TargetVariantVersion; + if (TargetVariantVersion < ZipperedOSVersion) + ZipperedOSVersion = TargetVariantVersion; } } break; @@ -1822,14 +1835,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; @@ -1838,38 +1849,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 @@ -1877,22 +1890,31 @@ 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(getOSVersion(), + /*MaximumDeploymentTarget=*/ + VersionTuple(getOSVersion().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) {} + : Kind(Kind), Platform(Platform), + Arguments({Argument, VersionTuple().getAsString()}) {} + DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, + VersionTuple Value, Arg *Argument = nullptr) + : Kind(Kind), Platform(Platform), + Arguments({Argument, Value.getAsString()}) { + if (!Value.empty()) + UnderlyingOSVersion = Value; + } + + 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) { @@ -1935,11 +1957,20 @@ struct DarwinPlatform { SourceKind Kind; DarwinPlatformKind Platform; DarwinEnvironmentKind Environment = DarwinEnvironmentKind::NativeEnvironment; - VersionTuple NativeTargetVersion; - std::string OSVersion; - bool HasOSVersion = true, InferSimulatorFromArch = true; - Arg *Argument; + // 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. When set, UnderlyingOSVersion represents + // the intended version to match the platform information computed from + // arguments. + std::optional<VersionTuple> UnderlyingOSVersion; + bool InferSimulatorFromArch = true; + 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. std::optional<llvm::Triple> TargetVariantTriple; }; @@ -1957,6 +1988,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) @@ -1965,30 +2009,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); @@ -2121,9 +2164,10 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args, // The SDK can be an SDK variant with a name like `<prefix>.<platform>`. return CreatePlatformFromSDKName(dropSDKNamePrefix(SDK)); } - -std::string 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) { @@ -2162,12 +2206,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. @@ -2190,8 +2229,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. @@ -2203,7 +2242,6 @@ 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); std::optional<llvm::Triple> TargetVariantTriple; for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) { llvm::Triple TVT(A->getValue()); @@ -2229,9 +2267,11 @@ std::optional<DarwinPlatform> getDeploymentTargetFromTargetArg( << A->getSpelling() << A->getValue(); } } - return DarwinPlatform::createFromTarget(Triple, OSVersion, - Args.getLastArg(options::OPT_target), - TargetVariantTriple, SDKInfo); + DarwinPlatform PlatformAndVersion = DarwinPlatform::createFromTarget( + Triple, Args.getLastArg(options::OPT_target), TargetVariantTriple, + SDKInfo); + + return PlatformAndVersion; } /// Returns the deployment target that's specified using the -mtargetos option. @@ -2310,119 +2350,144 @@ 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> PlatformAndVersion = getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo); - if (OSTarget) { + if (PlatformAndVersion) { // 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 = PlatformAndVersion->getAsString(Args, Opts); std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args); getDriver().Diag(diag::err_drv_cannot_mix_options) << TargetArgStr << MTargetOSArgStr; } - std::optional<DarwinPlatform> OSVersionArgTarget = + // 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 (OSVersionArgTarget) { + if (PlatformAndVersionFromOSVersionArg) { unsigned TargetMajor, TargetMinor, TargetMicro; 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 (PlatformAndVersion->getPlatform() != + PlatformAndVersionFromOSVersionArg->getPlatform() || + (Driver::GetReleaseVersion( + PlatformAndVersion->getOSVersion().getAsString(), TargetMajor, + TargetMinor, TargetMicro, TargetExtra) && + Driver::GetReleaseVersion( + 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 (OSTarget->getPlatform() == OSVersionArgTarget->getPlatform() && - !OSTarget->hasOSVersion()) { - OSTarget->setOSVersion(OSVersionArgTarget->getOSVersion()); + if (PlatformAndVersion->getPlatform() == + PlatformAndVersionFromOSVersionArg->getPlatform() && + !TripleProvidedOSVersion) { + 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 = OSTarget->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 ((OSTarget = 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 = OSTarget->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. - OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver()); + PlatformAndVersion = getDeploymentTargetFromOSVersionArg(Args, getDriver()); // If no deployment target was specified on the command line, check for // environment defines. - if (!OSTarget) { - OSTarget = + if (!PlatformAndVersion) { + PlatformAndVersion = getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); - if (OSTarget) { + if (PlatformAndVersion) { // 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()); + 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 (!OSTarget) { - OSTarget = 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 (OSTarget && !SDKInfo) - SDKInfo = OSTarget->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 (!OSTarget) - OSTarget = + if (!PlatformAndVersion) + PlatformAndVersion = inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver()); } - assert(OSTarget && "Unable to infer Darwin variant"); - OSTarget->addOSVersionMinArgument(Args, Opts); - DarwinPlatformKind Platform = OSTarget->getPlatform(); + 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 = PlatformAndVersion->getCanonicalOSVersion(); + if (CanonicalVersion != PlatformAndVersion->getOSVersion()) { + getDriver().Diag(diag::warn_drv_overriding_deployment_version) + << PlatformAndVersion->getOSVersion().getAsString() + << CanonicalVersion.getAsString(); + PlatformAndVersion->setOSVersion(CanonicalVersion); + } + + 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 VersionTuple OSVersion = PlatformAndVersion->takeOSVersion(); + const std::string OSVersionStr = OSVersion.getAsString(); // Set the tool chain target information. if (Platform == MacOS) { - if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), 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) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); } else if (Platform == IPhoneOS) { - if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), 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) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); ; - if (OSTarget->getEnvironment() == MacCatalyst && + if (PlatformAndVersion->getEnvironment() == MacCatalyst && (Major < 13 || (Major == 13 && Minor < 1))) { getDriver().Diag(diag::err_drv_invalid_version_number) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); Major = 13; Minor = 1; Micro = 0; @@ -2431,12 +2496,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 (PlatformAndVersion->isExplicitlySpecified()) { + if (PlatformAndVersion->getEnvironment() == MacCatalyst) getDriver().Diag(diag::err_invalid_macos_32bit_deployment_target); else getDriver().Diag(diag::warn_invalid_ios_deployment_target) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); // Otherwise, set it to 10.99.99. } else { Major = 10; @@ -2445,46 +2510,46 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { } } } else if (Platform == TvOS) { - if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), 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) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); } else if (Platform == WatchOS) { - if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), 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) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); } else if (Platform == DriverKit) { - if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), 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) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); } else if (Platform == XROS) { - if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), 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) - << OSTarget->getAsString(Args, Opts); + << PlatformAndVersion->getAsString(Args, Opts); } else llvm_unreachable("unknown kind of Darwin platform"); - DarwinEnvironmentKind Environment = OSTarget->getEnvironment(); + DarwinEnvironmentKind Environment = PlatformAndVersion->getEnvironment(); // Recognize iOS targets with an x86 architecture as the iOS simulator. if (Environment == NativeEnvironment && Platform != MacOS && - Platform != DriverKit && OSTarget->canInferSimulatorFromArch() && - getTriple().isX86()) + Platform != DriverKit && + PlatformAndVersion->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 = PlatformAndVersion->getZipperedOSVersion(); + setTarget(Platform, Environment, Major, Minor, Micro, ZipperedOSVersion); + TargetVariantTriple = PlatformAndVersion->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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits