Clang Project

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