1 //===--- HostInfo.cpp - Host specific information -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/Driver/HostInfo.h"
12 #include "clang/Driver/Arg.h"
13 #include "clang/Driver/ArgList.h"
14 #include "clang/Driver/Driver.h"
15 #include "clang/Driver/DriverDiagnostic.h"
16 #include "clang/Driver/Option.h"
17 #include "clang/Driver/Options.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/Support/Compiler.h"
22 #include "ToolChains.h"
26 using namespace clang::driver;
28 HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple)
29 : TheDriver(D), Triple(_Triple) {
32 HostInfo::~HostInfo() {
39 /// DarwinHostInfo - Darwin host information implementation.
40 class DarwinHostInfo : public HostInfo {
41 /// Cache of tool chains we have created.
42 mutable llvm::DenseMap<unsigned, ToolChain*> ToolChains;
45 DarwinHostInfo(const Driver &D, const llvm::Triple &Triple);
48 virtual bool useDriverDriver() const;
50 virtual ToolChain *CreateToolChain(const ArgList &Args,
51 const char *ArchName) const;
54 DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple)
55 : HostInfo(D, Triple) {
58 DarwinHostInfo::~DarwinHostInfo() {
59 for (llvm::DenseMap<unsigned, ToolChain*>::iterator
60 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
64 bool DarwinHostInfo::useDriverDriver() const {
68 ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
69 const char *ArchName) const {
70 llvm::Triple::ArchType Arch;
73 // If we aren't looking for a specific arch, infer the default architecture
74 // based on -arch and -m32/-m64 command line options.
75 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
76 // The gcc driver behavior with multiple -arch flags wasn't consistent for
77 // things which rely on a default architecture. We just use the last -arch
78 // to find the default tool chain (assuming it is valid).
79 Arch = llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args));
81 // If it was invalid just use the host, we will reject this command line
83 if (Arch == llvm::Triple::UnknownArch)
84 Arch = getTriple().getArch();
86 // Otherwise default to the arch of the host.
87 Arch = getTriple().getArch();
90 // Honor -m32 and -m64 when finding the default tool chain.
92 // FIXME: Should this information be in llvm::Triple?
93 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
94 if (A->getOption().matches(options::OPT_m32)) {
95 if (Arch == llvm::Triple::x86_64)
96 Arch = llvm::Triple::x86;
97 if (Arch == llvm::Triple::ppc64)
98 Arch = llvm::Triple::ppc;
100 if (Arch == llvm::Triple::x86)
101 Arch = llvm::Triple::x86_64;
102 if (Arch == llvm::Triple::ppc)
103 Arch = llvm::Triple::ppc64;
107 Arch = llvm::Triple::getArchTypeForDarwinArchName(ArchName);
109 assert(Arch != llvm::Triple::UnknownArch && "Unexpected arch!");
110 ToolChain *&TC = ToolChains[Arch];
112 llvm::Triple TCTriple(getTriple());
113 TCTriple.setArch(Arch);
115 // If we recognized the arch, match it to the toolchains we support.
116 if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64 ||
117 Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) {
118 TC = new toolchains::DarwinClang(*this, TCTriple);
120 TC = new toolchains::Darwin_Generic_GCC(*this, TCTriple);
128 /// TCEHostInfo - TCE host information implementation (see http://tce.cs.tut.fi)
129 class TCEHostInfo : public HostInfo {
132 TCEHostInfo(const Driver &D, const llvm::Triple &Triple);
135 virtual bool useDriverDriver() const;
137 virtual ToolChain *CreateToolChain(const ArgList &Args,
138 const char *ArchName) const;
141 TCEHostInfo::TCEHostInfo(const Driver &D, const llvm::Triple& Triple)
142 : HostInfo(D, Triple) {
145 bool TCEHostInfo::useDriverDriver() const {
149 ToolChain *TCEHostInfo::CreateToolChain(const ArgList &Args,
150 const char *ArchName) const {
151 llvm::Triple TCTriple(getTriple());
152 // TCTriple.setArchName(ArchName);
153 return new toolchains::TCEToolChain(*this, TCTriple);
159 /// UnknownHostInfo - Generic host information to use for unknown hosts.
160 class UnknownHostInfo : public HostInfo {
161 /// Cache of tool chains we have created.
162 mutable llvm::StringMap<ToolChain*> ToolChains;
165 UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
168 virtual bool useDriverDriver() const;
170 virtual ToolChain *CreateToolChain(const ArgList &Args,
171 const char *ArchName) const;
174 UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple)
175 : HostInfo(D, Triple) {
178 UnknownHostInfo::~UnknownHostInfo() {
179 for (llvm::StringMap<ToolChain*>::iterator
180 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
184 bool UnknownHostInfo::useDriverDriver() const {
188 ToolChain *UnknownHostInfo::CreateToolChain(const ArgList &Args,
189 const char *ArchName) const {
191 "Unexpected arch name on platform without driver driver support.");
193 // Automatically handle some instances of -m32/-m64 we know about.
194 std::string Arch = getArchName();
195 ArchName = Arch.c_str();
196 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
197 if (Triple.getArch() == llvm::Triple::x86 ||
198 Triple.getArch() == llvm::Triple::x86_64) {
200 (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
201 } else if (Triple.getArch() == llvm::Triple::ppc ||
202 Triple.getArch() == llvm::Triple::ppc64) {
204 (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
208 ToolChain *&TC = ToolChains[ArchName];
210 llvm::Triple TCTriple(getTriple());
211 TCTriple.setArchName(ArchName);
213 TC = new toolchains::Generic_GCC(*this, TCTriple);
221 /// OpenBSDHostInfo - OpenBSD host information implementation.
222 class OpenBSDHostInfo : public HostInfo {
223 /// Cache of tool chains we have created.
224 mutable llvm::StringMap<ToolChain*> ToolChains;
227 OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
228 : HostInfo(D, Triple) {}
231 virtual bool useDriverDriver() const;
233 virtual ToolChain *CreateToolChain(const ArgList &Args,
234 const char *ArchName) const;
237 OpenBSDHostInfo::~OpenBSDHostInfo() {
238 for (llvm::StringMap<ToolChain*>::iterator
239 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
243 bool OpenBSDHostInfo::useDriverDriver() const {
247 ToolChain *OpenBSDHostInfo::CreateToolChain(const ArgList &Args,
248 const char *ArchName) const {
250 "Unexpected arch name on platform without driver driver support.");
252 std::string Arch = getArchName();
253 ArchName = Arch.c_str();
255 ToolChain *&TC = ToolChains[ArchName];
257 llvm::Triple TCTriple(getTriple());
258 TCTriple.setArchName(ArchName);
260 TC = new toolchains::OpenBSD(*this, TCTriple);
266 // AuroraUX Host Info
268 /// AuroraUXHostInfo - AuroraUX host information implementation.
269 class AuroraUXHostInfo : public HostInfo {
270 /// Cache of tool chains we have created.
271 mutable llvm::StringMap<ToolChain*> ToolChains;
274 AuroraUXHostInfo(const Driver &D, const llvm::Triple& Triple)
275 : HostInfo(D, Triple) {}
278 virtual bool useDriverDriver() const;
280 virtual ToolChain *CreateToolChain(const ArgList &Args,
281 const char *ArchName) const;
284 AuroraUXHostInfo::~AuroraUXHostInfo() {
285 for (llvm::StringMap<ToolChain*>::iterator
286 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
290 bool AuroraUXHostInfo::useDriverDriver() const {
294 ToolChain *AuroraUXHostInfo::CreateToolChain(const ArgList &Args,
295 const char *ArchName) const {
297 "Unexpected arch name on platform without driver driver support.");
299 ToolChain *&TC = ToolChains[getArchName()];
302 llvm::Triple TCTriple(getTriple());
303 TCTriple.setArchName(getArchName());
305 TC = new toolchains::AuroraUX(*this, TCTriple);
313 /// FreeBSDHostInfo - FreeBSD host information implementation.
314 class FreeBSDHostInfo : public HostInfo {
315 /// Cache of tool chains we have created.
316 mutable llvm::StringMap<ToolChain*> ToolChains;
319 FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
320 : HostInfo(D, Triple) {}
323 virtual bool useDriverDriver() const;
325 virtual ToolChain *CreateToolChain(const ArgList &Args,
326 const char *ArchName) const;
329 FreeBSDHostInfo::~FreeBSDHostInfo() {
330 for (llvm::StringMap<ToolChain*>::iterator
331 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
335 bool FreeBSDHostInfo::useDriverDriver() const {
339 ToolChain *FreeBSDHostInfo::CreateToolChain(const ArgList &Args,
340 const char *ArchName) const {
342 "Unexpected arch name on platform without driver driver support.");
344 // Automatically handle some instances of -m32/-m64 we know about.
345 std::string Arch = getArchName();
346 ArchName = Arch.c_str();
347 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
348 if (Triple.getArch() == llvm::Triple::x86 ||
349 Triple.getArch() == llvm::Triple::x86_64) {
351 (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
352 } else if (Triple.getArch() == llvm::Triple::ppc ||
353 Triple.getArch() == llvm::Triple::ppc64) {
355 (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
359 ToolChain *&TC = ToolChains[ArchName];
361 llvm::Triple TCTriple(getTriple());
362 TCTriple.setArchName(ArchName);
364 TC = new toolchains::FreeBSD(*this, TCTriple);
372 /// NetBSDHostInfo - NetBSD host information implementation.
373 class NetBSDHostInfo : public HostInfo {
374 /// Cache of tool chains we have created.
375 mutable llvm::StringMap<ToolChain*> ToolChains;
378 NetBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
379 : HostInfo(D, Triple) {}
382 virtual bool useDriverDriver() const;
384 virtual ToolChain *CreateToolChain(const ArgList &Args,
385 const char *ArchName) const;
388 NetBSDHostInfo::~NetBSDHostInfo() {
389 for (llvm::StringMap<ToolChain*>::iterator
390 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
394 bool NetBSDHostInfo::useDriverDriver() const {
398 ToolChain *NetBSDHostInfo::CreateToolChain(const ArgList &Args,
399 const char *ArchName) const {
401 "Unexpected arch name on platform without driver driver support.");
403 // Automatically handle some instances of -m32/-m64 we know about.
404 std::string Arch = getArchName();
405 ArchName = Arch.c_str();
406 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
407 if (Triple.getArch() == llvm::Triple::x86 ||
408 Triple.getArch() == llvm::Triple::x86_64) {
410 (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
411 } else if (Triple.getArch() == llvm::Triple::ppc ||
412 Triple.getArch() == llvm::Triple::ppc64) {
414 (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
417 llvm::Triple TargetTriple(getTriple());
418 TargetTriple.setArchName(ArchName);
422 // XXX Cache toolchain even if -m32 is used
423 if (Arch == ArchName) {
424 TC = ToolChains[ArchName];
429 TC = new toolchains::NetBSD(*this, TargetTriple, getTriple());
436 /// MinixHostInfo - Minix host information implementation.
437 class MinixHostInfo : public HostInfo {
438 /// Cache of tool chains we have created.
439 mutable llvm::StringMap<ToolChain*> ToolChains;
442 MinixHostInfo(const Driver &D, const llvm::Triple& Triple)
443 : HostInfo(D, Triple) {}
446 virtual bool useDriverDriver() const;
448 virtual ToolChain *CreateToolChain(const ArgList &Args,
449 const char *ArchName) const;
452 MinixHostInfo::~MinixHostInfo() {
453 for (llvm::StringMap<ToolChain*>::iterator
454 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it){
459 bool MinixHostInfo::useDriverDriver() const {
463 ToolChain *MinixHostInfo::CreateToolChain(const ArgList &Args,
464 const char *ArchName) const {
466 "Unexpected arch name on platform without driver driver support.");
468 std::string Arch = getArchName();
469 ArchName = Arch.c_str();
471 ToolChain *&TC = ToolChains[ArchName];
473 llvm::Triple TCTriple(getTriple());
474 TCTriple.setArchName(ArchName);
476 TC = new toolchains::Minix(*this, TCTriple);
482 // DragonFly Host Info
484 /// DragonFlyHostInfo - DragonFly host information implementation.
485 class DragonFlyHostInfo : public HostInfo {
486 /// Cache of tool chains we have created.
487 mutable llvm::StringMap<ToolChain*> ToolChains;
490 DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
491 : HostInfo(D, Triple) {}
492 ~DragonFlyHostInfo();
494 virtual bool useDriverDriver() const;
496 virtual ToolChain *CreateToolChain(const ArgList &Args,
497 const char *ArchName) const;
500 DragonFlyHostInfo::~DragonFlyHostInfo() {
501 for (llvm::StringMap<ToolChain*>::iterator
502 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
506 bool DragonFlyHostInfo::useDriverDriver() const {
510 ToolChain *DragonFlyHostInfo::CreateToolChain(const ArgList &Args,
511 const char *ArchName) const {
513 "Unexpected arch name on platform without driver driver support.");
515 ToolChain *&TC = ToolChains[getArchName()];
518 llvm::Triple TCTriple(getTriple());
519 TCTriple.setArchName(getArchName());
521 TC = new toolchains::DragonFly(*this, TCTriple);
529 /// LinuxHostInfo - Linux host information implementation.
530 class LinuxHostInfo : public HostInfo {
531 /// Cache of tool chains we have created.
532 mutable llvm::StringMap<ToolChain*> ToolChains;
535 LinuxHostInfo(const Driver &D, const llvm::Triple& Triple)
536 : HostInfo(D, Triple) {}
539 virtual bool useDriverDriver() const;
541 virtual ToolChain *CreateToolChain(const ArgList &Args,
542 const char *ArchName) const;
545 LinuxHostInfo::~LinuxHostInfo() {
546 for (llvm::StringMap<ToolChain*>::iterator
547 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
551 bool LinuxHostInfo::useDriverDriver() const {
555 ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args,
556 const char *ArchName) const {
559 "Unexpected arch name on platform without driver driver support.");
561 // Automatically handle some instances of -m32/-m64 we know about.
562 std::string Arch = getArchName();
563 ArchName = Arch.c_str();
564 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
565 if (Triple.getArch() == llvm::Triple::x86 ||
566 Triple.getArch() == llvm::Triple::x86_64) {
568 (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
569 } else if (Triple.getArch() == llvm::Triple::ppc ||
570 Triple.getArch() == llvm::Triple::ppc64) {
572 (A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
576 ToolChain *&TC = ToolChains[ArchName];
579 llvm::Triple TCTriple(getTriple());
580 TCTriple.setArchName(ArchName);
582 TC = new toolchains::Linux(*this, TCTriple);
590 /// WindowsHostInfo - Host information to use on Microsoft Windows.
591 class WindowsHostInfo : public HostInfo {
592 /// Cache of tool chains we have created.
593 mutable llvm::StringMap<ToolChain*> ToolChains;
596 WindowsHostInfo(const Driver &D, const llvm::Triple& Triple);
599 virtual bool useDriverDriver() const;
601 virtual types::ID lookupTypeForExtension(const char *Ext) const {
602 return types::lookupTypeForExtension(Ext);
605 virtual ToolChain *CreateToolChain(const ArgList &Args,
606 const char *ArchName) const;
609 WindowsHostInfo::WindowsHostInfo(const Driver &D, const llvm::Triple& Triple)
610 : HostInfo(D, Triple) {
613 WindowsHostInfo::~WindowsHostInfo() {
614 for (llvm::StringMap<ToolChain*>::iterator
615 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
619 bool WindowsHostInfo::useDriverDriver() const {
623 ToolChain *WindowsHostInfo::CreateToolChain(const ArgList &Args,
624 const char *ArchName) const {
626 "Unexpected arch name on platform without driver driver support.");
628 // Automatically handle some instances of -m32/-m64 we know about.
629 std::string Arch = getArchName();
630 ArchName = Arch.c_str();
631 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
632 if (Triple.getArch() == llvm::Triple::x86 ||
633 Triple.getArch() == llvm::Triple::x86_64) {
635 (A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
639 ToolChain *&TC = ToolChains[ArchName];
641 llvm::Triple TCTriple(getTriple());
642 TCTriple.setArchName(ArchName);
644 TC = new toolchains::Windows(*this, TCTriple);
650 // FIXME: This is a placeholder.
651 class MinGWHostInfo : public UnknownHostInfo {
653 MinGWHostInfo(const Driver &D, const llvm::Triple& Triple);
656 MinGWHostInfo::MinGWHostInfo(const Driver &D, const llvm::Triple& Triple)
657 : UnknownHostInfo(D, Triple) {}
659 } // end anon namespace
662 clang::driver::createAuroraUXHostInfo(const Driver &D,
663 const llvm::Triple& Triple){
664 return new AuroraUXHostInfo(D, Triple);
668 clang::driver::createDarwinHostInfo(const Driver &D,
669 const llvm::Triple& Triple){
670 return new DarwinHostInfo(D, Triple);
674 clang::driver::createOpenBSDHostInfo(const Driver &D,
675 const llvm::Triple& Triple) {
676 return new OpenBSDHostInfo(D, Triple);
680 clang::driver::createFreeBSDHostInfo(const Driver &D,
681 const llvm::Triple& Triple) {
682 return new FreeBSDHostInfo(D, Triple);
686 clang::driver::createNetBSDHostInfo(const Driver &D,
687 const llvm::Triple& Triple) {
688 return new NetBSDHostInfo(D, Triple);
692 clang::driver::createMinixHostInfo(const Driver &D,
693 const llvm::Triple& Triple) {
694 return new MinixHostInfo(D, Triple);
698 clang::driver::createDragonFlyHostInfo(const Driver &D,
699 const llvm::Triple& Triple) {
700 return new DragonFlyHostInfo(D, Triple);
704 clang::driver::createLinuxHostInfo(const Driver &D,
705 const llvm::Triple& Triple) {
706 return new LinuxHostInfo(D, Triple);
710 clang::driver::createTCEHostInfo(const Driver &D,
711 const llvm::Triple& Triple) {
712 return new TCEHostInfo(D, Triple);
716 clang::driver::createWindowsHostInfo(const Driver &D,
717 const llvm::Triple& Triple) {
718 return new WindowsHostInfo(D, Triple);
722 clang::driver::createMinGWHostInfo(const Driver &D,
723 const llvm::Triple& Triple) {
724 return new MinGWHostInfo(D, Triple);
728 clang::driver::createUnknownHostInfo(const Driver &D,
729 const llvm::Triple& Triple) {
730 return new UnknownHostInfo(D, Triple);