+Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
+ // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
+ // archs which Darwin doesn't use.
+
+ // The matching this routine does is fairly pointless, since it is neither the
+ // complete architecture list, nor a reasonable subset. The problem is that
+ // historically the driver driver accepts this and also ties its -march=
+ // handling to the architecture name, so we need to be careful before removing
+ // support for it.
+
+ // This code must be kept in sync with Clang's Darwin specific argument
+ // translation.
+
+ return StringSwitch<ArchType>(Str)
+ .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
+ .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
+ .Case("ppc64", Triple::ppc64)
+ .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
+ .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
+ Triple::x86)
+ .Case("x86_64", Triple::x86_64)
+ // This is derived from the driver driver.
+ .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
+ .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
+ .Case("r600", Triple::r600)
+ .Case("ptx32", Triple::ptx32)
+ .Case("ptx64", Triple::ptx64)
+ .Case("amdil", Triple::amdil)
+ .Default(Triple::UnknownArch);
+}
+
+// Returns architecture name that is understood by the target assembler.
+const char *Triple::getArchNameForAssembler() {
+ if (!isOSDarwin() && getVendor() != Triple::Apple)
+ return NULL;
+
+ return StringSwitch<const char*>(getArchName())
+ .Case("i386", "i386")
+ .Case("x86_64", "x86_64")
+ .Case("powerpc", "ppc")
+ .Case("powerpc64", "ppc64")
+ .Cases("mblaze", "microblaze", "mblaze")
+ .Case("arm", "arm")
+ .Cases("armv4t", "thumbv4t", "armv4t")
+ .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
+ .Cases("armv6", "thumbv6", "armv6")
+ .Cases("armv7", "thumbv7", "armv7")
+ .Case("r600", "r600")
+ .Case("ptx32", "ptx32")
+ .Case("ptx64", "ptx64")
+ .Case("le32", "le32")
+ .Case("amdil", "amdil")
+ .Default(NULL);
+}
+
+static Triple::ArchType parseArch(StringRef ArchName) {
+ return StringSwitch<Triple::ArchType>(ArchName)
+ .Cases("i386", "i486", "i586", "i686", Triple::x86)
+ // FIXME: Do we need to support these?
+ .Cases("i786", "i886", "i986", Triple::x86)
+ .Cases("amd64", "x86_64", Triple::x86_64)
+ .Case("powerpc", Triple::ppc)
+ .Cases("powerpc64", "ppu", Triple::ppc64)
+ .Case("mblaze", Triple::mblaze)
+ .Cases("arm", "xscale", Triple::arm)
+ // FIXME: It would be good to replace these with explicit names for all the
+ // various suffixes supported.
+ .StartsWith("armv", Triple::arm)
+ .Case("thumb", Triple::thumb)
+ .StartsWith("thumbv", Triple::thumb)
+ .Cases("spu", "cellspu", Triple::cellspu)
+ .Case("msp430", Triple::msp430)
+ .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
+ .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
+ .Cases("mips64", "mips64eb", Triple::mips64)
+ .Case("mips64el", Triple::mips64el)
+ .Case("r600", Triple::r600)
+ .Case("hexagon", Triple::hexagon)
+ .Case("sparc", Triple::sparc)
+ .Case("sparcv9", Triple::sparcv9)
+ .Case("tce", Triple::tce)
+ .Case("xcore", Triple::xcore)
+ .Case("ptx32", Triple::ptx32)
+ .Case("ptx64", Triple::ptx64)
+ .Case("le32", Triple::le32)
+ .Case("amdil", Triple::amdil)
+ .Default(Triple::UnknownArch);
+}
+
+static Triple::VendorType parseVendor(StringRef VendorName) {
+ return StringSwitch<Triple::VendorType>(VendorName)
+ .Case("apple", Triple::Apple)
+ .Case("pc", Triple::PC)
+ .Case("scei", Triple::SCEI)
+ .Case("bgp", Triple::BGP)
+ .Case("bgq", Triple::BGQ)
+ .Default(Triple::UnknownVendor);
+}
+
+static Triple::OSType parseOS(StringRef OSName) {
+ return StringSwitch<Triple::OSType>(OSName)
+ .StartsWith("auroraux", Triple::AuroraUX)
+ .StartsWith("cygwin", Triple::Cygwin)
+ .StartsWith("darwin", Triple::Darwin)
+ .StartsWith("dragonfly", Triple::DragonFly)
+ .StartsWith("freebsd", Triple::FreeBSD)
+ .StartsWith("ios", Triple::IOS)
+ .StartsWith("kfreebsd", Triple::KFreeBSD)
+ .StartsWith("linux", Triple::Linux)
+ .StartsWith("lv2", Triple::Lv2)
+ .StartsWith("macosx", Triple::MacOSX)
+ .StartsWith("mingw32", Triple::MinGW32)
+ .StartsWith("netbsd", Triple::NetBSD)
+ .StartsWith("openbsd", Triple::OpenBSD)
+ .StartsWith("solaris", Triple::Solaris)
+ .StartsWith("win32", Triple::Win32)
+ .StartsWith("haiku", Triple::Haiku)
+ .StartsWith("minix", Triple::Minix)
+ .StartsWith("rtems", Triple::RTEMS)
+ .StartsWith("nacl", Triple::NativeClient)
+ .StartsWith("cnk", Triple::CNK)
+ .Default(Triple::UnknownOS);
+}
+
+static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
+ return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
+ .StartsWith("eabi", Triple::EABI)
+ .StartsWith("gnueabihf", Triple::GNUEABIHF)
+ .StartsWith("gnueabi", Triple::GNUEABI)
+ .StartsWith("gnu", Triple::GNU)
+ .StartsWith("macho", Triple::MachO)
+ .StartsWith("androideabi", Triple::ANDROIDEABI)
+ .Default(Triple::UnknownEnvironment);
+}
+
+/// \brief Construct a triple from the string representation provided.
+///
+/// This stores the string representation and parses the various pieces into
+/// enum members.
+Triple::Triple(const Twine &Str)
+ : Data(Str.str()),
+ Arch(parseArch(getArchName())),
+ Vendor(parseVendor(getVendorName())),
+ OS(parseOS(getOSName())),
+ Environment(parseEnvironment(getEnvironmentName())) {
+}
+
+/// \brief Construct a triple from string representations of the architecture,
+/// vendor, and OS.
+///
+/// This joins each argument into a canonical string representation and parses
+/// them into enum members. It leaves the environment unknown and omits it from
+/// the string representation.
+Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
+ : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
+ Arch(parseArch(ArchStr.str())),
+ Vendor(parseVendor(VendorStr.str())),
+ OS(parseOS(OSStr.str())),
+ Environment() {
+}