From 651aa689cc37d5932fac0e096aa8b536f282aa21 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 18 Aug 2009 19:26:55 +0000 Subject: [PATCH] Improve Triple to recognize the OS in i386-mingw32. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79359 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/Triple.h | 18 ++++++++++++++++-- lib/Support/Triple.cpp | 21 +++++++++++++++++++-- unittests/ADT/TripleTest.cpp | 12 ++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index a74fde3d6e1..c63d91be99b 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -29,8 +29,22 @@ class Twine; /// behavior for particular targets. This class isolates the mapping /// from the components of the target triple to well known IDs. /// -/// See autoconf/config.guess for a glimpse into what they look like -/// in practice. +/// At its core the Triple class is designed to be a wrapper for a triple +/// string; it does not normally change or normalize the triple string, instead +/// it provides additional APIs to parse normalized parts out of the triple. +/// +/// One curiosity this implies is that for some odd triples the results of, +/// e.g., getOSName() can be very different from the result of getOS(). For +/// example, for 'i386-mingw32', getOS() will return MinGW32, but since +/// getOSName() is purely based on the string structure that will return the +/// empty string. +/// +/// Clients should generally avoid using getOSName() and related APIs unless +/// they are familiar with the triple format (this is particularly true when +/// rewriting a triple). +/// +/// See autoconf/config.guess for a glimpse into what they look like in +/// practice. class Triple { public: enum ArchType { diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index c2982ce6615..df28b98b689 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -117,6 +117,9 @@ void Triple::Parse() const { assert(!isInitialized() && "Invalid parse call."); StringRef ArchName = getArchName(); + StringRef VendorName = getVendorName(); + StringRef OSName = getOSName(); + if (ArchName.size() == 4 && ArchName[0] == 'i' && ArchName[2] == '8' && ArchName[3] == '6' && ArchName[1] - '3' < 6) // i[3-9]86 @@ -156,7 +159,22 @@ void Triple::Parse() const { else Arch = UnknownArch; - StringRef VendorName = getVendorName(); + + // Handle some exceptional cases where the OS / environment components are + // stuck into the vendor field. + if (StringRef(getTriple()).count('-') == 1) { + StringRef VendorName = getVendorName(); + + if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc. + Vendor = PC; + OS = MinGW32; + return; + } + + // arm-elf is another example, but we don't currently parse anything about + // the environment. + } + if (VendorName == "apple") Vendor = Apple; else if (VendorName == "pc") @@ -164,7 +182,6 @@ void Triple::Parse() const { else Vendor = UnknownVendor; - StringRef OSName = getOSName(); if (OSName.startswith("auroraux")) OS = AuroraUX; else if (OSName.startswith("cygwin")) diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index cbb2ea48f1b..1a9e81a0df7 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -92,6 +92,18 @@ TEST(TripleTest, ParsedIDs) { T = Triple("huh"); EXPECT_EQ(Triple::UnknownArch, T.getArch()); + + // Two exceptional cases. + + T = Triple("i386-mingw32"); + EXPECT_EQ(Triple::x86, T.getArch()); + EXPECT_EQ(Triple::PC, T.getVendor()); + EXPECT_EQ(Triple::MinGW32, T.getOS()); + + T = Triple("arm-elf"); + EXPECT_EQ(Triple::arm, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::UnknownOS, T.getOS()); } TEST(TripleTest, MutateName) { -- 2.34.1