Canonicalise Windows target triple spellings
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 27 Mar 2014 22:50:05 +0000 (22:50 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 27 Mar 2014 22:50:05 +0000 (22:50 +0000)
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
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/MC/MCObjectFileInfo.cpp
lib/Support/Triple.cpp
lib/Target/TargetLibraryInfo.cpp
lib/Target/X86/X86Subtarget.h
unittests/ADT/TripleTest.cpp

index 0eb0420f564f1c8ac0fcd9c8789489c4548d1320..343eb00fe26c0ca39be0dd9fad756b088283c993 100644 (file)
@@ -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.
index 086b08173eb4e13e38660f13830340be4963d204..c3afc8ba8c21ce8e15ef60088550cfa7f1dd94dd 100644 (file)
@@ -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));
index c27b88b96897241d6b99bec950a993bd9b54eb1f..87ff0d359d1ad1b6d0059f4142c6aec693bc3655 100644 (file)
@@ -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 |
index 0b8e9a66856810a8b92592ebcf11e1e76511b708..85a3422bb7c42722a0b36bd1c5b5e900904d8a46 100644 (file)
@@ -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) {
index 063151601b89b8fc2d23f7b4378acbba10a9cc95..7f8919772f7390522ec17d37bef2315cddb6ae5b 100644 (file)
@@ -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);
index 51b2e51d20227b5ac1ff8a76d46bd3873cd16f1f..d66d859505912c315a430b4dd72d59a9d229bf52 100644 (file)
@@ -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(); }
index efd09157a47691742d4303d5d7d012973bde57a0..04b795ef8f75ba64fe28016690d48532cb1f20d2 100644 (file)
@@ -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"));
+}
 }