From 2ea701e67a136b834f059d87e389060d60cba05a Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 27 Mar 2014 22:50:05 +0000 Subject: [PATCH] Canonicalise Windows target triple spellings Construct a uniform Windows target triple nomenclature which is congruent to the Linux counterpart. The old triples are normalised to the new canonical form. This cleans up the long-standing issue of odd naming for various Windows environments. There are four different environments on Windows: MSVC: The MS ABI, MSVCRT environment as defined by Microsoft GNU: The MinGW32/MinGW32-W64 environment which uses MSVCRT and auxiliary libraries Itanium: The MSVCRT environment + libc++ built with Itanium ABI Cygnus: The Cygwin environment which uses custom libraries for everything The following spellings are now written as: i686-pc-win32 => i686-pc-windows-msvc i686-pc-mingw32 => i686-pc-windows-gnu i686-pc-cygwin => i686-pc-windows-cygnus This should be sufficiently flexible to allow us to target other windows environments in the future as necessary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204977 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Triple.h | 26 +++++++++++++++++++- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- lib/MC/MCObjectFileInfo.cpp | 4 ++-- lib/Support/Triple.cpp | 24 ++++++++++++++++++- lib/Target/TargetLibraryInfo.cpp | 2 +- lib/Target/X86/X86Subtarget.h | 11 ++++++--- unittests/ADT/TripleTest.cpp | 34 ++++++++++++++++++++++++++- 7 files changed, 93 insertions(+), 10 deletions(-) diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 0eb0420f564..343eb00fe26 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -125,6 +125,10 @@ public: EABI, EABIHF, Android, + + MSVC, + Itanium, + Cygnus, }; enum ObjectFormatType { UnknownObjectFormat, @@ -328,9 +332,29 @@ public: return isMacOSX() || isiOS(); } + bool isWindowsMSVCEnvironment() const { + return getOS() == Triple::Win32 && + (getEnvironment() == Triple::UnknownEnvironment || + getEnvironment() == Triple::MSVC); + } + + bool isKnownWindowsMSVCEnvironment() const { + return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC; + } + + bool isWindowsCygwinEnvironment() const { + return getOS() == Triple::Cygwin || + (getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus); + } + + bool isWindowsGNUEnvironment() const { + return getOS() == Triple::MinGW32 || + (getOS() == Triple::Win32 && getEnvironment() == Triple::GNU); + } + /// \brief Tests for either Cygwin or MinGW OS bool isOSCygMing() const { - return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; + return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment(); } /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment. diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 086b08173eb..c3afc8ba8c2 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -223,7 +223,7 @@ bool AsmPrinter::doInitialization(Module &M) { } if (MAI->doesSupportDebugInformation()) { - if (Triple(TM.getTargetTriple()).getOS() == Triple::Win32) { + if (Triple(TM.getTargetTriple()).isKnownWindowsMSVCEnvironment()) { Handlers.push_back(HandlerInfo(new WinCodeViewLineTables(this), DbgTimerName, CodeViewLineTablesGroupName)); diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index c27b88b9689..87ff0d359d1 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -566,7 +566,7 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); - if (T.getOS() == Triple::Win32) { + if (T.isKnownWindowsMSVCEnvironment()) { StaticCtorSection = Ctx->getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | @@ -582,7 +582,7 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { } - if (T.getOS() == Triple::Win32) { + if (T.isKnownWindowsMSVCEnvironment()) { StaticDtorSection = Ctx->getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 0b8e9a66856..85a3422bb7c 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -129,7 +129,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case NetBSD: return "netbsd"; case OpenBSD: return "openbsd"; case Solaris: return "solaris"; - case Win32: return "win32"; + case Win32: return "windows"; case Haiku: return "haiku"; case Minix: return "minix"; case RTEMS: return "rtems"; @@ -155,6 +155,9 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { case EABI: return "eabi"; case EABIHF: return "eabihf"; case Android: return "android"; + case MSVC: return "msvc"; + case Itanium: return "itanium"; + case Cygnus: return "cygnus"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -287,6 +290,7 @@ static Triple::OSType parseOS(StringRef OSName) { .StartsWith("openbsd", Triple::OpenBSD) .StartsWith("solaris", Triple::Solaris) .StartsWith("win32", Triple::Win32) + .StartsWith("windows", Triple::Win32) .StartsWith("haiku", Triple::Haiku) .StartsWith("minix", Triple::Minix) .StartsWith("rtems", Triple::RTEMS) @@ -309,6 +313,9 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("code16", Triple::CODE16) .StartsWith("gnu", Triple::GNU) .StartsWith("android", Triple::Android) + .StartsWith("msvc", Triple::MSVC) + .StartsWith("itanium", Triple::Itanium) + .StartsWith("cygnus", Triple::Cygnus) .Default(Triple::UnknownEnvironment); } @@ -516,6 +523,21 @@ std::string Triple::normalize(StringRef Str) { // Special case logic goes here. At this point Arch, Vendor and OS have the // correct values for the computed components. + if (OS == Triple::Win32) { + Components.resize(4); + Components[2] = "windows"; + if (Environment == UnknownEnvironment && ObjectFormat == UnknownObjectFormat) + Components[3] = "msvc"; + } else if (OS == Triple::MinGW32) { + Components.resize(4); + Components[2] = "windows"; + Components[3] = (ObjectFormat == Triple::ELF) ? "gnuelf" : "gnu"; + } else if (OS == Triple::Cygwin) { + Components.resize(4); + Components[2] = "windows"; + Components[3] = "cygnus"; + } + // Stick the corrected components back together to form the normalized string. std::string Normalized; for (unsigned i = 0, e = Components.size(); i != e; ++i) { diff --git a/lib/Target/TargetLibraryInfo.cpp b/lib/Target/TargetLibraryInfo.cpp index 063151601b8..7f8919772f7 100644 --- a/lib/Target/TargetLibraryInfo.cpp +++ b/lib/Target/TargetLibraryInfo.cpp @@ -417,7 +417,7 @@ static void initialize(TargetLibraryInfo &TLI, const Triple &T, TLI.setUnavailable(LibFunc::fiprintf); } - if (T.getOS() == Triple::Win32) { + if (T.isKnownWindowsMSVCEnvironment()) { // Win32 does not support long double TLI.setUnavailable(LibFunc::acosl); TLI.setUnavailable(LibFunc::asinl); diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index 51b2e51d202..d66d8595059 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -343,9 +343,14 @@ public: bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); } bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); } - bool isTargetWindows() const { return TargetTriple.getOS() == Triple::Win32; } - bool isTargetMingw() const { return TargetTriple.getOS() == Triple::MinGW32; } - bool isTargetCygwin() const { return TargetTriple.getOS() == Triple::Cygwin; } + bool isTargetWindows() const { + return TargetTriple.isOSWindows() && + !TargetTriple.isWindowsGNUEnvironment(); + } + bool isTargetMingw() const { return TargetTriple.isWindowsGNUEnvironment(); } + bool isTargetCygwin() const { + return TargetTriple.isWindowsCygwinEnvironment(); + } bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } bool isOSWindows() const { return TargetTriple.isOSWindows(); } diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index efd09157a47..04b795ef8f7 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -190,6 +190,9 @@ TEST(TripleTest, Normalization) { ++Vendor) { C[1] = Triple::getVendorTypeName(Triple::VendorType(Vendor)); for (int OS = 1+Triple::UnknownOS; OS <= Triple::Minix; ++OS) { + if (OS == Triple::Cygwin || OS == Triple::MinGW32 || OS == Triple::Win32) + continue; + C[2] = Triple::getOSTypeName(Triple::OSType(OS)); std::string E = Join(C[0], C[1], C[2]); @@ -238,7 +241,7 @@ TEST(TripleTest, Normalization) { // Various real-world funky triples. The value returned by GCC's config.sub // is given in the comment. - EXPECT_EQ("i386--mingw32", Triple::normalize("i386-mingw32")); // i386-pc-mingw32 + EXPECT_EQ("i386--windows-gnu", Triple::normalize("i386-mingw32")); // i386-pc-mingw32 EXPECT_EQ("x86_64--linux-gnu", Triple::normalize("x86_64-linux-gnu")); // x86_64-pc-linux-gnu EXPECT_EQ("i486--linux-gnu", Triple::normalize("i486-linux-gnu")); // i486-pc-linux-gnu EXPECT_EQ("i386-redhat-linux", Triple::normalize("i386-redhat-linux")); // i386-redhat-linux-gnu @@ -515,4 +518,33 @@ TEST(TripleTest, FileFormat) { EXPECT_EQ(Triple::ELF, T.getObjectFormat()); } +TEST(TripleTest, NormalizeWindows) { + EXPECT_EQ("i686-pc-windows-msvc", Triple::normalize("i686-pc-win32")); + EXPECT_EQ("i686--windows-msvc", Triple::normalize("i686-win32")); + EXPECT_EQ("i686-pc-windows-gnu", Triple::normalize("i686-pc-mingw32")); + EXPECT_EQ("i686--windows-gnu", Triple::normalize("i686-mingw32")); + EXPECT_EQ("i686-pc-windows-gnu", Triple::normalize("i686-pc-mingw32-w64")); + EXPECT_EQ("i686--windows-gnu", Triple::normalize("i686-mingw32-w64")); + EXPECT_EQ("i686-pc-windows-cygnus", Triple::normalize("i686-pc-cygwin")); + EXPECT_EQ("i686--windows-cygnus", Triple::normalize("i686-cygwin")); + + EXPECT_EQ("x86_64-pc-windows-msvc", Triple::normalize("x86_64-pc-win32")); + EXPECT_EQ("x86_64--windows-msvc", Triple::normalize("x86_64-win32")); + EXPECT_EQ("x86_64-pc-windows-gnu", Triple::normalize("x86_64-pc-mingw32")); + EXPECT_EQ("x86_64--windows-gnu", Triple::normalize("x86_64-mingw32")); + EXPECT_EQ("x86_64-pc-windows-gnu", Triple::normalize("x86_64-pc-mingw32-w64")); + EXPECT_EQ("x86_64--windows-gnu", Triple::normalize("x86_64-mingw32-w64")); + + EXPECT_EQ("i686-pc-windows-elf", Triple::normalize("i686-pc-win32-elf")); + EXPECT_EQ("i686--windows-elf", Triple::normalize("i686-win32-elf")); + EXPECT_EQ("i686-pc-windows-macho", Triple::normalize("i686-pc-win32-macho")); + EXPECT_EQ("i686--windows-macho", Triple::normalize("i686-win32-macho")); + + EXPECT_EQ("x86_64-pc-windows-elf", Triple::normalize("x86_64-pc-win32-elf")); + EXPECT_EQ("x86_64--windows-elf", Triple::normalize("x86_64-win32-elf")); + EXPECT_EQ("x86_64-pc-windows-macho", Triple::normalize("x86_64-pc-win32-macho")); + EXPECT_EQ("x86_64--windows-macho", Triple::normalize("x86_64-win32-macho")); + + EXPECT_EQ("i686-pc-windows-itanium", Triple::normalize("i686-pc-windows-itanium")); +} } -- 2.34.1