d6408c514f44f2731001b7e2fa2f7dc432c886a2
[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
438   // Note which components are already in their final position.  These will not
439   // be moved.
440   bool Found[4];
441   Found[0] = Arch != UnknownArch;
442   Found[1] = Vendor != UnknownVendor;
443   Found[2] = OS != UnknownOS;
444   Found[3] = Environment != UnknownEnvironment;
445
446   // If they are not there already, permute the components into their canonical
447   // positions by seeing if they parse as a valid architecture, and if so moving
448   // the component to the architecture position etc.
449   for (unsigned Pos = 0; Pos != array_lengthof(Found); ++Pos) {
450     if (Found[Pos])
451       continue; // Already in the canonical position.
452
453     for (unsigned Idx = 0; Idx != Components.size(); ++Idx) {
454       // Do not reparse any components that already matched.
455       if (Idx < array_lengthof(Found) && Found[Idx])
456         continue;
457
458       // Does this component parse as valid for the target position?
459       bool Valid = false;
460       StringRef Comp = Components[Idx];
461       switch (Pos) {
462       default: llvm_unreachable("unexpected component type!");
463       case 0:
464         Arch = parseArch(Comp);
465         Valid = Arch != UnknownArch;
466         break;
467       case 1:
468         Vendor = parseVendor(Comp);
469         Valid = Vendor != UnknownVendor;
470         break;
471       case 2:
472         OS = parseOS(Comp);
473         Valid = OS != UnknownOS;
474         break;
475       case 3:
476         Environment = parseEnvironment(Comp);
477         Valid = Environment != UnknownEnvironment;
478         if (!Valid) {
479           ObjectFormat = parseFormat(Comp);
480           Valid = ObjectFormat != UnknownObjectFormat;
481         }
482         break;
483       }
484       if (!Valid)
485         continue; // Nope, try the next component.
486
487       // Move the component to the target position, pushing any non-fixed
488       // components that are in the way to the right.  This tends to give
489       // good results in the common cases of a forgotten vendor component
490       // or a wrongly positioned environment.
491       if (Pos < Idx) {
492         // Insert left, pushing the existing components to the right.  For
493         // example, a-b-i386 -> i386-a-b when moving i386 to the front.
494         StringRef CurrentComponent(""); // The empty component.
495         // Replace the component we are moving with an empty component.
496         std::swap(CurrentComponent, Components[Idx]);
497         // Insert the component being moved at Pos, displacing any existing
498         // components to the right.
499         for (unsigned i = Pos; !CurrentComponent.empty(); ++i) {
500           // Skip over any fixed components.
501           while (i < array_lengthof(Found) && Found[i])
502             ++i;
503           // Place the component at the new position, getting the component
504           // that was at this position - it will be moved right.
505           std::swap(CurrentComponent, Components[i]);
506         }
507       } else if (Pos > Idx) {
508         // Push right by inserting empty components until the component at Idx
509         // reaches the target position Pos.  For example, pc-a -> -pc-a when
510         // moving pc to the second position.
511         do {
512           // Insert one empty component at Idx.
513           StringRef CurrentComponent(""); // The empty component.
514           for (unsigned i = Idx; i < Components.size();) {
515             // Place the component at the new position, getting the component
516             // that was at this position - it will be moved right.
517             std::swap(CurrentComponent, Components[i]);
518             // If it was placed on top of an empty component then we are done.
519             if (CurrentComponent.empty())
520               break;
521             // Advance to the next component, skipping any fixed components.
522             while (++i < array_lengthof(Found) && Found[i])
523               ;
524           }
525           // The last component was pushed off the end - append it.
526           if (!CurrentComponent.empty())
527             Components.push_back(CurrentComponent);
528
529           // Advance Idx to the component's new position.
530           while (++Idx < array_lengthof(Found) && Found[Idx])
531             ;
532         } while (Idx < Pos); // Add more until the final position is reached.
533       }
534       assert(Pos < Components.size() && Components[Pos] == Comp &&
535              "Component moved wrong!");
536       Found[Pos] = true;
537       break;
538     }
539   }
540
541   // Special case logic goes here.  At this point Arch, Vendor and OS have the
542   // correct values for the computed components.
543
544   if (OS == Triple::Win32) {
545     Components.resize(4);
546     Components[2] = "windows";
547     if (Environment == UnknownEnvironment && ObjectFormat == UnknownObjectFormat)
548       Components[3] = "msvc";
549   } else if (OS == Triple::MinGW32) {
550     Components.resize(4);
551     Components[2] = "windows";
552     Components[3] = (ObjectFormat == Triple::ELF) ? "gnuelf" : "gnu";
553   } else if (OS == Triple::Cygwin) {
554     Components.resize(4);
555     Components[2] = "windows";
556     Components[3] = "cygnus";
557   }
558
559   // Stick the corrected components back together to form the normalized string.
560   std::string Normalized;
561   for (unsigned i = 0, e = Components.size(); i != e; ++i) {
562     if (i) Normalized += '-';
563     Normalized += Components[i];
564   }
565   return Normalized;
566 }
567
568 StringRef Triple::getArchName() const {
569   return StringRef(Data).split('-').first;           // Isolate first component
570 }
571
572 StringRef Triple::getVendorName() const {
573   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
574   return Tmp.split('-').first;                       // Isolate second component
575 }
576
577 StringRef Triple::getOSName() const {
578   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
579   Tmp = Tmp.split('-').second;                       // Strip second component
580   return Tmp.split('-').first;                       // Isolate third component
581 }
582
583 StringRef Triple::getEnvironmentName() const {
584   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
585   Tmp = Tmp.split('-').second;                       // Strip second component
586   return Tmp.split('-').second;                      // Strip third component
587 }
588
589 StringRef Triple::getOSAndEnvironmentName() const {
590   StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
591   return Tmp.split('-').second;                      // Strip second component
592 }
593
594 static unsigned EatNumber(StringRef &Str) {
595   assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
596   unsigned Result = 0;
597
598   do {
599     // Consume the leading digit.
600     Result = Result*10 + (Str[0] - '0');
601
602     // Eat the digit.
603     Str = Str.substr(1);
604   } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
605
606   return Result;
607 }
608
609 void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
610                           unsigned &Micro) const {
611   StringRef OSName = getOSName();
612
613   // Assume that the OS portion of the triple starts with the canonical name.
614   StringRef OSTypeName = getOSTypeName(getOS());
615   if (OSName.startswith(OSTypeName))
616     OSName = OSName.substr(OSTypeName.size());
617
618   // Any unset version defaults to 0.
619   Major = Minor = Micro = 0;
620
621   // Parse up to three components.
622   unsigned *Components[3] = { &Major, &Minor, &Micro };
623   for (unsigned i = 0; i != 3; ++i) {
624     if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
625       break;
626
627     // Consume the leading number.
628     *Components[i] = EatNumber(OSName);
629
630     // Consume the separator, if present.
631     if (OSName.startswith("."))
632       OSName = OSName.substr(1);
633   }
634 }
635
636 bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
637                               unsigned &Micro) const {
638   getOSVersion(Major, Minor, Micro);
639
640   switch (getOS()) {
641   default: llvm_unreachable("unexpected OS for Darwin triple");
642   case Darwin:
643     // Default to darwin8, i.e., MacOSX 10.4.
644     if (Major == 0)
645       Major = 8;
646     // Darwin version numbers are skewed from OS X versions.
647     if (Major < 4)
648       return false;
649     Micro = 0;
650     Minor = Major - 4;
651     Major = 10;
652     break;
653   case MacOSX:
654     // Default to 10.4.
655     if (Major == 0) {
656       Major = 10;
657       Minor = 4;
658     }
659     if (Major != 10)
660       return false;
661     break;
662   case IOS:
663     // Ignore the version from the triple.  This is only handled because the
664     // the clang driver combines OS X and IOS support into a common Darwin
665     // toolchain that wants to know the OS X version number even when targeting
666     // IOS.
667     Major = 10;
668     Minor = 4;
669     Micro = 0;
670     break;
671   }
672   return true;
673 }
674
675 void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
676                            unsigned &Micro) const {
677   switch (getOS()) {
678   default: llvm_unreachable("unexpected OS for Darwin triple");
679   case Darwin:
680   case MacOSX:
681     // Ignore the version from the triple.  This is only handled because the
682     // the clang driver combines OS X and IOS support into a common Darwin
683     // toolchain that wants to know the iOS version number even when targeting
684     // OS X.
685     Major = 5;
686     Minor = 0;
687     Micro = 0;
688     break;
689   case IOS:
690     getOSVersion(Major, Minor, Micro);
691     // Default to 5.0 (or 7.0 for arm64).
692     if (Major == 0)
693       Major = (getArch() == arm64) ? 7 : 5;
694     break;
695   }
696 }
697
698 void Triple::setTriple(const Twine &Str) {
699   *this = Triple(Str);
700 }
701
702 void Triple::setArch(ArchType Kind) {
703   setArchName(getArchTypeName(Kind));
704 }
705
706 void Triple::setVendor(VendorType Kind) {
707   setVendorName(getVendorTypeName(Kind));
708 }
709
710 void Triple::setOS(OSType Kind) {
711   setOSName(getOSTypeName(Kind));
712 }
713
714 void Triple::setEnvironment(EnvironmentType Kind) {
715   setEnvironmentName(getEnvironmentTypeName(Kind));
716 }
717
718 void Triple::setObjectFormat(ObjectFormatType Kind) {
719   setEnvironmentName(getObjectFormatTypeName(Kind));
720 }
721
722 void Triple::setArchName(StringRef Str) {
723   // Work around a miscompilation bug for Twines in gcc 4.0.3.
724   SmallString<64> Triple;
725   Triple += Str;
726   Triple += "-";
727   Triple += getVendorName();
728   Triple += "-";
729   Triple += getOSAndEnvironmentName();
730   setTriple(Triple.str());
731 }
732
733 void Triple::setVendorName(StringRef Str) {
734   setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
735 }
736
737 void Triple::setOSName(StringRef Str) {
738   if (hasEnvironment())
739     setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
740               "-" + getEnvironmentName());
741   else
742     setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
743 }
744
745 void Triple::setEnvironmentName(StringRef Str) {
746   setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
747             "-" + Str);
748 }
749
750 void Triple::setOSAndEnvironmentName(StringRef Str) {
751   setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
752 }
753
754 static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
755   switch (Arch) {
756   case llvm::Triple::UnknownArch:
757     return 0;
758
759   case llvm::Triple::msp430:
760     return 16;
761
762   case llvm::Triple::amdil:
763   case llvm::Triple::arm:
764   case llvm::Triple::armeb:
765   case llvm::Triple::hexagon:
766   case llvm::Triple::le32:
767   case llvm::Triple::mips:
768   case llvm::Triple::mipsel:
769   case llvm::Triple::nvptx:
770   case llvm::Triple::ppc:
771   case llvm::Triple::r600:
772   case llvm::Triple::sparc:
773   case llvm::Triple::tce:
774   case llvm::Triple::thumb:
775   case llvm::Triple::thumbeb:
776   case llvm::Triple::x86:
777   case llvm::Triple::xcore:
778   case llvm::Triple::spir:
779     return 32;
780
781   case llvm::Triple::arm64:
782   case llvm::Triple::aarch64:
783   case llvm::Triple::aarch64_be:
784   case llvm::Triple::mips64:
785   case llvm::Triple::mips64el:
786   case llvm::Triple::nvptx64:
787   case llvm::Triple::ppc64:
788   case llvm::Triple::ppc64le:
789   case llvm::Triple::sparcv9:
790   case llvm::Triple::systemz:
791   case llvm::Triple::x86_64:
792   case llvm::Triple::spir64:
793     return 64;
794   }
795   llvm_unreachable("Invalid architecture value");
796 }
797
798 bool Triple::isArch64Bit() const {
799   return getArchPointerBitWidth(getArch()) == 64;
800 }
801
802 bool Triple::isArch32Bit() const {
803   return getArchPointerBitWidth(getArch()) == 32;
804 }
805
806 bool Triple::isArch16Bit() const {
807   return getArchPointerBitWidth(getArch()) == 16;
808 }
809
810 Triple Triple::get32BitArchVariant() const {
811   Triple T(*this);
812   switch (getArch()) {
813   case Triple::UnknownArch:
814   case Triple::aarch64:
815   case Triple::aarch64_be:
816   case Triple::msp430:
817   case Triple::systemz:
818   case Triple::ppc64le:
819     T.setArch(UnknownArch);
820     break;
821
822   case Triple::amdil:
823   case Triple::spir:
824   case Triple::arm:
825   case Triple::armeb:
826   case Triple::hexagon:
827   case Triple::le32:
828   case Triple::mips:
829   case Triple::mipsel:
830   case Triple::nvptx:
831   case Triple::ppc:
832   case Triple::r600:
833   case Triple::sparc:
834   case Triple::tce:
835   case Triple::thumb:
836   case Triple::thumbeb:
837   case Triple::x86:
838   case Triple::xcore:
839     // Already 32-bit.
840     break;
841
842   case Triple::mips64:    T.setArch(Triple::mips);    break;
843   case Triple::mips64el:  T.setArch(Triple::mipsel);  break;
844   case Triple::nvptx64:   T.setArch(Triple::nvptx);   break;
845   case Triple::ppc64:     T.setArch(Triple::ppc);     break;
846   case Triple::sparcv9:   T.setArch(Triple::sparc);   break;
847   case Triple::x86_64:    T.setArch(Triple::x86);     break;
848   case Triple::spir64:    T.setArch(Triple::spir);    break;
849   case Triple::arm64:     T.setArch(Triple::arm);     break;
850   }
851   return T;
852 }
853
854 Triple Triple::get64BitArchVariant() const {
855   Triple T(*this);
856   switch (getArch()) {
857   case Triple::UnknownArch:
858   case Triple::amdil:
859   case Triple::armeb:
860   case Triple::hexagon:
861   case Triple::le32:
862   case Triple::msp430:
863   case Triple::r600:
864   case Triple::tce:
865   case Triple::thumb:
866   case Triple::thumbeb:
867   case Triple::xcore:
868     T.setArch(UnknownArch);
869     break;
870
871   case Triple::aarch64:
872   case Triple::aarch64_be:
873   case Triple::spir64:
874   case Triple::mips64:
875   case Triple::mips64el:
876   case Triple::nvptx64:
877   case Triple::ppc64:
878   case Triple::ppc64le:
879   case Triple::sparcv9:
880   case Triple::systemz:
881   case Triple::x86_64:
882   case Triple::arm64:
883     // Already 64-bit.
884     break;
885
886   case Triple::mips:    T.setArch(Triple::mips64);    break;
887   case Triple::mipsel:  T.setArch(Triple::mips64el);  break;
888   case Triple::nvptx:   T.setArch(Triple::nvptx64);   break;
889   case Triple::ppc:     T.setArch(Triple::ppc64);     break;
890   case Triple::sparc:   T.setArch(Triple::sparcv9);   break;
891   case Triple::x86:     T.setArch(Triple::x86_64);    break;
892   case Triple::spir:    T.setArch(Triple::spir64);    break;
893   case Triple::arm:     T.setArch(Triple::arm64);     break;
894   }
895   return T;
896 }