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