Support: generalise object type handling for Windows
[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 || 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
581 StringRef Triple::getArchName() const {
582   return StringRef(Data).split('-').first;           // Isolate first component
583 }
584
585 StringRef Triple::getVendorName() const {
586   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
587   return Tmp.split('-').first;                       // Isolate second component
588 }
589
590 StringRef 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
596 StringRef 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
602 StringRef Triple::getOSAndEnvironmentName() const {
603   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
604   return Tmp.split('-').second;                      // Strip second component
605 }
606
607 static 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
622 void 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
649 bool 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
688 void 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
711 void Triple::setTriple(const Twine &Str) {
712   *this = Triple(Str);
713 }
714
715 void Triple::setArch(ArchType Kind) {
716   setArchName(getArchTypeName(Kind));
717 }
718
719 void Triple::setVendor(VendorType Kind) {
720   setVendorName(getVendorTypeName(Kind));
721 }
722
723 void Triple::setOS(OSType Kind) {
724   setOSName(getOSTypeName(Kind));
725 }
726
727 void Triple::setEnvironment(EnvironmentType Kind) {
728   setEnvironmentName(getEnvironmentTypeName(Kind));
729 }
730
731 void 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
740 void 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
751 void Triple::setVendorName(StringRef Str) {
752   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
753 }
754
755 void Triple::setOSName(StringRef Str) {
756   if (hasEnvironment())
757     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
758               "-" + getEnvironmentName());
759   else
760     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
761 }
762
763 void Triple::setEnvironmentName(StringRef Str) {
764   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
765             "-" + Str);
766 }
767
768 void Triple::setOSAndEnvironmentName(StringRef Str) {
769   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
770 }
771
772 static 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
816 bool Triple::isArch64Bit() const {
817   return getArchPointerBitWidth(getArch()) == 64;
818 }
819
820 bool Triple::isArch32Bit() const {
821   return getArchPointerBitWidth(getArch()) == 32;
822 }
823
824 bool Triple::isArch16Bit() const {
825   return getArchPointerBitWidth(getArch()) == 16;
826 }
827
828 Triple 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
872 Triple 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 }