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