From 1c4a42a4d88eeca8de47d615a23fc654a39abdb7 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Mon, 22 Jun 2020 16:32:35 -0700 Subject: [PATCH] [Triple] support macOS 11 os version number macOS goes to 11! This commit adds support for the new version number by ensuring that existing version comparison routines, and the 'darwin' OS identifier understands the new numbering scheme. It also adds a new utility method 'getCanonicalVersionForOS', which lets users translate some uses of macOS 10.16 into macOS 11. This utility method will be used in upcoming clang and swift commits. Differential Revision: https://reviews.llvm.org/D82337 --- llvm/include/llvm/ADT/Triple.h | 18 +++++------- llvm/lib/Support/Triple.cpp | 47 ++++++++++++++++++++++++++---- llvm/unittests/ADT/TripleTest.cpp | 60 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h index 8e46265..8967961 100644 --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -19,6 +19,8 @@ namespace llvm { +class VersionTuple; + /// Triple - Helper class for working with autoconf configuration names. For /// historical reasons, we also call these 'triples' (they used to contain /// exactly three fields). @@ -438,17 +440,7 @@ public: /// compatibility, which handles supporting skewed version numbering schemes /// used by the "darwin" triples. bool isMacOSXVersionLT(unsigned Major, unsigned Minor = 0, - unsigned Micro = 0) const { - assert(isMacOSX() && "Not an OS X triple!"); - - // If this is OS X, expect a sane version number. - if (getOS() == Triple::MacOSX) - return isOSVersionLT(Major, Minor, Micro); - - // Otherwise, compare to the "Darwin" number. - assert(Major == 10 && "Unexpected major version"); - return isOSVersionLT(Minor + 4, Micro, 0); - } + unsigned Micro = 0) const; /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both /// "darwin" and "osx" as OS X triples. @@ -902,6 +894,10 @@ public: static ArchType getArchTypeForLLVMName(StringRef Str); /// @} + + /// Returns a canonicalized OS version number for the specified OS. + static VersionTuple getCanonicalVersionForOS(OSType OSKind, + const VersionTuple &Version); }; } // End llvm namespace diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp index da6b877..75ec257 100644 --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/TargetParser.h" +#include "llvm/Support/VersionTuple.h" #include #include using namespace llvm; @@ -1086,17 +1087,23 @@ bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor, // Darwin version numbers are skewed from OS X versions. if (Major < 4) return false; - Micro = 0; - Minor = Major - 4; - Major = 10; + if (Major <= 19) { + Micro = 0; + Minor = Major - 4; + Major = 10; + } else { + Micro = 0; + Minor = 0; + // darwin20+ corresponds to macOS 11+. + Major = 11 + Major - 20; + } break; case MacOSX: // Default to 10.4. if (Major == 0) { Major = 10; Minor = 4; - } - if (Major != 10) + } else if (Major < 10) return false; break; case IOS: @@ -1600,6 +1607,23 @@ std::string Triple::merge(const Triple &Other) const { return Other.str(); } +bool Triple::isMacOSXVersionLT(unsigned Major, unsigned Minor, + unsigned Micro) const { + assert(isMacOSX() && "Not an OS X triple!"); + + // If this is OS X, expect a sane version number. + if (getOS() == Triple::MacOSX) + return isOSVersionLT(Major, Minor, Micro); + + // Otherwise, compare to the "Darwin" number. + if (Major == 10) { + return isOSVersionLT(Minor + 4, Micro, 0); + } else { + assert(Major >= 11 && "Unexpected major version"); + return isOSVersionLT(Major - 11 + 20, Minor, Micro); + } +} + StringRef Triple::getARMCPUForArch(StringRef MArch) const { if (MArch.empty()) MArch = getArchName(); @@ -1662,3 +1686,16 @@ StringRef Triple::getARMCPUForArch(StringRef MArch) const { llvm_unreachable("invalid arch name"); } + +VersionTuple Triple::getCanonicalVersionForOS(OSType OSKind, + const VersionTuple &Version) { + switch (OSKind) { + case MacOSX: + // macOS 10.16 is canonicalized to macOS 11. + if (Version == VersionTuple(10, 16)) + return VersionTuple(11, 0); + LLVM_FALLTHROUGH; + default: + return Version; + } +} diff --git a/llvm/unittests/ADT/TripleTest.cpp b/llvm/unittests/ADT/TripleTest.cpp index ca00837..dc7a28c 100644 --- a/llvm/unittests/ADT/TripleTest.cpp +++ b/llvm/unittests/ADT/TripleTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Triple.h" +#include "llvm/Support/VersionTuple.h" #include "gtest/gtest.h" using namespace llvm; @@ -1222,6 +1223,44 @@ TEST(TripleTest, getOSVersion) { EXPECT_EQ((unsigned)0, Minor); EXPECT_EQ((unsigned)0, Micro); + T = Triple("x86_64-apple-macos11.0"); + EXPECT_TRUE(T.isMacOSX()); + EXPECT_FALSE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)11, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("arm64-apple-macosx11.5.8"); + EXPECT_TRUE(T.isMacOSX()); + EXPECT_FALSE(T.isiOS()); + EXPECT_FALSE(T.isArch16Bit()); + EXPECT_FALSE(T.isArch32Bit()); + EXPECT_TRUE(T.isArch64Bit()); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)11, Major); + EXPECT_EQ((unsigned)5, Minor); + EXPECT_EQ((unsigned)8, Micro); + + // 10.16 forms a valid triple, even though it's not + // a version of a macOS. + T = Triple("x86_64-apple-macos10.16"); + EXPECT_TRUE(T.isMacOSX()); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)10, Major); + EXPECT_EQ((unsigned)16, Minor); + EXPECT_EQ((unsigned)0, Micro); + + T = Triple("x86_64-apple-darwin20"); + EXPECT_TRUE(T.isMacOSX()); + T.getMacOSXVersion(Major, Minor, Micro); + EXPECT_EQ((unsigned)11, Major); + EXPECT_EQ((unsigned)0, Minor); + EXPECT_EQ((unsigned)0, Micro); + T = Triple("armv7-apple-ios"); EXPECT_FALSE(T.isMacOSX()); EXPECT_TRUE(T.isiOS()); @@ -1273,6 +1312,27 @@ TEST(TripleTest, getOSVersion) { EXPECT_FALSE(T.isSimulatorEnvironment()); } +TEST(TripleTest, isMacOSVersionLT) { + Triple T = Triple("x86_64-apple-macos11"); + EXPECT_TRUE(T.isMacOSXVersionLT(11, 1, 0)); + EXPECT_FALSE(T.isMacOSXVersionLT(10, 15, 0)); + + T = Triple("x86_64-apple-darwin20"); + EXPECT_TRUE(T.isMacOSXVersionLT(11, 1, 0)); + EXPECT_FALSE(T.isMacOSXVersionLT(11, 0, 0)); + EXPECT_FALSE(T.isMacOSXVersionLT(10, 15, 0)); +} + +TEST(TripleTest, CanonicalizeOSVersion) { + EXPECT_EQ(VersionTuple(10, 15, 4), + Triple::getCanonicalVersionForOS(Triple::MacOSX, + VersionTuple(10, 15, 4))); + EXPECT_EQ(VersionTuple(11, 0), Triple::getCanonicalVersionForOS( + Triple::MacOSX, VersionTuple(10, 16))); + EXPECT_EQ(VersionTuple(20), + Triple::getCanonicalVersionForOS(Triple::Darwin, VersionTuple(20))); +} + TEST(TripleTest, FileFormat) { EXPECT_EQ(Triple::ELF, Triple("i686-unknown-linux-gnu").getObjectFormat()); EXPECT_EQ(Triple::ELF, Triple("i686-unknown-freebsd").getObjectFormat()); -- 2.7.4