diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index ef53eb92511..8c2d18d5b8e 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -72,7 +72,8 @@ public: UnknownVendor, Apple, - PC + PC, + NoVendor }; enum OSType { UnknownOS, @@ -92,10 +93,15 @@ public: Solaris, Win32, Haiku, - Minix + Minix, + NoOS }; enum EnvironmentType { - UnknownEnvironment + UnknownEnvironment, + + GNU, + GNUEABI, + EABI }; private: diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index c7ad7b76111..c9da964ce13 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -84,6 +84,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) { case Apple: return "apple"; case PC: return "pc"; + case NoVendor: return "none"; } return ""; @@ -109,6 +110,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case Win32: return "win32"; case Haiku: return "haiku"; case Minix: return "minix"; + case NoOS: return "none"; } return ""; @@ -117,6 +119,9 @@ const char *Triple::getOSTypeName(OSType Kind) { const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { switch (Kind) { case UnknownEnvironment: return "unknown"; + case GNU: return "gnu"; + case GNUEABI: return "gnueabi"; + case EABI: return "eabi"; } return ""; @@ -293,6 +298,8 @@ Triple::VendorType Triple::ParseVendor(StringRef VendorName) { return Apple; else if (VendorName == "pc") return PC; + else if (VendorName == "none") + return NoVendor; else return UnknownVendor; } @@ -330,12 +337,21 @@ Triple::OSType Triple::ParseOS(StringRef OSName) { return Haiku; else if (OSName.startswith("minix")) return Minix; + else if (OSName.startswith("eabi")) + return NoOS; else return UnknownOS; } Triple::EnvironmentType Triple::ParseEnvironment(StringRef EnvironmentName) { - return UnknownEnvironment; + if (EnvironmentName.startswith("eabi")) + return EABI; + else if (EnvironmentName.startswith("gnueabi")) + return GNUEABI; + else if (EnvironmentName.startswith("gnu")) + return GNU; + else + return UnknownEnvironment; } void Triple::Parse() const { @@ -344,7 +360,12 @@ void Triple::Parse() const { Arch = ParseArch(getArchName()); Vendor = ParseVendor(getVendorName()); OS = ParseOS(getOSName()); - Environment = ParseEnvironment(getEnvironmentName()); + if (OS == NoOS) { + // Some targets don't have an OS (embedded systems) + Environment = ParseEnvironment(getOSName()); + } else { + Environment = ParseEnvironment(getEnvironmentName()); + } assert(isInitialized() && "Failed to initialize!"); } @@ -411,7 +432,13 @@ std::string Triple::normalize(StringRef Str) { break; case 2: OS = ParseOS(Comp); - Valid = OS != UnknownOS; + // Some targets don't have an OS (embedded systems) + if (OS == NoOS) { + Environment = ParseEnvironment(Comp); + Valid = Environment != UnknownEnvironment; + } else { + Valid = OS != UnknownOS; + } break; case 3: Environment = ParseEnvironment(Comp); @@ -450,6 +477,9 @@ std::string Triple::normalize(StringRef Str) { for (unsigned i = Idx; i < Components.size(); ++i) { // Skip over any fixed components. while (i < array_lengthof(Found) && Found[i]) ++i; + // Fix problem when Components vector is not big enough + if (i >= Components.size()) + Components.push_back(StringRef("")); // Place the component at the new position, getting the component // that was at this position - it will be moved right. std::swap(CurrentComponent, Components[i]); diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp index bcc71968fe2..8f778c19ddc 100644 --- a/unittests/ADT/TripleTest.cpp +++ b/unittests/ADT/TripleTest.cpp @@ -85,9 +85,7 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::x86_64, T.getArch()); EXPECT_EQ(Triple::PC, T.getVendor()); EXPECT_EQ(Triple::Linux, T.getOS()); - // When environments are defined, change this test to verify the "gnu" - // environment. - EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + EXPECT_EQ(Triple::GNU, T.getEnvironment()); T = Triple("powerpc-dunno-notsure"); EXPECT_EQ(Triple::ppc, T.getArch()); @@ -95,6 +93,12 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::UnknownOS, T.getOS()); EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment()); + T = Triple("arm-none-eabi"); + EXPECT_EQ(Triple::arm, T.getArch()); + EXPECT_EQ(Triple::NoVendor, T.getVendor()); + EXPECT_EQ(Triple::NoOS, T.getOS()); + EXPECT_EQ(Triple::EABI, T.getEnvironment()); + T = Triple("huh"); EXPECT_EQ(Triple::UnknownArch, T.getArch()); } @@ -110,6 +114,7 @@ static std::string Join(StringRef A, StringRef B, StringRef C, StringRef D) { } TEST(TripleTest, Normalization) { + EXPECT_EQ("", Triple::normalize("")); EXPECT_EQ("-", Triple::normalize("-")); EXPECT_EQ("--", Triple::normalize("--")); @@ -144,6 +149,8 @@ TEST(TripleTest, Normalization) { EXPECT_EQ("-pc", Triple::normalize("pc")); EXPECT_EQ("--linux", Triple::normalize("linux")); + EXPECT_EQ("x86_64--linux-gnu", Triple::normalize("x86_64-gnu-linux")); + // Check that normalizing a permutated set of valid components returns a // triple with the unpermuted components. StringRef C[4]; @@ -251,6 +258,7 @@ TEST(TripleTest, MutateName) { EXPECT_EQ(Triple::PC, T.getVendor()); EXPECT_EQ(Triple::Darwin, T.getOS()); EXPECT_EQ("i386-pc-darwin", T.getTriple()); + } }