Home | History | Annotate | Line # | Download | only in Basic
Targets.cpp revision 1.1.1.2
      1 //===--- Targets.cpp - Implement target feature support -------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file implements construction of a TargetInfo object from a
     10 // target triple.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "Targets.h"
     15 
     16 #include "Targets/AArch64.h"
     17 #include "Targets/AMDGPU.h"
     18 #include "Targets/ARC.h"
     19 #include "Targets/ARM.h"
     20 #include "Targets/AVR.h"
     21 #include "Targets/BPF.h"
     22 #include "Targets/Hexagon.h"
     23 #include "Targets/Lanai.h"
     24 #include "Targets/Le64.h"
     25 #include "Targets/M68k.h"
     26 #include "Targets/MSP430.h"
     27 #include "Targets/Mips.h"
     28 #include "Targets/NVPTX.h"
     29 #include "Targets/OSTargets.h"
     30 #include "Targets/PNaCl.h"
     31 #include "Targets/PPC.h"
     32 #include "Targets/RISCV.h"
     33 #include "Targets/SPIR.h"
     34 #include "Targets/Sparc.h"
     35 #include "Targets/SystemZ.h"
     36 #include "Targets/TCE.h"
     37 #include "Targets/VE.h"
     38 #include "Targets/WebAssembly.h"
     39 #include "Targets/X86.h"
     40 #include "Targets/XCore.h"
     41 #include "clang/Basic/Diagnostic.h"
     42 #include "llvm/ADT/StringExtras.h"
     43 #include "llvm/ADT/Triple.h"
     44 
     45 using namespace clang;
     46 
     47 namespace clang {
     48 namespace targets {
     49 //===----------------------------------------------------------------------===//
     50 //  Common code shared among targets.
     51 //===----------------------------------------------------------------------===//
     52 
     53 /// DefineStd - Define a macro name and standard variants.  For example if
     54 /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
     55 /// when in GNU mode.
     56 void DefineStd(MacroBuilder &Builder, StringRef MacroName,
     57                const LangOptions &Opts) {
     58   assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
     59 
     60   // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier
     61   // in the user's namespace.
     62   if (Opts.GNUMode)
     63     Builder.defineMacro(MacroName);
     64 
     65   // Define __unix.
     66   Builder.defineMacro("__" + MacroName);
     67 
     68   // Define __unix__.
     69   Builder.defineMacro("__" + MacroName + "__");
     70 }
     71 
     72 void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, bool Tuning) {
     73   Builder.defineMacro("__" + CPUName);
     74   Builder.defineMacro("__" + CPUName + "__");
     75   if (Tuning)
     76     Builder.defineMacro("__tune_" + CPUName + "__");
     77 }
     78 
     79 void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) {
     80   // Mingw and cygwin define __declspec(a) to __attribute__((a)).  Clang
     81   // supports __declspec natively under -fms-extensions, but we define a no-op
     82   // __declspec macro anyway for pre-processor compatibility.
     83   if (Opts.MicrosoftExt)
     84     Builder.defineMacro("__declspec", "__declspec");
     85   else
     86     Builder.defineMacro("__declspec(a)", "__attribute__((a))");
     87 
     88   if (!Opts.MicrosoftExt) {
     89     // Provide macros for all the calling convention keywords.  Provide both
     90     // single and double underscore prefixed variants.  These are available on
     91     // x64 as well as x86, even though they have no effect.
     92     const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"};
     93     for (const char *CC : CCs) {
     94       std::string GCCSpelling = "__attribute__((__";
     95       GCCSpelling += CC;
     96       GCCSpelling += "__))";
     97       Builder.defineMacro(Twine("_") + CC, GCCSpelling);
     98       Builder.defineMacro(Twine("__") + CC, GCCSpelling);
     99     }
    100   }
    101 }
    102 
    103 //===----------------------------------------------------------------------===//
    104 // Driver code
    105 //===----------------------------------------------------------------------===//
    106 
    107 TargetInfo *AllocateTarget(const llvm::Triple &Triple,
    108                            const TargetOptions &Opts) {
    109   llvm::Triple::OSType os = Triple.getOS();
    110 
    111   switch (Triple.getArch()) {
    112   default:
    113     return nullptr;
    114 
    115   case llvm::Triple::arc:
    116     return new ARCTargetInfo(Triple, Opts);
    117 
    118   case llvm::Triple::xcore:
    119     return new XCoreTargetInfo(Triple, Opts);
    120 
    121   case llvm::Triple::hexagon:
    122     if (os == llvm::Triple::Linux &&
    123         Triple.getEnvironment() == llvm::Triple::Musl)
    124       return new LinuxTargetInfo<HexagonTargetInfo>(Triple, Opts);
    125     return new HexagonTargetInfo(Triple, Opts);
    126 
    127   case llvm::Triple::lanai:
    128     return new LanaiTargetInfo(Triple, Opts);
    129 
    130   case llvm::Triple::aarch64_32:
    131     if (Triple.isOSDarwin())
    132       return new DarwinAArch64TargetInfo(Triple, Opts);
    133 
    134     return nullptr;
    135   case llvm::Triple::aarch64:
    136     if (Triple.isOSDarwin())
    137       return new DarwinAArch64TargetInfo(Triple, Opts);
    138 
    139     switch (os) {
    140     case llvm::Triple::CloudABI:
    141       return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts);
    142     case llvm::Triple::FreeBSD:
    143       return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
    144     case llvm::Triple::Fuchsia:
    145       return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts);
    146     case llvm::Triple::Linux:
    147       return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts);
    148     case llvm::Triple::NetBSD:
    149       return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
    150     case llvm::Triple::OpenBSD:
    151       return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts);
    152     case llvm::Triple::Win32:
    153       switch (Triple.getEnvironment()) {
    154       case llvm::Triple::GNU:
    155         return new MinGWARM64TargetInfo(Triple, Opts);
    156       case llvm::Triple::MSVC:
    157       default: // Assume MSVC for unknown environments
    158         return new MicrosoftARM64TargetInfo(Triple, Opts);
    159       }
    160     default:
    161       return new AArch64leTargetInfo(Triple, Opts);
    162     }
    163 
    164   case llvm::Triple::aarch64_be:
    165     switch (os) {
    166     case llvm::Triple::FreeBSD:
    167       return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
    168     case llvm::Triple::Fuchsia:
    169       return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts);
    170     case llvm::Triple::Linux:
    171       return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts);
    172     case llvm::Triple::NetBSD:
    173       return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts);
    174     default:
    175       return new AArch64beTargetInfo(Triple, Opts);
    176     }
    177 
    178   case llvm::Triple::arm:
    179   case llvm::Triple::thumb:
    180     if (Triple.isOSBinFormatMachO())
    181       return new DarwinARMTargetInfo(Triple, Opts);
    182 
    183     switch (os) {
    184     case llvm::Triple::CloudABI:
    185       return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts);
    186     case llvm::Triple::Linux:
    187       return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts);
    188     case llvm::Triple::FreeBSD:
    189       return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
    190     case llvm::Triple::NetBSD:
    191       return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
    192     case llvm::Triple::OpenBSD:
    193       return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts);
    194     case llvm::Triple::RTEMS:
    195       return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts);
    196     case llvm::Triple::NaCl:
    197       return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts);
    198     case llvm::Triple::Win32:
    199       switch (Triple.getEnvironment()) {
    200       case llvm::Triple::Cygnus:
    201         return new CygwinARMTargetInfo(Triple, Opts);
    202       case llvm::Triple::GNU:
    203         return new MinGWARMTargetInfo(Triple, Opts);
    204       case llvm::Triple::Itanium:
    205         return new ItaniumWindowsARMleTargetInfo(Triple, Opts);
    206       case llvm::Triple::MSVC:
    207       default: // Assume MSVC for unknown environments
    208         return new MicrosoftARMleTargetInfo(Triple, Opts);
    209       }
    210     default:
    211       return new ARMleTargetInfo(Triple, Opts);
    212     }
    213 
    214   case llvm::Triple::armeb:
    215   case llvm::Triple::thumbeb:
    216     if (Triple.isOSDarwin())
    217       return new DarwinARMTargetInfo(Triple, Opts);
    218 
    219     switch (os) {
    220     case llvm::Triple::Linux:
    221       return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts);
    222     case llvm::Triple::FreeBSD:
    223       return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
    224     case llvm::Triple::NetBSD:
    225       return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
    226     case llvm::Triple::OpenBSD:
    227       return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts);
    228     case llvm::Triple::RTEMS:
    229       return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts);
    230     case llvm::Triple::NaCl:
    231       return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts);
    232     default:
    233       return new ARMbeTargetInfo(Triple, Opts);
    234     }
    235 
    236   case llvm::Triple::avr:
    237     return new AVRTargetInfo(Triple, Opts);
    238   case llvm::Triple::bpfeb:
    239   case llvm::Triple::bpfel:
    240     return new BPFTargetInfo(Triple, Opts);
    241 
    242   case llvm::Triple::msp430:
    243     return new MSP430TargetInfo(Triple, Opts);
    244 
    245   case llvm::Triple::mips:
    246     switch (os) {
    247     case llvm::Triple::Linux:
    248       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
    249     case llvm::Triple::RTEMS:
    250       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
    251     case llvm::Triple::FreeBSD:
    252       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    253     case llvm::Triple::NetBSD:
    254       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    255     default:
    256       return new MipsTargetInfo(Triple, Opts);
    257     }
    258 
    259   case llvm::Triple::mipsel:
    260     switch (os) {
    261     case llvm::Triple::Linux:
    262       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
    263     case llvm::Triple::RTEMS:
    264       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
    265     case llvm::Triple::FreeBSD:
    266       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    267     case llvm::Triple::NetBSD:
    268       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    269     case llvm::Triple::NaCl:
    270       return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts);
    271     default:
    272       return new MipsTargetInfo(Triple, Opts);
    273     }
    274 
    275   case llvm::Triple::mips64:
    276     switch (os) {
    277     case llvm::Triple::Linux:
    278       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
    279     case llvm::Triple::RTEMS:
    280       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
    281     case llvm::Triple::FreeBSD:
    282       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    283     case llvm::Triple::NetBSD:
    284       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    285     case llvm::Triple::OpenBSD:
    286       return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    287     default:
    288       return new MipsTargetInfo(Triple, Opts);
    289     }
    290 
    291   case llvm::Triple::mips64el:
    292     switch (os) {
    293     case llvm::Triple::Linux:
    294       return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts);
    295     case llvm::Triple::RTEMS:
    296       return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts);
    297     case llvm::Triple::FreeBSD:
    298       return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    299     case llvm::Triple::NetBSD:
    300       return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    301     case llvm::Triple::OpenBSD:
    302       return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts);
    303     default:
    304       return new MipsTargetInfo(Triple, Opts);
    305     }
    306 
    307   case llvm::Triple::m68k:
    308     switch (os) {
    309     case llvm::Triple::Linux:
    310       return new LinuxTargetInfo<M68kTargetInfo>(Triple, Opts);
    311     case llvm::Triple::NetBSD:
    312       return new NetBSDTargetInfo<M68kTargetInfo>(Triple, Opts);
    313     default:
    314       return new M68kTargetInfo(Triple, Opts);
    315     }
    316 
    317   case llvm::Triple::le32:
    318     switch (os) {
    319     case llvm::Triple::NaCl:
    320       return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts);
    321     default:
    322       return nullptr;
    323     }
    324 
    325   case llvm::Triple::le64:
    326     return new Le64TargetInfo(Triple, Opts);
    327 
    328   case llvm::Triple::ppc:
    329     if (Triple.isOSDarwin())
    330       return new DarwinPPC32TargetInfo(Triple, Opts);
    331     switch (os) {
    332     case llvm::Triple::Linux:
    333       return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
    334     case llvm::Triple::FreeBSD:
    335       return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
    336     case llvm::Triple::NetBSD:
    337       return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
    338     case llvm::Triple::OpenBSD:
    339       return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
    340     case llvm::Triple::RTEMS:
    341       return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts);
    342     case llvm::Triple::AIX:
    343       return new AIXPPC32TargetInfo(Triple, Opts);
    344     default:
    345       return new PPC32TargetInfo(Triple, Opts);
    346     }
    347 
    348   case llvm::Triple::ppcle:
    349     switch (os) {
    350     case llvm::Triple::Linux:
    351       return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts);
    352     case llvm::Triple::FreeBSD:
    353       return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts);
    354     default:
    355       return new PPC32TargetInfo(Triple, Opts);
    356     }
    357 
    358   case llvm::Triple::ppc64:
    359     if (Triple.isOSDarwin())
    360       return new DarwinPPC64TargetInfo(Triple, Opts);
    361     switch (os) {
    362     case llvm::Triple::Linux:
    363       return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
    364     case llvm::Triple::Lv2:
    365       return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts);
    366     case llvm::Triple::FreeBSD:
    367       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
    368     case llvm::Triple::NetBSD:
    369       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
    370     case llvm::Triple::OpenBSD:
    371       return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
    372     case llvm::Triple::AIX:
    373       return new AIXPPC64TargetInfo(Triple, Opts);
    374     default:
    375       return new PPC64TargetInfo(Triple, Opts);
    376     }
    377 
    378   case llvm::Triple::ppc64le:
    379     switch (os) {
    380     case llvm::Triple::Linux:
    381       return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts);
    382     case llvm::Triple::FreeBSD:
    383       return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
    384     case llvm::Triple::NetBSD:
    385       return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
    386     case llvm::Triple::OpenBSD:
    387       return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts);
    388     default:
    389       return new PPC64TargetInfo(Triple, Opts);
    390     }
    391 
    392   case llvm::Triple::nvptx:
    393     return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32);
    394   case llvm::Triple::nvptx64:
    395     return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64);
    396 
    397   case llvm::Triple::amdgcn:
    398   case llvm::Triple::r600:
    399     return new AMDGPUTargetInfo(Triple, Opts);
    400 
    401   case llvm::Triple::riscv32:
    402     // TODO: add cases for NetBSD, RTEMS once tested.
    403     switch (os) {
    404     case llvm::Triple::FreeBSD:
    405       return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts);
    406     case llvm::Triple::Linux:
    407       return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts);
    408     default:
    409       return new RISCV32TargetInfo(Triple, Opts);
    410     }
    411 
    412   case llvm::Triple::riscv64:
    413     // TODO: add cases for NetBSD, RTEMS once tested.
    414     switch (os) {
    415     case llvm::Triple::FreeBSD:
    416       return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
    417     case llvm::Triple::OpenBSD:
    418       return new OpenBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
    419     case llvm::Triple::Fuchsia:
    420       return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts);
    421     case llvm::Triple::Linux:
    422       return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
    423     default:
    424       return new RISCV64TargetInfo(Triple, Opts);
    425     }
    426 
    427   case llvm::Triple::sparc:
    428     switch (os) {
    429     case llvm::Triple::Linux:
    430       return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts);
    431     case llvm::Triple::Solaris:
    432       return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts);
    433     case llvm::Triple::NetBSD:
    434       return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts);
    435     case llvm::Triple::RTEMS:
    436       return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts);
    437     default:
    438       return new SparcV8TargetInfo(Triple, Opts);
    439     }
    440 
    441   // The 'sparcel' architecture copies all the above cases except for Solaris.
    442   case llvm::Triple::sparcel:
    443     switch (os) {
    444     case llvm::Triple::Linux:
    445       return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
    446     case llvm::Triple::NetBSD:
    447       return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
    448     case llvm::Triple::RTEMS:
    449       return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts);
    450     default:
    451       return new SparcV8elTargetInfo(Triple, Opts);
    452     }
    453 
    454   case llvm::Triple::sparcv9:
    455     switch (os) {
    456     case llvm::Triple::Linux:
    457       return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts);
    458     case llvm::Triple::Solaris:
    459       return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts);
    460     case llvm::Triple::NetBSD:
    461       return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
    462     case llvm::Triple::OpenBSD:
    463       return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
    464     case llvm::Triple::FreeBSD:
    465       return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts);
    466     default:
    467       return new SparcV9TargetInfo(Triple, Opts);
    468     }
    469 
    470   case llvm::Triple::systemz:
    471     switch (os) {
    472     case llvm::Triple::Linux:
    473       return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts);
    474     case llvm::Triple::ZOS:
    475       return new ZOSTargetInfo<SystemZTargetInfo>(Triple, Opts);
    476     default:
    477       return new SystemZTargetInfo(Triple, Opts);
    478     }
    479 
    480   case llvm::Triple::tce:
    481     return new TCETargetInfo(Triple, Opts);
    482 
    483   case llvm::Triple::tcele:
    484     return new TCELETargetInfo(Triple, Opts);
    485 
    486   case llvm::Triple::x86:
    487     if (Triple.isOSDarwin())
    488       return new DarwinI386TargetInfo(Triple, Opts);
    489 
    490     switch (os) {
    491     case llvm::Triple::Ananas:
    492       return new AnanasTargetInfo<X86_32TargetInfo>(Triple, Opts);
    493     case llvm::Triple::CloudABI:
    494       return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts);
    495     case llvm::Triple::Linux: {
    496       switch (Triple.getEnvironment()) {
    497       default:
    498         return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts);
    499       case llvm::Triple::Android:
    500         return new AndroidX86_32TargetInfo(Triple, Opts);
    501       }
    502     }
    503     case llvm::Triple::DragonFly:
    504       return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
    505     case llvm::Triple::NetBSD:
    506       return new NetBSDI386TargetInfo(Triple, Opts);
    507     case llvm::Triple::OpenBSD:
    508       return new OpenBSDI386TargetInfo(Triple, Opts);
    509     case llvm::Triple::FreeBSD:
    510       return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
    511     case llvm::Triple::Fuchsia:
    512       return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts);
    513     case llvm::Triple::KFreeBSD:
    514       return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts);
    515     case llvm::Triple::Minix:
    516       return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts);
    517     case llvm::Triple::Solaris:
    518       return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts);
    519     case llvm::Triple::Win32: {
    520       switch (Triple.getEnvironment()) {
    521       case llvm::Triple::Cygnus:
    522         return new CygwinX86_32TargetInfo(Triple, Opts);
    523       case llvm::Triple::GNU:
    524         return new MinGWX86_32TargetInfo(Triple, Opts);
    525       case llvm::Triple::Itanium:
    526       case llvm::Triple::MSVC:
    527       default: // Assume MSVC for unknown environments
    528         return new MicrosoftX86_32TargetInfo(Triple, Opts);
    529       }
    530     }
    531     case llvm::Triple::Haiku:
    532       return new HaikuX86_32TargetInfo(Triple, Opts);
    533     case llvm::Triple::RTEMS:
    534       return new RTEMSX86_32TargetInfo(Triple, Opts);
    535     case llvm::Triple::NaCl:
    536       return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts);
    537     case llvm::Triple::ELFIAMCU:
    538       return new MCUX86_32TargetInfo(Triple, Opts);
    539     case llvm::Triple::Hurd:
    540       return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts);
    541     default:
    542       return new X86_32TargetInfo(Triple, Opts);
    543     }
    544 
    545   case llvm::Triple::x86_64:
    546     if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
    547       return new DarwinX86_64TargetInfo(Triple, Opts);
    548 
    549     switch (os) {
    550     case llvm::Triple::Ananas:
    551       return new AnanasTargetInfo<X86_64TargetInfo>(Triple, Opts);
    552     case llvm::Triple::CloudABI:
    553       return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts);
    554     case llvm::Triple::Linux: {
    555       switch (Triple.getEnvironment()) {
    556       default:
    557         return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts);
    558       case llvm::Triple::Android:
    559         return new AndroidX86_64TargetInfo(Triple, Opts);
    560       }
    561     }
    562     case llvm::Triple::DragonFly:
    563       return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
    564     case llvm::Triple::NetBSD:
    565       return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
    566     case llvm::Triple::OpenBSD:
    567       return new OpenBSDX86_64TargetInfo(Triple, Opts);
    568     case llvm::Triple::FreeBSD:
    569       return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
    570     case llvm::Triple::Fuchsia:
    571       return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts);
    572     case llvm::Triple::KFreeBSD:
    573       return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts);
    574     case llvm::Triple::Solaris:
    575       return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts);
    576     case llvm::Triple::Win32: {
    577       switch (Triple.getEnvironment()) {
    578       case llvm::Triple::Cygnus:
    579         return new CygwinX86_64TargetInfo(Triple, Opts);
    580       case llvm::Triple::GNU:
    581         return new MinGWX86_64TargetInfo(Triple, Opts);
    582       case llvm::Triple::MSVC:
    583       default: // Assume MSVC for unknown environments
    584         return new MicrosoftX86_64TargetInfo(Triple, Opts);
    585       }
    586     }
    587     case llvm::Triple::Haiku:
    588       return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts);
    589     case llvm::Triple::NaCl:
    590       return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts);
    591     case llvm::Triple::PS4:
    592       return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts);
    593     default:
    594       return new X86_64TargetInfo(Triple, Opts);
    595     }
    596 
    597   case llvm::Triple::spir: {
    598     if (os != llvm::Triple::UnknownOS ||
    599         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
    600       return nullptr;
    601     return new SPIR32TargetInfo(Triple, Opts);
    602   }
    603   case llvm::Triple::spir64: {
    604     if (os != llvm::Triple::UnknownOS ||
    605         Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
    606       return nullptr;
    607     return new SPIR64TargetInfo(Triple, Opts);
    608   }
    609   case llvm::Triple::wasm32:
    610     if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
    611         Triple.getVendor() != llvm::Triple::UnknownVendor ||
    612         !Triple.isOSBinFormatWasm())
    613       return nullptr;
    614     switch (os) {
    615       case llvm::Triple::WASI:
    616         return new WASITargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
    617       case llvm::Triple::Emscripten:
    618         return new EmscriptenTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
    619       case llvm::Triple::UnknownOS:
    620         return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
    621       default:
    622         return nullptr;
    623     }
    624   case llvm::Triple::wasm64:
    625     if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
    626         Triple.getVendor() != llvm::Triple::UnknownVendor ||
    627         !Triple.isOSBinFormatWasm())
    628       return nullptr;
    629     switch (os) {
    630       case llvm::Triple::WASI:
    631         return new WASITargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
    632       case llvm::Triple::Emscripten:
    633         return new EmscriptenTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
    634       case llvm::Triple::UnknownOS:
    635         return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
    636       default:
    637         return nullptr;
    638     }
    639 
    640   case llvm::Triple::renderscript32:
    641     return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts);
    642   case llvm::Triple::renderscript64:
    643     return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts);
    644 
    645   case llvm::Triple::ve:
    646     return new LinuxTargetInfo<VETargetInfo>(Triple, Opts);
    647   }
    648 }
    649 } // namespace targets
    650 } // namespace clang
    651 
    652 using namespace clang::targets;
    653 /// CreateTargetInfo - Return the target info object for the specified target
    654 /// options.
    655 TargetInfo *
    656 TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
    657                              const std::shared_ptr<TargetOptions> &Opts) {
    658   llvm::Triple Triple(Opts->Triple);
    659 
    660   // Construct the target
    661   std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts));
    662   if (!Target) {
    663     Diags.Report(diag::err_target_unknown_triple) << Triple.str();
    664     return nullptr;
    665   }
    666   Target->TargetOpts = Opts;
    667 
    668   // Set the target CPU if specified.
    669   if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
    670     Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
    671     SmallVector<StringRef, 32> ValidList;
    672     Target->fillValidCPUList(ValidList);
    673     if (!ValidList.empty())
    674       Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", ");
    675     return nullptr;
    676   }
    677 
    678   // Check the TuneCPU name if specified.
    679   if (!Opts->TuneCPU.empty() &&
    680       !Target->isValidTuneCPUName(Opts->TuneCPU)) {
    681     Diags.Report(diag::err_target_unknown_cpu) << Opts->TuneCPU;
    682     SmallVector<StringRef, 32> ValidList;
    683     Target->fillValidTuneCPUList(ValidList);
    684     if (!ValidList.empty())
    685       Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", ");
    686     return nullptr;
    687   }
    688 
    689   // Set the target ABI if specified.
    690   if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
    691     Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
    692     return nullptr;
    693   }
    694 
    695   // Set the fp math unit.
    696   if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
    697     Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
    698     return nullptr;
    699   }
    700 
    701   // Compute the default target features, we need the target to handle this
    702   // because features may have dependencies on one another.
    703   if (!Target->initFeatureMap(Opts->FeatureMap, Diags, Opts->CPU,
    704                               Opts->FeaturesAsWritten))
    705     return nullptr;
    706 
    707   // Add the features to the compile options.
    708   Opts->Features.clear();
    709   for (const auto &F : Opts->FeatureMap)
    710     Opts->Features.push_back((F.getValue() ? "+" : "-") + F.getKey().str());
    711   // Sort here, so we handle the features in a predictable order. (This matters
    712   // when we're dealing with features that overlap.)
    713   llvm::sort(Opts->Features);
    714 
    715   if (!Target->handleTargetFeatures(Opts->Features, Diags))
    716     return nullptr;
    717 
    718   Target->setSupportedOpenCLOpts();
    719   Target->setCommandLineOpenCLOpts();
    720   Target->setMaxAtomicWidth();
    721 
    722   if (!Target->validateTarget(Diags))
    723     return nullptr;
    724 
    725   Target->CheckFixedPointBits();
    726 
    727   return Target.release();
    728 }
    729 /// validateOpenCLTarget  - Check that OpenCL target has valid
    730 /// options setting based on OpenCL version.
    731 bool TargetInfo::validateOpenCLTarget(const LangOptions &Opts,
    732                                       DiagnosticsEngine &Diags) const {
    733   const llvm::StringMap<bool> &OpenCLFeaturesMap = getSupportedOpenCLOpts();
    734 
    735   auto diagnoseNotSupportedCore = [&](llvm::StringRef Name, auto... OptArgs) {
    736     if (OpenCLOptions::isOpenCLOptionCoreIn(Opts, OptArgs...) &&
    737         !hasFeatureEnabled(OpenCLFeaturesMap, Name))
    738       Diags.Report(diag::warn_opencl_unsupported_core_feature)
    739           << Name << Opts.OpenCLCPlusPlus
    740           << Opts.getOpenCLVersionTuple().getAsString();
    741   };
    742 #define OPENCL_GENERIC_EXTENSION(Ext, ...)                                     \
    743   diagnoseNotSupportedCore(#Ext, __VA_ARGS__);
    744 #include "clang/Basic/OpenCLExtensions.def"
    745 
    746   // Validate that feature macros are set properly for OpenCL C 3.0.
    747   // In other cases assume that target is always valid.
    748   if (Opts.OpenCLCPlusPlus || Opts.OpenCLVersion < 300)
    749     return true;
    750 
    751   // Feature and corresponding equivalent extension must be set
    752   // simultaneously to the same value.
    753   for (auto &ExtAndFeat : {std::make_pair("cl_khr_fp64", "__opencl_c_fp64")})
    754     if (hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.first) !=
    755         hasFeatureEnabled(OpenCLFeaturesMap, ExtAndFeat.second)) {
    756       Diags.Report(diag::err_opencl_extension_and_feature_differs)
    757           << ExtAndFeat.first << ExtAndFeat.second;
    758       return false;
    759     }
    760 
    761   return true;
    762 }
    763