Index: include/llvm/ADT/Triple.h =================================================================== --- include/llvm/ADT/Triple.h +++ include/llvm/ADT/Triple.h @@ -125,6 +125,10 @@ EABI, EABIHF, Android, + + MSVC, + Itanium, + Cygnus, }; enum ObjectFormatType { UnknownObjectFormat, @@ -327,7 +331,9 @@ /// \brief Tests for either Cygwin or MinGW OS bool isOSCygMing() const { - return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; + return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32 || + (getOS() == Triple::Win32 && (getEnvironment() == Triple::Cygnus || + getEnvironment() == Triple::GNU)); } /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment. Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -205,7 +205,8 @@ } if (MAI->doesSupportDebugInformation()) { - if (Triple(TM.getTargetTriple()).getOS() == Triple::Win32) { + if (Triple(TM.getTargetTriple()).getOS() == Triple::Win32 && + Triple(TM.getTargetTriple()).getEnvironment() == Triple::MSVC) { Handlers.push_back(HandlerInfo(new WinCodeViewLineTables(this), DbgTimerName, CodeViewLineTablesGroupName)); Index: lib/MC/MCObjectFileInfo.cpp =================================================================== --- lib/MC/MCObjectFileInfo.cpp +++ lib/MC/MCObjectFileInfo.cpp @@ -565,7 +565,7 @@ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); - if (T.getOS() == Triple::Win32) { + if (T.getOS() == Triple::Win32 && T.getEnvironment() == Triple::MSVC) { StaticCtorSection = Ctx->getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | @@ -581,7 +581,7 @@ } - if (T.getOS() == Triple::Win32) { + if (T.getOS() == Triple::Win32 && T.getEnvironment() == Triple::MSVC) { StaticDtorSection = Ctx->getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | Index: lib/Support/Triple.cpp =================================================================== --- lib/Support/Triple.cpp +++ lib/Support/Triple.cpp @@ -129,7 +129,7 @@ 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 @@ 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 @@ .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 @@ .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); } @@ -408,6 +415,7 @@ EnvironmentType Environment = UnknownEnvironment; if (Components.size() > 3) Environment = parseEnvironment(Components[3]); + ObjectFormatType Format = UnknownObjectFormat; // Note which components are already in their final position. These will not // be moved. @@ -450,7 +458,7 @@ Environment = parseEnvironment(Comp); Valid = Environment != UnknownEnvironment; if (!Valid) { - Triple::ObjectFormatType Format = parseFormat(Comp); + Format = parseFormat(Comp); Valid = Format != UnknownObjectFormat; } break; @@ -515,6 +523,21 @@ // 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 && Format == UnknownObjectFormat) + Components[3] = "msvc"; + } else if (OS == Triple::MinGW32) { + Components.resize(4); + Components[2] = "windows"; + Components[3] = (Format == 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: lib/Target/TargetLibraryInfo.cpp =================================================================== --- lib/Target/TargetLibraryInfo.cpp +++ lib/Target/TargetLibraryInfo.cpp @@ -417,7 +417,7 @@ TLI.setUnavailable(LibFunc::fiprintf); } - if (T.getOS() == Triple::Win32) { + if (T.getOS() == Triple::Win32 && T.getEnvironment() == Triple::MSVC) { // Win32 does not support long double TLI.setUnavailable(LibFunc::acosl); TLI.setUnavailable(LibFunc::asinl); Index: lib/Target/X86/X86Subtarget.h =================================================================== --- lib/Target/X86/X86Subtarget.h +++ lib/Target/X86/X86Subtarget.h @@ -343,9 +343,21 @@ 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.getOS() == Triple::Win32 && + TargetTriple.getEnvironment() != Triple::GNU; + } + bool isTargetMingw() const { + return TargetTriple.getOS() == Triple::MinGW32 || + (TargetTriple.getOS() == Triple::Win32 && + (TargetTriple.getEnvironment() == Triple::Cygnus || + TargetTriple.getEnvironment() == Triple::GNU)); + } + bool isTargetCygwin() const { + return TargetTriple.getOS() == Triple::Cygwin || + (TargetTriple.getOS() == Triple::Win32 && + TargetTriple.getEnvironment() == Triple::Cygnus); + } bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); } bool isOSWindows() const { return TargetTriple.isOSWindows(); } Index: unittests/ADT/TripleTest.cpp =================================================================== --- unittests/ADT/TripleTest.cpp +++ unittests/ADT/TripleTest.cpp @@ -190,6 +190,9 @@ ++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 @@ // 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 @@ -497,4 +500,34 @@ EXPECT_EQ((unsigned)0, Micro); } +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")); +} + }