|  | //===--- Targets.cpp - Implement target feature support -------------------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file implements construction of a TargetInfo object from a | 
|  | // target triple. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "Targets.h" | 
|  |  | 
|  | #include "Targets/AArch64.h" | 
|  | #include "Targets/AMDGPU.h" | 
|  | #include "Targets/ARC.h" | 
|  | #include "Targets/ARM.h" | 
|  | #include "Targets/AVR.h" | 
|  | #include "Targets/BPF.h" | 
|  | #include "Targets/Hexagon.h" | 
|  | #include "Targets/Lanai.h" | 
|  | #include "Targets/Le64.h" | 
|  | #include "Targets/MSP430.h" | 
|  | #include "Targets/Mips.h" | 
|  | #include "Targets/NVPTX.h" | 
|  | #include "Targets/OSTargets.h" | 
|  | #include "Targets/PNaCl.h" | 
|  | #include "Targets/PPC.h" | 
|  | #include "Targets/RISCV.h" | 
|  | #include "Targets/SPIR.h" | 
|  | #include "Targets/Sparc.h" | 
|  | #include "Targets/SystemZ.h" | 
|  | #include "Targets/TCE.h" | 
|  | #include "Targets/VE.h" | 
|  | #include "Targets/WebAssembly.h" | 
|  | #include "Targets/X86.h" | 
|  | #include "Targets/XCore.h" | 
|  | #include "clang/Basic/Diagnostic.h" | 
|  | #include "llvm/ADT/StringExtras.h" | 
|  | #include "llvm/ADT/Triple.h" | 
|  |  | 
|  | using namespace clang; | 
|  |  | 
|  | namespace clang { | 
|  | namespace targets { | 
|  | //===----------------------------------------------------------------------===// | 
|  | //  Common code shared among targets. | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | /// DefineStd - Define a macro name and standard variants.  For example if | 
|  | /// MacroName is "unix", then this will define "__unix", "__unix__", and "unix" | 
|  | /// when in GNU mode. | 
|  | void DefineStd(MacroBuilder &Builder, StringRef MacroName, | 
|  | const LangOptions &Opts) { | 
|  | assert(MacroName[0] != '_' && "Identifier should be in the user's namespace"); | 
|  |  | 
|  | // If in GNU mode (e.g. -std=gnu99 but not -std=c99) define the raw identifier | 
|  | // in the user's namespace. | 
|  | if (Opts.GNUMode) | 
|  | Builder.defineMacro(MacroName); | 
|  |  | 
|  | // Define __unix. | 
|  | Builder.defineMacro("__" + MacroName); | 
|  |  | 
|  | // Define __unix__. | 
|  | Builder.defineMacro("__" + MacroName + "__"); | 
|  | } | 
|  |  | 
|  | void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, bool Tuning) { | 
|  | Builder.defineMacro("__" + CPUName); | 
|  | Builder.defineMacro("__" + CPUName + "__"); | 
|  | if (Tuning) | 
|  | Builder.defineMacro("__tune_" + CPUName + "__"); | 
|  | } | 
|  |  | 
|  | void addCygMingDefines(const LangOptions &Opts, MacroBuilder &Builder) { | 
|  | // Mingw and cygwin define __declspec(a) to __attribute__((a)).  Clang | 
|  | // supports __declspec natively under -fms-extensions, but we define a no-op | 
|  | // __declspec macro anyway for pre-processor compatibility. | 
|  | if (Opts.MicrosoftExt) | 
|  | Builder.defineMacro("__declspec", "__declspec"); | 
|  | else | 
|  | Builder.defineMacro("__declspec(a)", "__attribute__((a))"); | 
|  |  | 
|  | if (!Opts.MicrosoftExt) { | 
|  | // Provide macros for all the calling convention keywords.  Provide both | 
|  | // single and double underscore prefixed variants.  These are available on | 
|  | // x64 as well as x86, even though they have no effect. | 
|  | const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"}; | 
|  | for (const char *CC : CCs) { | 
|  | std::string GCCSpelling = "__attribute__((__"; | 
|  | GCCSpelling += CC; | 
|  | GCCSpelling += "__))"; | 
|  | Builder.defineMacro(Twine("_") + CC, GCCSpelling); | 
|  | Builder.defineMacro(Twine("__") + CC, GCCSpelling); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | //===----------------------------------------------------------------------===// | 
|  | // Driver code | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | TargetInfo *AllocateTarget(const llvm::Triple &Triple, | 
|  | const TargetOptions &Opts) { | 
|  | llvm::Triple::OSType os = Triple.getOS(); | 
|  |  | 
|  | switch (Triple.getArch()) { | 
|  | default: | 
|  | return nullptr; | 
|  |  | 
|  | case llvm::Triple::arc: | 
|  | return new ARCTargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::xcore: | 
|  | return new XCoreTargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::hexagon: | 
|  | if (os == llvm::Triple::Linux && | 
|  | Triple.getEnvironment() == llvm::Triple::Musl) | 
|  | return new LinuxTargetInfo<HexagonTargetInfo>(Triple, Opts); | 
|  | return new HexagonTargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::lanai: | 
|  | return new LanaiTargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::aarch64_32: | 
|  | if (Triple.isOSDarwin()) | 
|  | return new DarwinAArch64TargetInfo(Triple, Opts); | 
|  |  | 
|  | return nullptr; | 
|  | case llvm::Triple::aarch64: | 
|  | if (Triple.isOSDarwin()) | 
|  | return new DarwinAArch64TargetInfo(Triple, Opts); | 
|  |  | 
|  | switch (os) { | 
|  | case llvm::Triple::CloudABI: | 
|  | return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Fuchsia: | 
|  | return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Win32: | 
|  | switch (Triple.getEnvironment()) { | 
|  | case llvm::Triple::GNU: | 
|  | return new MinGWARM64TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::MSVC: | 
|  | default: // Assume MSVC for unknown environments | 
|  | return new MicrosoftARM64TargetInfo(Triple, Opts); | 
|  | } | 
|  | default: | 
|  | return new AArch64leTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::aarch64_be: | 
|  | switch (os) { | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Fuchsia: | 
|  | return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new AArch64beTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::arm: | 
|  | case llvm::Triple::thumb: | 
|  | if (Triple.isOSBinFormatMachO()) | 
|  | return new DarwinARMTargetInfo(Triple, Opts); | 
|  |  | 
|  | switch (os) { | 
|  | case llvm::Triple::CloudABI: | 
|  | return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NaCl: | 
|  | return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Win32: | 
|  | switch (Triple.getEnvironment()) { | 
|  | case llvm::Triple::Cygnus: | 
|  | return new CygwinARMTargetInfo(Triple, Opts); | 
|  | case llvm::Triple::GNU: | 
|  | return new MinGWARMTargetInfo(Triple, Opts); | 
|  | case llvm::Triple::Itanium: | 
|  | return new ItaniumWindowsARMleTargetInfo(Triple, Opts); | 
|  | case llvm::Triple::MSVC: | 
|  | default: // Assume MSVC for unknown environments | 
|  | return new MicrosoftARMleTargetInfo(Triple, Opts); | 
|  | } | 
|  | default: | 
|  | return new ARMleTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::armeb: | 
|  | case llvm::Triple::thumbeb: | 
|  | if (Triple.isOSDarwin()) | 
|  | return new DarwinARMTargetInfo(Triple, Opts); | 
|  |  | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NaCl: | 
|  | return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new ARMbeTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::avr: | 
|  | return new AVRTargetInfo(Triple, Opts); | 
|  | case llvm::Triple::bpfeb: | 
|  | case llvm::Triple::bpfel: | 
|  | return new BPFTargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::msp430: | 
|  | return new MSP430TargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::mips: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new MipsTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::mipsel: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NaCl: | 
|  | return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new MipsTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::mips64: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new MipsTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::mips64el: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new MipsTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::le32: | 
|  | switch (os) { | 
|  | case llvm::Triple::NaCl: | 
|  | return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | case llvm::Triple::le64: | 
|  | return new Le64TargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::ppc: | 
|  | if (Triple.isOSDarwin()) | 
|  | return new DarwinPPC32TargetInfo(Triple, Opts); | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::AIX: | 
|  | return new AIXPPC32TargetInfo(Triple, Opts); | 
|  | default: | 
|  | return new PPC32TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::ppcle: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new PPC32TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::ppc64: | 
|  | if (Triple.isOSDarwin()) | 
|  | return new DarwinPPC64TargetInfo(Triple, Opts); | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Lv2: | 
|  | return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::AIX: | 
|  | return new AIXPPC64TargetInfo(Triple, Opts); | 
|  | default: | 
|  | return new PPC64TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::ppc64le: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new PPC64TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::nvptx: | 
|  | return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32); | 
|  | case llvm::Triple::nvptx64: | 
|  | return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64); | 
|  |  | 
|  | case llvm::Triple::amdgcn: | 
|  | case llvm::Triple::r600: | 
|  | return new AMDGPUTargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::riscv32: | 
|  | // TODO: add cases for NetBSD, RTEMS once tested. | 
|  | switch (os) { | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new RISCV32TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::riscv64: | 
|  | // TODO: add cases for NetBSD, RTEMS once tested. | 
|  | switch (os) { | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Fuchsia: | 
|  | return new FuchsiaTargetInfo<RISCV64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new RISCV64TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::sparc: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Solaris: | 
|  | return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new SparcV8TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | // The 'sparcel' architecture copies all the above cases except for Solaris. | 
|  | case llvm::Triple::sparcel: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new SparcV8elTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::sparcv9: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Solaris: | 
|  | return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new SparcV9TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::systemz: | 
|  | switch (os) { | 
|  | case llvm::Triple::Linux: | 
|  | return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::ZOS: | 
|  | return new ZOSTargetInfo<SystemZTargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new SystemZTargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::tce: | 
|  | return new TCETargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::tcele: | 
|  | return new TCELETargetInfo(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::x86: | 
|  | if (Triple.isOSDarwin()) | 
|  | return new DarwinI386TargetInfo(Triple, Opts); | 
|  |  | 
|  | switch (os) { | 
|  | case llvm::Triple::Ananas: | 
|  | return new AnanasTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::CloudABI: | 
|  | return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: { | 
|  | switch (Triple.getEnvironment()) { | 
|  | default: | 
|  | return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Android: | 
|  | return new AndroidX86_32TargetInfo(Triple, Opts); | 
|  | } | 
|  | } | 
|  | case llvm::Triple::DragonFly: | 
|  | return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDI386TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDI386TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Fuchsia: | 
|  | return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::KFreeBSD: | 
|  | return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Minix: | 
|  | return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Solaris: | 
|  | return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Win32: { | 
|  | switch (Triple.getEnvironment()) { | 
|  | case llvm::Triple::Cygnus: | 
|  | return new CygwinX86_32TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::GNU: | 
|  | return new MinGWX86_32TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::Itanium: | 
|  | case llvm::Triple::MSVC: | 
|  | default: // Assume MSVC for unknown environments | 
|  | return new MicrosoftX86_32TargetInfo(Triple, Opts); | 
|  | } | 
|  | } | 
|  | case llvm::Triple::Haiku: | 
|  | return new HaikuX86_32TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::RTEMS: | 
|  | return new RTEMSX86_32TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::NaCl: | 
|  | return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::ELFIAMCU: | 
|  | return new MCUX86_32TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::Hurd: | 
|  | return new HurdTargetInfo<X86_32TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new X86_32TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::x86_64: | 
|  | if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) | 
|  | return new DarwinX86_64TargetInfo(Triple, Opts); | 
|  |  | 
|  | switch (os) { | 
|  | case llvm::Triple::Ananas: | 
|  | return new AnanasTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::CloudABI: | 
|  | return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Linux: { | 
|  | switch (Triple.getEnvironment()) { | 
|  | default: | 
|  | return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Android: | 
|  | return new AndroidX86_64TargetInfo(Triple, Opts); | 
|  | } | 
|  | } | 
|  | case llvm::Triple::DragonFly: | 
|  | return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NetBSD: | 
|  | return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::OpenBSD: | 
|  | return new OpenBSDX86_64TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::FreeBSD: | 
|  | return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Fuchsia: | 
|  | return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::KFreeBSD: | 
|  | return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Solaris: | 
|  | return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Win32: { | 
|  | switch (Triple.getEnvironment()) { | 
|  | case llvm::Triple::Cygnus: | 
|  | return new CygwinX86_64TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::GNU: | 
|  | return new MinGWX86_64TargetInfo(Triple, Opts); | 
|  | case llvm::Triple::MSVC: | 
|  | default: // Assume MSVC for unknown environments | 
|  | return new MicrosoftX86_64TargetInfo(Triple, Opts); | 
|  | } | 
|  | } | 
|  | case llvm::Triple::Haiku: | 
|  | return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::NaCl: | 
|  | return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::PS4: | 
|  | return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return new X86_64TargetInfo(Triple, Opts); | 
|  | } | 
|  |  | 
|  | case llvm::Triple::spir: { | 
|  | if (Triple.getOS() != llvm::Triple::UnknownOS || | 
|  | Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) | 
|  | return nullptr; | 
|  | return new SPIR32TargetInfo(Triple, Opts); | 
|  | } | 
|  | case llvm::Triple::spir64: { | 
|  | if (Triple.getOS() != llvm::Triple::UnknownOS || | 
|  | Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) | 
|  | return nullptr; | 
|  | return new SPIR64TargetInfo(Triple, Opts); | 
|  | } | 
|  | case llvm::Triple::wasm32: | 
|  | if (Triple.getSubArch() != llvm::Triple::NoSubArch || | 
|  | Triple.getVendor() != llvm::Triple::UnknownVendor || | 
|  | !Triple.isOSBinFormatWasm()) | 
|  | return nullptr; | 
|  | switch (Triple.getOS()) { | 
|  | case llvm::Triple::WASI: | 
|  | return new WASITargetInfo<WebAssembly32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Emscripten: | 
|  | return new EmscriptenTargetInfo<WebAssembly32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::UnknownOS: | 
|  | return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return nullptr; | 
|  | } | 
|  | case llvm::Triple::wasm64: | 
|  | if (Triple.getSubArch() != llvm::Triple::NoSubArch || | 
|  | Triple.getVendor() != llvm::Triple::UnknownVendor || | 
|  | !Triple.isOSBinFormatWasm()) | 
|  | return nullptr; | 
|  | switch (Triple.getOS()) { | 
|  | case llvm::Triple::WASI: | 
|  | return new WASITargetInfo<WebAssembly64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::Emscripten: | 
|  | return new EmscriptenTargetInfo<WebAssembly64TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::UnknownOS: | 
|  | return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts); | 
|  | default: | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | case llvm::Triple::renderscript32: | 
|  | return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts); | 
|  | case llvm::Triple::renderscript64: | 
|  | return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts); | 
|  |  | 
|  | case llvm::Triple::ve: | 
|  | return new LinuxTargetInfo<VETargetInfo>(Triple, Opts); | 
|  | } | 
|  | } | 
|  | } // namespace targets | 
|  | } // namespace clang | 
|  |  | 
|  | using namespace clang::targets; | 
|  | /// CreateTargetInfo - Return the target info object for the specified target | 
|  | /// options. | 
|  | TargetInfo * | 
|  | TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, | 
|  | const std::shared_ptr<TargetOptions> &Opts) { | 
|  | llvm::Triple Triple(Opts->Triple); | 
|  |  | 
|  | // Construct the target | 
|  | std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts)); | 
|  | if (!Target) { | 
|  | Diags.Report(diag::err_target_unknown_triple) << Triple.str(); | 
|  | return nullptr; | 
|  | } | 
|  | Target->TargetOpts = Opts; | 
|  |  | 
|  | // Set the target CPU if specified. | 
|  | if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) { | 
|  | Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU; | 
|  | SmallVector<StringRef, 32> ValidList; | 
|  | Target->fillValidCPUList(ValidList); | 
|  | if (!ValidList.empty()) | 
|  | Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", "); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | // Check the TuneCPU name if specified. | 
|  | if (!Opts->TuneCPU.empty() && | 
|  | !Target->isValidTuneCPUName(Opts->TuneCPU)) { | 
|  | Diags.Report(diag::err_target_unknown_cpu) << Opts->TuneCPU; | 
|  | SmallVector<StringRef, 32> ValidList; | 
|  | Target->fillValidTuneCPUList(ValidList); | 
|  | if (!ValidList.empty()) | 
|  | Diags.Report(diag::note_valid_options) << llvm::join(ValidList, ", "); | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | // Set the target ABI if specified. | 
|  | if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) { | 
|  | Diags.Report(diag::err_target_unknown_abi) << Opts->ABI; | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | // Set the fp math unit. | 
|  | if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) { | 
|  | Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath; | 
|  | return nullptr; | 
|  | } | 
|  |  | 
|  | // Compute the default target features, we need the target to handle this | 
|  | // because features may have dependencies on one another. | 
|  | if (!Target->initFeatureMap(Opts->FeatureMap, Diags, Opts->CPU, | 
|  | Opts->FeaturesAsWritten)) | 
|  | return nullptr; | 
|  |  | 
|  | // Add the features to the compile options. | 
|  | Opts->Features.clear(); | 
|  | for (const auto &F : Opts->FeatureMap) | 
|  | Opts->Features.push_back((F.getValue() ? "+" : "-") + F.getKey().str()); | 
|  | // Sort here, so we handle the features in a predictable order. (This matters | 
|  | // when we're dealing with features that overlap.) | 
|  | llvm::sort(Opts->Features); | 
|  |  | 
|  | if (!Target->handleTargetFeatures(Opts->Features, Diags)) | 
|  | return nullptr; | 
|  |  | 
|  | Target->setSupportedOpenCLOpts(); | 
|  | Target->setCommandLineOpenCLOpts(); | 
|  | Target->setMaxAtomicWidth(); | 
|  |  | 
|  | if (!Target->validateTarget(Diags)) | 
|  | return nullptr; | 
|  |  | 
|  | Target->CheckFixedPointBits(); | 
|  |  | 
|  | return Target.release(); | 
|  | } | 
|  |  | 
|  | /// getOpenCLFeatureDefines - Define OpenCL macros based on target settings | 
|  | /// and language version | 
|  | void TargetInfo::getOpenCLFeatureDefines(const LangOptions &Opts, | 
|  | MacroBuilder &Builder) const { | 
|  |  | 
|  | auto defineOpenCLExtMacro = [&](llvm::StringRef Name, unsigned AvailVer, | 
|  | unsigned CoreVersions, | 
|  | unsigned OptionalVersions) { | 
|  | // Check if extension is supported by target and is available in this | 
|  | // OpenCL version | 
|  | auto It = getTargetOpts().OpenCLFeaturesMap.find(Name); | 
|  | if ((It != getTargetOpts().OpenCLFeaturesMap.end()) && It->getValue() && | 
|  | OpenCLOptions::OpenCLOptionInfo(AvailVer, CoreVersions, | 
|  | OptionalVersions) | 
|  | .isAvailableIn(Opts)) | 
|  | Builder.defineMacro(Name); | 
|  | }; | 
|  | #define OPENCL_GENERIC_EXTENSION(Ext, Avail, Core, Opt)                        \ | 
|  | defineOpenCLExtMacro(#Ext, Avail, Core, Opt); | 
|  | #include "clang/Basic/OpenCLExtensions.def" | 
|  |  | 
|  | // FIXME: OpenCL options which affect language semantics/syntax | 
|  | // should be moved into LangOptions, thus macro definitions of | 
|  | // such options is better to be done in clang::InitializePreprocessor | 
|  | } |