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