Home | History | Annotate | Download | only in Support
      1 //===--- Triple.cpp - Target triple helper class --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/ADT/Triple.h"
     11 #include "llvm/ADT/STLExtras.h"
     12 #include "llvm/ADT/SmallString.h"
     13 #include "llvm/ADT/StringSwitch.h"
     14 #include "llvm/Support/ErrorHandling.h"
     15 #include <cstring>
     16 using namespace llvm;
     17 
     18 const char *Triple::getArchTypeName(ArchType Kind) {
     19   switch (Kind) {
     20   case UnknownArch: return "unknown";
     21 
     22   case aarch64:     return "aarch64";
     23   case aarch64_be:  return "aarch64_be";
     24   case arm:         return "arm";
     25   case armeb:       return "armeb";
     26   case arm64:       return "arm64";
     27   case arm64_be:    return "arm64_be";
     28   case hexagon:     return "hexagon";
     29   case mips:        return "mips";
     30   case mipsel:      return "mipsel";
     31   case mips64:      return "mips64";
     32   case mips64el:    return "mips64el";
     33   case msp430:      return "msp430";
     34   case ppc64:       return "powerpc64";
     35   case ppc64le:     return "powerpc64le";
     36   case ppc:         return "powerpc";
     37   case r600:        return "r600";
     38   case sparc:       return "sparc";
     39   case sparcv9:     return "sparcv9";
     40   case systemz:     return "s390x";
     41   case tce:         return "tce";
     42   case thumb:       return "thumb";
     43   case thumbeb:     return "thumbeb";
     44   case x86:         return "i386";
     45   case x86_64:      return "x86_64";
     46   case xcore:       return "xcore";
     47   case nvptx:       return "nvptx";
     48   case nvptx64:     return "nvptx64";
     49   case le32:        return "le32";
     50   case amdil:       return "amdil";
     51   case spir:        return "spir";
     52   case spir64:      return "spir64";
     53   case kalimba:     return "kalimba";
     54   }
     55 
     56   llvm_unreachable("Invalid ArchType!");
     57 }
     58 
     59 const char *Triple::getArchTypePrefix(ArchType Kind) {
     60   switch (Kind) {
     61   default:
     62     return nullptr;
     63 
     64   case aarch64:
     65   case aarch64_be:  return "aarch64";
     66 
     67   case arm:
     68   case armeb:
     69   case thumb:
     70   case thumbeb:     return "arm";
     71 
     72   case arm64:
     73   case arm64_be:    return "arm64";
     74 
     75   case ppc64:
     76   case ppc64le:
     77   case ppc:         return "ppc";
     78 
     79   case mips:
     80   case mipsel:
     81   case mips64:
     82   case mips64el:    return "mips";
     83 
     84   case hexagon:     return "hexagon";
     85 
     86   case r600:        return "r600";
     87 
     88   case sparcv9:
     89   case sparc:       return "sparc";
     90 
     91   case systemz:     return "systemz";
     92 
     93   case x86:
     94   case x86_64:      return "x86";
     95 
     96   case xcore:       return "xcore";
     97 
     98   case nvptx:       return "nvptx";
     99   case nvptx64:     return "nvptx";
    100 
    101   case le32:        return "le32";
    102   case amdil:       return "amdil";
    103   case spir:        return "spir";
    104   case spir64:      return "spir";
    105   case kalimba:     return "kalimba";
    106   }
    107 }
    108 
    109 const char *Triple::getVendorTypeName(VendorType Kind) {
    110   switch (Kind) {
    111   case UnknownVendor: return "unknown";
    112 
    113   case Apple: return "apple";
    114   case PC: return "pc";
    115   case SCEI: return "scei";
    116   case BGP: return "bgp";
    117   case BGQ: return "bgq";
    118   case Freescale: return "fsl";
    119   case IBM: return "ibm";
    120   case ImaginationTechnologies: return "img";
    121   case NVIDIA: return "nvidia";
    122   case CSR: return "csr";
    123   }
    124 
    125   llvm_unreachable("Invalid VendorType!");
    126 }
    127 
    128 const char *Triple::getOSTypeName(OSType Kind) {
    129   switch (Kind) {
    130   case UnknownOS: return "unknown";
    131 
    132   case AuroraUX: return "auroraux";
    133   case Cygwin: return "cygwin";
    134   case Darwin: return "darwin";
    135   case DragonFly: return "dragonfly";
    136   case FreeBSD: return "freebsd";
    137   case IOS: return "ios";
    138   case KFreeBSD: return "kfreebsd";
    139   case Linux: return "linux";
    140   case Lv2: return "lv2";
    141   case MacOSX: return "macosx";
    142   case MinGW32: return "mingw32";
    143   case NetBSD: return "netbsd";
    144   case OpenBSD: return "openbsd";
    145   case Solaris: return "solaris";
    146   case Win32: return "windows";
    147   case Haiku: return "haiku";
    148   case Minix: return "minix";
    149   case RTEMS: return "rtems";
    150   case NaCl: return "nacl";
    151   case CNK: return "cnk";
    152   case Bitrig: return "bitrig";
    153   case AIX: return "aix";
    154   case CUDA: return "cuda";
    155   case NVCL: return "nvcl";
    156   }
    157 
    158   llvm_unreachable("Invalid OSType");
    159 }
    160 
    161 const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
    162   switch (Kind) {
    163   case UnknownEnvironment: return "unknown";
    164   case GNU: return "gnu";
    165   case GNUEABIHF: return "gnueabihf";
    166   case GNUEABI: return "gnueabi";
    167   case GNUX32: return "gnux32";
    168   case CODE16: return "code16";
    169   case EABI: return "eabi";
    170   case EABIHF: return "eabihf";
    171   case Android: return "android";
    172   case MSVC: return "msvc";
    173   case Itanium: return "itanium";
    174   case Cygnus: return "cygnus";
    175   }
    176 
    177   llvm_unreachable("Invalid EnvironmentType!");
    178 }
    179 
    180 Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
    181   return StringSwitch<Triple::ArchType>(Name)
    182     .Case("aarch64", aarch64)
    183     .Case("aarch64_be", aarch64_be)
    184     .Case("arm", arm)
    185     .Case("armeb", armeb)
    186     .Case("arm64", arm64)
    187     .Case("arm64_be", arm64_be)
    188     .Case("mips", mips)
    189     .Case("mipsel", mipsel)
    190     .Case("mips64", mips64)
    191     .Case("mips64el", mips64el)
    192     .Case("msp430", msp430)
    193     .Case("ppc64", ppc64)
    194     .Case("ppc32", ppc)
    195     .Case("ppc", ppc)
    196     .Case("ppc64le", ppc64le)
    197     .Case("r600", r600)
    198     .Case("hexagon", hexagon)
    199     .Case("sparc", sparc)
    200     .Case("sparcv9", sparcv9)
    201     .Case("systemz", systemz)
    202     .Case("tce", tce)
    203     .Case("thumb", thumb)
    204     .Case("thumbeb", thumbeb)
    205     .Case("x86", x86)
    206     .Case("x86-64", x86_64)
    207     .Case("xcore", xcore)
    208     .Case("nvptx", nvptx)
    209     .Case("nvptx64", nvptx64)
    210     .Case("le32", le32)
    211     .Case("amdil", amdil)
    212     .Case("spir", spir)
    213     .Case("spir64", spir64)
    214     .Case("kalimba", kalimba)
    215     .Default(UnknownArch);
    216 }
    217 
    218 // Returns architecture name that is understood by the target assembler.
    219 const char *Triple::getArchNameForAssembler() {
    220   if (!isOSDarwin() && getVendor() != Triple::Apple)
    221     return nullptr;
    222 
    223   return StringSwitch<const char*>(getArchName())
    224     .Case("i386", "i386")
    225     .Case("x86_64", "x86_64")
    226     .Case("powerpc", "ppc")
    227     .Case("powerpc64", "ppc64")
    228     .Case("powerpc64le", "ppc64le")
    229     .Case("arm", "arm")
    230     .Cases("armv4t", "thumbv4t", "armv4t")
    231     .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
    232     .Cases("armv6", "thumbv6", "armv6")
    233     .Cases("armv7", "thumbv7", "armv7")
    234     .Case("armeb", "armeb")
    235     .Case("arm64", "arm64")
    236     .Case("arm64_be", "arm64")
    237     .Case("r600", "r600")
    238     .Case("nvptx", "nvptx")
    239     .Case("nvptx64", "nvptx64")
    240     .Case("le32", "le32")
    241     .Case("amdil", "amdil")
    242     .Case("spir", "spir")
    243     .Case("spir64", "spir64")
    244     .Default(nullptr);
    245 }
    246 
    247 static Triple::ArchType parseArch(StringRef ArchName) {
    248   return StringSwitch<Triple::ArchType>(ArchName)
    249     .Cases("i386", "i486", "i586", "i686", Triple::x86)
    250     // FIXME: Do we need to support these?
    251     .Cases("i786", "i886", "i986", Triple::x86)
    252     .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
    253     .Case("powerpc", Triple::ppc)
    254     .Cases("powerpc64", "ppu", Triple::ppc64)
    255     .Case("powerpc64le", Triple::ppc64le)
    256     .Case("aarch64", Triple::aarch64)
    257     .Case("aarch64_be", Triple::aarch64_be)
    258     .Cases("arm", "xscale", Triple::arm)
    259     // FIXME: It would be good to replace these with explicit names for all the
    260     // various suffixes supported.
    261     .StartsWith("armv", Triple::arm)
    262     .Case("armeb", Triple::armeb)
    263     .StartsWith("armebv", Triple::armeb)
    264     .Case("thumb", Triple::thumb)
    265     .StartsWith("thumbv", Triple::thumb)
    266     .Case("thumbeb", Triple::thumbeb)
    267     .StartsWith("thumbebv", Triple::thumbeb)
    268     .Case("arm64", Triple::arm64)
    269     .Case("arm64_be", Triple::arm64_be)
    270     .Case("msp430", Triple::msp430)
    271     .Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
    272     .Cases("mipsel", "mipsallegrexel", Triple::mipsel)
    273     .Cases("mips64", "mips64eb", Triple::mips64)
    274     .Case("mips64el", Triple::mips64el)
    275     .Case("r600", Triple::r600)
    276     .Case("hexagon", Triple::hexagon)
    277     .Case("s390x", Triple::systemz)
    278     .Case("sparc", Triple::sparc)
    279     .Cases("sparcv9", "sparc64", Triple::sparcv9)
    280     .Case("tce", Triple::tce)
    281     .Case("xcore", Triple::xcore)
    282     .Case("nvptx", Triple::nvptx)
    283     .Case("nvptx64", Triple::nvptx64)
    284     .Case("le32", Triple::le32)
    285     .Case("amdil", Triple::amdil)
    286     .Case("spir", Triple::spir)
    287     .Case("spir64", Triple::spir64)
    288     .Case("kalimba", Triple::kalimba)
    289     .Default(Triple::UnknownArch);
    290 }
    291 
    292 static Triple::VendorType parseVendor(StringRef VendorName) {
    293   return StringSwitch<Triple::VendorType>(VendorName)
    294     .Case("apple", Triple::Apple)
    295     .Case("pc", Triple::PC)
    296     .Case("scei", Triple::SCEI)
    297     .Case("bgp", Triple::BGP)
    298     .Case("bgq", Triple::BGQ)
    299     .Case("fsl", Triple::Freescale)
    300     .Case("ibm", Triple::IBM)
    301     .Case("img", Triple::ImaginationTechnologies)
    302     .Case("nvidia", Triple::NVIDIA)
    303     .Case("csr", Triple::CSR)
    304     .Default(Triple::UnknownVendor);
    305 }
    306 
    307 static Triple::OSType parseOS(StringRef OSName) {
    308   return StringSwitch<Triple::OSType>(OSName)
    309     .StartsWith("auroraux", Triple::AuroraUX)
    310     .StartsWith("cygwin", Triple::Cygwin)
    311     .StartsWith("darwin", Triple::Darwin)
    312     .StartsWith("dragonfly", Triple::DragonFly)
    313     .StartsWith("freebsd", Triple::FreeBSD)
    314     .StartsWith("ios", Triple::IOS)
    315     .StartsWith("kfreebsd", Triple::KFreeBSD)
    316     .StartsWith("linux", Triple::Linux)
    317     .StartsWith("lv2", Triple::Lv2)
    318     .StartsWith("macosx", Triple::MacOSX)
    319     .StartsWith("mingw32", Triple::MinGW32)
    320     .StartsWith("netbsd", Triple::NetBSD)
    321     .StartsWith("openbsd", Triple::OpenBSD)
    322     .StartsWith("solaris", Triple::Solaris)
    323     .StartsWith("win32", Triple::Win32)
    324     .StartsWith("windows", Triple::Win32)
    325     .StartsWith("haiku", Triple::Haiku)
    326     .StartsWith("minix", Triple::Minix)
    327     .StartsWith("rtems", Triple::RTEMS)
    328     .StartsWith("nacl", Triple::NaCl)
    329     .StartsWith("cnk", Triple::CNK)
    330     .StartsWith("bitrig", Triple::Bitrig)
    331     .StartsWith("aix", Triple::AIX)
    332     .StartsWith("cuda", Triple::CUDA)
    333     .StartsWith("nvcl", Triple::NVCL)
    334     .Default(Triple::UnknownOS);
    335 }
    336 
    337 static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
    338   return StringSwitch<Triple::EnvironmentType>(EnvironmentName)
    339     .StartsWith("eabihf", Triple::EABIHF)
    340     .StartsWith("eabi", Triple::EABI)
    341     .StartsWith("gnueabihf", Triple::GNUEABIHF)
    342     .StartsWith("gnueabi", Triple::GNUEABI)
    343     .StartsWith("gnux32", Triple::GNUX32)
    344     .StartsWith("code16", Triple::CODE16)
    345     .StartsWith("gnu", Triple::GNU)
    346     .StartsWith("android", Triple::Android)
    347     .StartsWith("msvc", Triple::MSVC)
    348     .StartsWith("itanium", Triple::Itanium)
    349     .StartsWith("cygnus", Triple::Cygnus)
    350     .Default(Triple::UnknownEnvironment);
    351 }
    352 
    353 static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
    354   return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
    355     .EndsWith("coff", Triple::COFF)
    356     .EndsWith("elf", Triple::ELF)
    357     .EndsWith("macho", Triple::MachO)
    358     .Default(Triple::UnknownObjectFormat);
    359 }
    360 
    361 static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
    362   switch (Kind) {
    363   case Triple::UnknownObjectFormat: return "";
    364   case Triple::COFF: return "coff";
    365   case Triple::ELF: return "elf";
    366   case Triple::MachO: return "macho";
    367   }
    368   llvm_unreachable("unknown object format type");
    369 }
    370 
    371 static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
    372   if (T.isOSDarwin())
    373     return Triple::MachO;
    374   else if (T.isOSWindows())
    375     return Triple::COFF;
    376   return Triple::ELF;
    377 }
    378 
    379 /// \brief Construct a triple from the string representation provided.
    380 ///
    381 /// This stores the string representation and parses the various pieces into
    382 /// enum members.
    383 Triple::Triple(const Twine &Str)
    384     : Data(Str.str()),
    385       Arch(parseArch(getArchName())),
    386       Vendor(parseVendor(getVendorName())),
    387       OS(parseOS(getOSName())),
    388       Environment(parseEnvironment(getEnvironmentName())),
    389       ObjectFormat(parseFormat(getEnvironmentName())) {
    390   if (ObjectFormat == Triple::UnknownObjectFormat)
    391     ObjectFormat = getDefaultFormat(*this);
    392 }
    393 
    394 /// \brief Construct a triple from string representations of the architecture,
    395 /// vendor, and OS.
    396 ///
    397 /// This joins each argument into a canonical string representation and parses
    398 /// them into enum members. It leaves the environment unknown and omits it from
    399 /// the string representation.
    400 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr)
    401     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()),
    402       Arch(parseArch(ArchStr.str())),
    403       Vendor(parseVendor(VendorStr.str())),
    404       OS(parseOS(OSStr.str())),
    405       Environment(), ObjectFormat(Triple::UnknownObjectFormat) {
    406   ObjectFormat = getDefaultFormat(*this);
    407 }
    408 
    409 /// \brief Construct a triple from string representations of the architecture,
    410 /// vendor, OS, and environment.
    411 ///
    412 /// This joins each argument into a canonical string representation and parses
    413 /// them into enum members.
    414 Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr,
    415                const Twine &EnvironmentStr)
    416     : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') +
    417             EnvironmentStr).str()),
    418       Arch(parseArch(ArchStr.str())),
    419       Vendor(parseVendor(VendorStr.str())),
    420       OS(parseOS(OSStr.str())),
    421       Environment(parseEnvironment(EnvironmentStr.str())),
    422       ObjectFormat(parseFormat(EnvironmentStr.str())) {
    423   if (ObjectFormat == Triple::UnknownObjectFormat)
    424     ObjectFormat = getDefaultFormat(*this);
    425 }
    426 
    427 std::string Triple::normalize(StringRef Str) {
    428   // Parse into components.
    429   SmallVector<StringRef, 4> Components;
    430   Str.split(Components, "-");
    431 
    432   // If the first component corresponds to a known architecture, preferentially
    433   // use it for the architecture.  If the second component corresponds to a
    434   // known vendor, preferentially use it for the vendor, etc.  This avoids silly
    435   // component movement when a component parses as (eg) both a valid arch and a
    436   // valid os.
    437   ArchType Arch = UnknownArch;
    438   if (Components.size() > 0)
    439     Arch = parseArch(Components[0]);
    440   VendorType Vendor = UnknownVendor;
    441   if (Components.size() > 1)
    442     Vendor = parseVendor(Components[1]);
    443   OSType OS = UnknownOS;
    444   if (Components.size() > 2)
    445     OS = parseOS(Components[2]);
    446   EnvironmentType Environment = UnknownEnvironment;
    447   if (Components.size() > 3)
    448     Environment = parseEnvironment(Components[3]);
    449   ObjectFormatType ObjectFormat = UnknownObjectFormat;
    450   if (Components.size() > 4)
    451     ObjectFormat = parseFormat(Components[4]);
    452 
    453   // Note which components are already in their final position.  These will not
    454   // be moved.
    455   bool Found[4];
    456   Found[0] = Arch != UnknownArch;
    457   Found[1] = Vendor != UnknownVendor;
    458   Found[2] = OS != UnknownOS;
    459   Found[3] = Environment != UnknownEnvironment;
    460 
    461   // If they are not there already, permute the components into their canonical
    462   // positions by seeing if they parse as a valid architecture, and if so moving
    463   // the component to the architecture position etc.
    464   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
    465     if (Found[Pos])
    466       continue; // Already in the canonical position.
    467 
    468     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
    469       // Do not reparse any components that already matched.
    470       if (Idx < array_lengthof(Found) && Found[Idx])
    471         continue;
    472 
    473       // Does this component parse as valid for the target position?
    474       bool Valid = false;
    475       StringRef Comp = Components[Idx];
    476       switch (Pos) {
    477       default: llvm_unreachable("unexpected component type!");
    478       case 0:
    479         Arch = parseArch(Comp);
    480         Valid = Arch != UnknownArch;
    481         break;
    482       case 1:
    483         Vendor = parseVendor(Comp);
    484         Valid = Vendor != UnknownVendor;
    485         break;
    486       case 2:
    487         OS = parseOS(Comp);
    488         Valid = OS != UnknownOS;
    489         break;
    490       case 3:
    491         Environment = parseEnvironment(Comp);
    492         Valid = Environment != UnknownEnvironment;
    493         if (!Valid) {
    494           ObjectFormat = parseFormat(Comp);
    495           Valid = ObjectFormat != UnknownObjectFormat;
    496         }
    497         break;
    498       }
    499       if (!Valid)
    500         continue; // Nope, try the next component.
    501 
    502       // Move the component to the target position, pushing any non-fixed
    503       // components that are in the way to the right.  This tends to give
    504       // good results in the common cases of a forgotten vendor component
    505       // or a wrongly positioned environment.
    506       if (Pos < Idx) {
    507         // Insert left, pushing the existing components to the right.  For
    508         // example, a-b-i386 -> i386-a-b when moving i386 to the front.
    509         StringRef CurrentComponent(""); // The empty component.
    510         // Replace the component we are moving with an empty component.
    511         std::swap(CurrentComponent, Components[Idx]);
    512         // Insert the component being moved at Pos, displacing any existing
    513         // components to the right.
    514         for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
    515           // Skip over any fixed components.
    516           while (i < array_lengthof(Found) && Found[i])
    517             ++i;
    518           // Place the component at the new position, getting the component
    519           // that was at this position - it will be moved right.
    520           std::swap(CurrentComponent, Components[i]);
    521         }
    522       } else if (Pos > Idx) {
    523         // Push right by inserting empty components until the component at Idx
    524         // reaches the target position Pos.  For example, pc-a -> -pc-a when
    525         // moving pc to the second position.
    526         do {
    527           // Insert one empty component at Idx.
    528           StringRef CurrentComponent(""); // The empty component.
    529           for (unsigned i = Idx; i < Components.size();) {
    530             // Place the component at the new position, getting the component
    531             // that was at this position - it will be moved right.
    532             std::swap(CurrentComponent, Components[i]);
    533             // If it was placed on top of an empty component then we are done.
    534             if (CurrentComponent.empty())
    535               break;
    536             // Advance to the next component, skipping any fixed components.
    537             while (++i < array_lengthof(Found) && Found[i])
    538               ;
    539           }
    540           // The last component was pushed off the end - append it.
    541           if (!CurrentComponent.empty())
    542             Components.push_back(CurrentComponent);
    543 
    544           // Advance Idx to the component's new position.
    545           while (++Idx < array_lengthof(Found) && Found[Idx])
    546             ;
    547         } while (Idx < Pos); // Add more until the final position is reached.
    548       }
    549       assert(Pos < Components.size() && Components[Pos] == Comp &&
    550              "Component moved wrong!");
    551       Found[Pos] = true;
    552       break;
    553     }
    554   }
    555 
    556   // Special case logic goes here.  At this point Arch, Vendor and OS have the
    557   // correct values for the computed components.
    558 
    559   if (OS == Triple::Win32) {
    560     Components.resize(4);
    561     Components[2] = "windows";
    562     if (Environment == UnknownEnvironment) {
    563       if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF)
    564         Components[3] = "msvc";
    565       else
    566         Components[3] = getObjectFormatTypeName(ObjectFormat);
    567     }
    568   } else if (OS == Triple::MinGW32) {
    569     Components.resize(4);
    570     Components[2] = "windows";
    571     Components[3] = "gnu";
    572   } else if (OS == Triple::Cygwin) {
    573     Components.resize(4);
    574     Components[2] = "windows";
    575     Components[3] = "cygnus";
    576   }
    577   if (OS == Triple::MinGW32 || OS == Triple::Cygwin ||
    578       (OS == Triple::Win32 && Environment != UnknownEnvironment)) {
    579     if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) {
    580       Components.resize(5);
    581       Components[4] = getObjectFormatTypeName(ObjectFormat);
    582     }
    583   }
    584 
    585   // Stick the corrected components back together to form the normalized string.
    586   std::string Normalized;
    587   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
    588     if (i) Normalized += '-';
    589     Normalized += Components[i];
    590   }
    591   return Normalized;
    592 }
    593 
    594 StringRef Triple::getArchName() const {
    595   return StringRef(Data).split('-').first;           // Isolate first component
    596 }
    597 
    598 StringRef Triple::getVendorName() const {
    599   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
    600   return Tmp.split('-').first;                       // Isolate second component
    601 }
    602 
    603 StringRef Triple::getOSName() const {
    604   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
    605   Tmp = Tmp.split('-').second;                       // Strip second component
    606   return Tmp.split('-').first;                       // Isolate third component
    607 }
    608 
    609 StringRef Triple::getEnvironmentName() const {
    610   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
    611   Tmp = Tmp.split('-').second;                       // Strip second component
    612   return Tmp.split('-').second;                      // Strip third component
    613 }
    614 
    615 StringRef Triple::getOSAndEnvironmentName() const {
    616   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
    617   return Tmp.split('-').second;                      // Strip second component
    618 }
    619 
    620 static unsigned EatNumber(StringRef &Str) {
    621   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
    622   unsigned Result = 0;
    623 
    624   do {
    625     // Consume the leading digit.
    626     Result = Result*10 + (Str[0] - '0');
    627 
    628     // Eat the digit.
    629     Str = Str.substr(1);
    630   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
    631 
    632   return Result;
    633 }
    634 
    635 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
    636                           unsigned &Micro) const {
    637   StringRef OSName = getOSName();
    638 
    639   // Assume that the OS portion of the triple starts with the canonical name.
    640   StringRef OSTypeName = getOSTypeName(getOS());
    641   if (OSName.startswith(OSTypeName))
    642     OSName = OSName.substr(OSTypeName.size());
    643 
    644   // Any unset version defaults to 0.
    645   Major = Minor = Micro = 0;
    646 
    647   // Parse up to three components.
    648   unsigned *Components[3] = { &Major, &Minor, &Micro };
    649   for (unsigned i = 0; i != 3; ++i) {
    650     if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    651       break;
    652 
    653     // Consume the leading number.
    654     *Components[i] = EatNumber(OSName);
    655 
    656     // Consume the separator, if present.
    657     if (OSName.startswith("."))
    658       OSName = OSName.substr(1);
    659   }
    660 }
    661 
    662 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
    663                               unsigned &Micro) const {
    664   getOSVersion(Major, Minor, Micro);
    665 
    666   switch (getOS()) {
    667   default: llvm_unreachable("unexpected OS for Darwin triple");
    668   case Darwin:
    669     // Default to darwin8, i.e., MacOSX 10.4.
    670     if (Major == 0)
    671       Major = 8;
    672     // Darwin version numbers are skewed from OS X versions.
    673     if (Major < 4)
    674       return false;
    675     Micro = 0;
    676     Minor = Major - 4;
    677     Major = 10;
    678     break;
    679   case MacOSX:
    680     // Default to 10.4.
    681     if (Major == 0) {
    682       Major = 10;
    683       Minor = 4;
    684     }
    685     if (Major != 10)
    686       return false;
    687     break;
    688   case IOS:
    689     // Ignore the version from the triple.  This is only handled because the
    690     // the clang driver combines OS X and IOS support into a common Darwin
    691     // toolchain that wants to know the OS X version number even when targeting
    692     // IOS.
    693     Major = 10;
    694     Minor = 4;
    695     Micro = 0;
    696     break;
    697   }
    698   return true;
    699 }
    700 
    701 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
    702                            unsigned &Micro) const {
    703   switch (getOS()) {
    704   default: llvm_unreachable("unexpected OS for Darwin triple");
    705   case Darwin:
    706   case MacOSX:
    707     // Ignore the version from the triple.  This is only handled because the
    708     // the clang driver combines OS X and IOS support into a common Darwin
    709     // toolchain that wants to know the iOS version number even when targeting
    710     // OS X.
    711     Major = 5;
    712     Minor = 0;
    713     Micro = 0;
    714     break;
    715   case IOS:
    716     getOSVersion(Major, Minor, Micro);
    717     // Default to 5.0 (or 7.0 for arm64).
    718     if (Major == 0)
    719       Major = (getArch() == arm64) ? 7 : 5;
    720     break;
    721   }
    722 }
    723 
    724 void Triple::setTriple(const Twine &Str) {
    725   *this = Triple(Str);
    726 }
    727 
    728 void Triple::setArch(ArchType Kind) {
    729   setArchName(getArchTypeName(Kind));
    730 }
    731 
    732 void Triple::setVendor(VendorType Kind) {
    733   setVendorName(getVendorTypeName(Kind));
    734 }
    735 
    736 void Triple::setOS(OSType Kind) {
    737   setOSName(getOSTypeName(Kind));
    738 }
    739 
    740 void Triple::setEnvironment(EnvironmentType Kind) {
    741   setEnvironmentName(getEnvironmentTypeName(Kind));
    742 }
    743 
    744 void Triple::setObjectFormat(ObjectFormatType Kind) {
    745   if (Environment == UnknownEnvironment)
    746     return setEnvironmentName(getObjectFormatTypeName(Kind));
    747 
    748   setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") +
    749                       getObjectFormatTypeName(Kind)).str());
    750 }
    751 
    752 void Triple::setArchName(StringRef Str) {
    753   // Work around a miscompilation bug for Twines in gcc 4.0.3.
    754   SmallString<64> Triple;
    755   Triple += Str;
    756   Triple += "-";
    757   Triple += getVendorName();
    758   Triple += "-";
    759   Triple += getOSAndEnvironmentName();
    760   setTriple(Triple.str());
    761 }
    762 
    763 void Triple::setVendorName(StringRef Str) {
    764   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
    765 }
    766 
    767 void Triple::setOSName(StringRef Str) {
    768   if (hasEnvironment())
    769     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
    770               "-" + getEnvironmentName());
    771   else
    772     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
    773 }
    774 
    775 void Triple::setEnvironmentName(StringRef Str) {
    776   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
    777             "-" + Str);
    778 }
    779 
    780 void Triple::setOSAndEnvironmentName(StringRef Str) {
    781   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
    782 }
    783 
    784 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
    785   switch (Arch) {
    786   case llvm::Triple::UnknownArch:
    787     return 0;
    788 
    789   case llvm::Triple::msp430:
    790     return 16;
    791 
    792   case llvm::Triple::amdil:
    793   case llvm::Triple::arm:
    794   case llvm::Triple::armeb:
    795   case llvm::Triple::hexagon:
    796   case llvm::Triple::le32:
    797   case llvm::Triple::mips:
    798   case llvm::Triple::mipsel:
    799   case llvm::Triple::nvptx:
    800   case llvm::Triple::ppc:
    801   case llvm::Triple::r600:
    802   case llvm::Triple::sparc:
    803   case llvm::Triple::tce:
    804   case llvm::Triple::thumb:
    805   case llvm::Triple::thumbeb:
    806   case llvm::Triple::x86:
    807   case llvm::Triple::xcore:
    808   case llvm::Triple::spir:
    809   case llvm::Triple::kalimba:
    810     return 32;
    811 
    812   case llvm::Triple::arm64:
    813   case llvm::Triple::arm64_be:
    814   case llvm::Triple::aarch64:
    815   case llvm::Triple::aarch64_be:
    816   case llvm::Triple::mips64:
    817   case llvm::Triple::mips64el:
    818   case llvm::Triple::nvptx64:
    819   case llvm::Triple::ppc64:
    820   case llvm::Triple::ppc64le:
    821   case llvm::Triple::sparcv9:
    822   case llvm::Triple::systemz:
    823   case llvm::Triple::x86_64:
    824   case llvm::Triple::spir64:
    825     return 64;
    826   }
    827   llvm_unreachable("Invalid architecture value");
    828 }
    829 
    830 bool Triple::isArch64Bit() const {
    831   return getArchPointerBitWidth(getArch()) == 64;
    832 }
    833 
    834 bool Triple::isArch32Bit() const {
    835   return getArchPointerBitWidth(getArch()) == 32;
    836 }
    837 
    838 bool Triple::isArch16Bit() const {
    839   return getArchPointerBitWidth(getArch()) == 16;
    840 }
    841 
    842 Triple Triple::get32BitArchVariant() const {
    843   Triple T(*this);
    844   switch (getArch()) {
    845   case Triple::UnknownArch:
    846   case Triple::aarch64:
    847   case Triple::aarch64_be:
    848   case Triple::arm64:
    849   case Triple::arm64_be:
    850   case Triple::msp430:
    851   case Triple::systemz:
    852   case Triple::ppc64le:
    853     T.setArch(UnknownArch);
    854     break;
    855 
    856   case Triple::amdil:
    857   case Triple::spir:
    858   case Triple::arm:
    859   case Triple::armeb:
    860   case Triple::hexagon:
    861   case Triple::kalimba:
    862   case Triple::le32:
    863   case Triple::mips:
    864   case Triple::mipsel:
    865   case Triple::nvptx:
    866   case Triple::ppc:
    867   case Triple::r600:
    868   case Triple::sparc:
    869   case Triple::tce:
    870   case Triple::thumb:
    871   case Triple::thumbeb:
    872   case Triple::x86:
    873   case Triple::xcore:
    874     // Already 32-bit.
    875     break;
    876 
    877   case Triple::mips64:    T.setArch(Triple::mips);    break;
    878   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
    879   case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
    880   case Triple::ppc64:     T.setArch(Triple::ppc);     break;
    881   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
    882   case Triple::x86_64:    T.setArch(Triple::x86);     break;
    883   case Triple::spir64:    T.setArch(Triple::spir);    break;
    884   }
    885   return T;
    886 }
    887 
    888 Triple Triple::get64BitArchVariant() const {
    889   Triple T(*this);
    890   switch (getArch()) {
    891   case Triple::UnknownArch:
    892   case Triple::amdil:
    893   case Triple::arm:
    894   case Triple::armeb:
    895   case Triple::hexagon:
    896   case Triple::kalimba:
    897   case Triple::le32:
    898   case Triple::msp430:
    899   case Triple::r600:
    900   case Triple::tce:
    901   case Triple::thumb:
    902   case Triple::thumbeb:
    903   case Triple::xcore:
    904     T.setArch(UnknownArch);
    905     break;
    906 
    907   case Triple::aarch64:
    908   case Triple::aarch64_be:
    909   case Triple::spir64:
    910   case Triple::mips64:
    911   case Triple::mips64el:
    912   case Triple::nvptx64:
    913   case Triple::ppc64:
    914   case Triple::ppc64le:
    915   case Triple::sparcv9:
    916   case Triple::systemz:
    917   case Triple::x86_64:
    918   case Triple::arm64:
    919   case Triple::arm64_be:
    920     // Already 64-bit.
    921     break;
    922 
    923   case Triple::mips:    T.setArch(Triple::mips64);    break;
    924   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
    925   case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
    926   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
    927   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
    928   case Triple::x86:     T.setArch(Triple::x86_64);    break;
    929   case Triple::spir:    T.setArch(Triple::spir64);    break;
    930   }
    931   return T;
    932 }
    933