Support: correct Windows normalisation
[oota-llvm.git] / lib / Support / Triple.cpp
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 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
57 const 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
105 const 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
122 const 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
155 const 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
174 Triple::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.
211 const 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
238 static 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
281 static 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
294 static 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
324 static 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
340 static 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
348 static 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
358 static 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.
370 Triple::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.
387 Triple::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.
401 Triple::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
414 std::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)
551         Components[3] = "msvc";
552       else
553         Components[3] = getObjectFormatTypeName(ObjectFormat);
554     } else if (ObjectFormat != UnknownObjectFormat &&
555                ObjectFormat != Triple::COFF) {
556       Components.resize(5);
557       Components[4] = getObjectFormatTypeName(ObjectFormat);
558     }
559   } else if (OS == Triple::MinGW32) {
560     Components.resize(4);
561     Components[2] = "windows";
562     Components[3] = (ObjectFormat == Triple::ELF) ? "gnuelf" : "gnu";
563   } else if (OS == Triple::Cygwin) {
564     Components.resize(4);
565     Components[2] = "windows";
566     Components[3] = "cygnus";
567   }
568
569   // Stick the corrected components back together to form the normalized string.
570   std::string Normalized;
571   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
572     if (i) Normalized += '-';
573     Normalized += Components[i];
574   }
575   return Normalized;
576 }
577
578 StringRef Triple::getArchName() const {
579   return StringRef(Data).split('-').first;           // Isolate first component
580 }
581
582 StringRef Triple::getVendorName() const {
583   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
584   return Tmp.split('-').first;                       // Isolate second component
585 }
586
587 StringRef Triple::getOSName() const {
588   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
589   Tmp = Tmp.split('-').second;                       // Strip second component
590   return Tmp.split('-').first;                       // Isolate third component
591 }
592
593 StringRef Triple::getEnvironmentName() const {
594   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
595   Tmp = Tmp.split('-').second;                       // Strip second component
596   return Tmp.split('-').second;                      // Strip third component
597 }
598
599 StringRef Triple::getOSAndEnvironmentName() const {
600   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
601   return Tmp.split('-').second;                      // Strip second component
602 }
603
604 static unsigned EatNumber(StringRef &Str) {
605   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
606   unsigned Result = 0;
607
608   do {
609     // Consume the leading digit.
610     Result = Result*10 + (Str[0] - '0');
611
612     // Eat the digit.
613     Str = Str.substr(1);
614   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
615
616   return Result;
617 }
618
619 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
620                           unsigned &Micro) const {
621   StringRef OSName = getOSName();
622
623   // Assume that the OS portion of the triple starts with the canonical name.
624   StringRef OSTypeName = getOSTypeName(getOS());
625   if (OSName.startswith(OSTypeName))
626     OSName = OSName.substr(OSTypeName.size());
627
628   // Any unset version defaults to 0.
629   Major = Minor = Micro = 0;
630
631   // Parse up to three components.
632   unsigned *Components[3] = { &Major, &Minor, &Micro };
633   for (unsigned i = 0; i != 3; ++i) {
634     if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
635       break;
636
637     // Consume the leading number.
638     *Components[i] = EatNumber(OSName);
639
640     // Consume the separator, if present.
641     if (OSName.startswith("."))
642       OSName = OSName.substr(1);
643   }
644 }
645
646 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
647                               unsigned &Micro) const {
648   getOSVersion(Major, Minor, Micro);
649
650   switch (getOS()) {
651   default: llvm_unreachable("unexpected OS for Darwin triple");
652   case Darwin:
653     // Default to darwin8, i.e., MacOSX 10.4.
654     if (Major == 0)
655       Major = 8;
656     // Darwin version numbers are skewed from OS X versions.
657     if (Major < 4)
658       return false;
659     Micro = 0;
660     Minor = Major - 4;
661     Major = 10;
662     break;
663   case MacOSX:
664     // Default to 10.4.
665     if (Major == 0) {
666       Major = 10;
667       Minor = 4;
668     }
669     if (Major != 10)
670       return false;
671     break;
672   case IOS:
673     // Ignore the version from the triple.  This is only handled because the
674     // the clang driver combines OS X and IOS support into a common Darwin
675     // toolchain that wants to know the OS X version number even when targeting
676     // IOS.
677     Major = 10;
678     Minor = 4;
679     Micro = 0;
680     break;
681   }
682   return true;
683 }
684
685 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
686                            unsigned &Micro) const {
687   switch (getOS()) {
688   default: llvm_unreachable("unexpected OS for Darwin triple");
689   case Darwin:
690   case MacOSX:
691     // Ignore the version from the triple.  This is only handled because the
692     // the clang driver combines OS X and IOS support into a common Darwin
693     // toolchain that wants to know the iOS version number even when targeting
694     // OS X.
695     Major = 5;
696     Minor = 0;
697     Micro = 0;
698     break;
699   case IOS:
700     getOSVersion(Major, Minor, Micro);
701     // Default to 5.0 (or 7.0 for arm64).
702     if (Major == 0)
703       Major = (getArch() == arm64) ? 7 : 5;
704     break;
705   }
706 }
707
708 void Triple::setTriple(const Twine &Str) {
709   *this = Triple(Str);
710 }
711
712 void Triple::setArch(ArchType Kind) {
713   setArchName(getArchTypeName(Kind));
714 }
715
716 void Triple::setVendor(VendorType Kind) {
717   setVendorName(getVendorTypeName(Kind));
718 }
719
720 void Triple::setOS(OSType Kind) {
721   setOSName(getOSTypeName(Kind));
722 }
723
724 void Triple::setEnvironment(EnvironmentType Kind) {
725   setEnvironmentName(getEnvironmentTypeName(Kind));
726 }
727
728 void Triple::setObjectFormat(ObjectFormatType Kind) {
729   setEnvironmentName(getObjectFormatTypeName(Kind));
730 }
731
732 void Triple::setArchName(StringRef Str) {
733   // Work around a miscompilation bug for Twines in gcc 4.0.3.
734   SmallString<64> Triple;
735   Triple += Str;
736   Triple += "-";
737   Triple += getVendorName();
738   Triple += "-";
739   Triple += getOSAndEnvironmentName();
740   setTriple(Triple.str());
741 }
742
743 void Triple::setVendorName(StringRef Str) {
744   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
745 }
746
747 void Triple::setOSName(StringRef Str) {
748   if (hasEnvironment())
749     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
750               "-" + getEnvironmentName());
751   else
752     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
753 }
754
755 void Triple::setEnvironmentName(StringRef Str) {
756   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
757             "-" + Str);
758 }
759
760 void Triple::setOSAndEnvironmentName(StringRef Str) {
761   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
762 }
763
764 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
765   switch (Arch) {
766   case llvm::Triple::UnknownArch:
767     return 0;
768
769   case llvm::Triple::msp430:
770     return 16;
771
772   case llvm::Triple::amdil:
773   case llvm::Triple::arm:
774   case llvm::Triple::armeb:
775   case llvm::Triple::hexagon:
776   case llvm::Triple::le32:
777   case llvm::Triple::mips:
778   case llvm::Triple::mipsel:
779   case llvm::Triple::nvptx:
780   case llvm::Triple::ppc:
781   case llvm::Triple::r600:
782   case llvm::Triple::sparc:
783   case llvm::Triple::tce:
784   case llvm::Triple::thumb:
785   case llvm::Triple::thumbeb:
786   case llvm::Triple::x86:
787   case llvm::Triple::xcore:
788   case llvm::Triple::spir:
789     return 32;
790
791   case llvm::Triple::arm64:
792   case llvm::Triple::aarch64:
793   case llvm::Triple::aarch64_be:
794   case llvm::Triple::mips64:
795   case llvm::Triple::mips64el:
796   case llvm::Triple::nvptx64:
797   case llvm::Triple::ppc64:
798   case llvm::Triple::ppc64le:
799   case llvm::Triple::sparcv9:
800   case llvm::Triple::systemz:
801   case llvm::Triple::x86_64:
802   case llvm::Triple::spir64:
803     return 64;
804   }
805   llvm_unreachable("Invalid architecture value");
806 }
807
808 bool Triple::isArch64Bit() const {
809   return getArchPointerBitWidth(getArch()) == 64;
810 }
811
812 bool Triple::isArch32Bit() const {
813   return getArchPointerBitWidth(getArch()) == 32;
814 }
815
816 bool Triple::isArch16Bit() const {
817   return getArchPointerBitWidth(getArch()) == 16;
818 }
819
820 Triple Triple::get32BitArchVariant() const {
821   Triple T(*this);
822   switch (getArch()) {
823   case Triple::UnknownArch:
824   case Triple::aarch64:
825   case Triple::aarch64_be:
826   case Triple::msp430:
827   case Triple::systemz:
828   case Triple::ppc64le:
829     T.setArch(UnknownArch);
830     break;
831
832   case Triple::amdil:
833   case Triple::spir:
834   case Triple::arm:
835   case Triple::armeb:
836   case Triple::hexagon:
837   case Triple::le32:
838   case Triple::mips:
839   case Triple::mipsel:
840   case Triple::nvptx:
841   case Triple::ppc:
842   case Triple::r600:
843   case Triple::sparc:
844   case Triple::tce:
845   case Triple::thumb:
846   case Triple::thumbeb:
847   case Triple::x86:
848   case Triple::xcore:
849     // Already 32-bit.
850     break;
851
852   case Triple::mips64:    T.setArch(Triple::mips);    break;
853   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
854   case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
855   case Triple::ppc64:     T.setArch(Triple::ppc);     break;
856   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
857   case Triple::x86_64:    T.setArch(Triple::x86);     break;
858   case Triple::spir64:    T.setArch(Triple::spir);    break;
859   case Triple::arm64:     T.setArch(Triple::arm);     break;
860   }
861   return T;
862 }
863
864 Triple Triple::get64BitArchVariant() const {
865   Triple T(*this);
866   switch (getArch()) {
867   case Triple::UnknownArch:
868   case Triple::amdil:
869   case Triple::armeb:
870   case Triple::hexagon:
871   case Triple::le32:
872   case Triple::msp430:
873   case Triple::r600:
874   case Triple::tce:
875   case Triple::thumb:
876   case Triple::thumbeb:
877   case Triple::xcore:
878     T.setArch(UnknownArch);
879     break;
880
881   case Triple::aarch64:
882   case Triple::aarch64_be:
883   case Triple::spir64:
884   case Triple::mips64:
885   case Triple::mips64el:
886   case Triple::nvptx64:
887   case Triple::ppc64:
888   case Triple::ppc64le:
889   case Triple::sparcv9:
890   case Triple::systemz:
891   case Triple::x86_64:
892   case Triple::arm64:
893     // Already 64-bit.
894     break;
895
896   case Triple::mips:    T.setArch(Triple::mips64);    break;
897   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
898   case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
899   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
900   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
901   case Triple::x86:     T.setArch(Triple::x86_64);    break;
902   case Triple::spir:    T.setArch(Triple::spir64);    break;
903   case Triple::arm:     T.setArch(Triple::arm64);     break;
904   }
905   return T;
906 }