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