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