blob: 2d577f82fd40b46198b75a27766a7ee8001231be [file] [log] [blame]
Daniel Dunbare3995642009-03-10 23:50:49 +00001//===--- HostInfo.cpp - Host specific information -----------------------*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Driver/HostInfo.h"
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000011
12#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000014#include "clang/Driver/Driver.h"
15#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000016#include "clang/Driver/Option.h"
17#include "clang/Driver/Options.h"
18
19#include "llvm/ADT/StringMap.h"
20#include "llvm/Support/Compiler.h"
21
Daniel Dunbar83b08eb2009-03-17 21:38:00 +000022#include "ToolChains.h"
23
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000024#include <cassert>
Daniel Dunbare3995642009-03-10 23:50:49 +000025
26using namespace clang::driver;
27
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000028HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple)
29 : TheDriver(D), Triple(_Triple)
Daniel Dunbare3995642009-03-10 23:50:49 +000030{
31
32}
33
34HostInfo::~HostInfo() {
35}
36
Chris Lattneraae82f12009-03-17 22:24:01 +000037namespace {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000038
Daniel Dunbare3995642009-03-10 23:50:49 +000039// Darwin Host Info
40
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000041/// DarwinHostInfo - Darwin host information implementation.
42class DarwinHostInfo : public HostInfo {
43 /// Darwin version of host.
44 unsigned DarwinVersion[3];
45
46 /// GCC version to use on this host.
47 unsigned GCCVersion[3];
48
49 /// Cache of tool chains we have created.
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000050 mutable llvm::StringMap<ToolChain *> ToolChains;
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000051
52public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000053 DarwinHostInfo(const Driver &D, const llvm::Triple &Triple);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000054 ~DarwinHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000055
56 virtual bool useDriverDriver() const;
57
Daniel Dunbare33bea42009-03-20 23:39:23 +000058 virtual types::ID lookupTypeForExtension(const char *Ext) const {
59 types::ID Ty = types::lookupTypeForExtension(Ext);
60
61 // Darwin always preprocesses assembly files (unless -x is used
62 // explicitly).
63 if (Ty == types::TY_PP_Asm)
64 return types::TY_Asm;
65
66 return Ty;
67 }
68
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000069 virtual ToolChain *getToolChain(const ArgList &Args,
70 const char *ArchName) const;
71};
72
Daniel Dunbarcb8ab232009-05-22 02:53:45 +000073DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple)
74 : HostInfo(D, Triple) {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000075
76 assert((getArchName() == "i386" || getArchName() == "x86_64" ||
Eli Friedman8ea97542009-05-28 20:57:06 +000077 getArchName() == "powerpc" || getArchName() == "powerpc64" ||
78 getArchName() == "arm") &&
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000079 "Unknown Darwin arch.");
Daniel Dunbare3995642009-03-10 23:50:49 +000080
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000081 assert(memcmp(&getOSName()[0], "darwin", 6) == 0 &&
82 "Unknown Darwin platform.");
Daniel Dunbard73fe9b2009-03-26 15:58:36 +000083 bool HadExtra;
Daniel Dunbar10708c42009-05-23 18:55:58 +000084 if (!Driver::GetReleaseVersion(&getOSName()[6],
85 DarwinVersion[0], DarwinVersion[1],
Daniel Dunbard73fe9b2009-03-26 15:58:36 +000086 DarwinVersion[2], HadExtra)) {
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000087 D.Diag(clang::diag::err_drv_invalid_darwin_version)
Daniel Dunbar10708c42009-05-23 18:55:58 +000088 << getOSName();
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000089 }
Daniel Dunbare3995642009-03-10 23:50:49 +000090
91 // We can only call 4.2.1 for now.
92 GCCVersion[0] = 4;
93 GCCVersion[1] = 2;
94 GCCVersion[2] = 1;
95}
96
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000097DarwinHostInfo::~DarwinHostInfo() {
98 for (llvm::StringMap<ToolChain*>::iterator
99 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
100 delete it->second;
101}
102
Daniel Dunbare3995642009-03-10 23:50:49 +0000103bool DarwinHostInfo::useDriverDriver() const {
104 return true;
105}
106
107ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args,
108 const char *ArchName) const {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000109 std::string Arch;
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000110 if (!ArchName) {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000111 Arch = getArchName();
112 ArchName = Arch.c_str();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000113
114 // If no arch name is specified, infer it from the host and
115 // -m32/-m64.
116 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
117 if (getArchName() == "i386" || getArchName() == "x86_64") {
118 ArchName =
119 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000120 } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") {
121 ArchName = (A->getOption().getId() == options::OPT_m32) ? "powerpc" :
122 "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000123 }
124 }
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000125 } else {
126 // Normalize arch name; we shouldn't be doing this here.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000127 //
128 // FIXME: This should be unnecessary once everything moves over to using the
129 // ID based Triple interface.
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000130 if (strcmp(ArchName, "ppc") == 0)
131 ArchName = "powerpc";
132 else if (strcmp(ArchName, "ppc64") == 0)
133 ArchName = "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000134 }
135
136 ToolChain *&TC = ToolChains[ArchName];
137 if (!TC) {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000138 llvm::Triple TCTriple(getTriple());
139 TCTriple.setArchName(ArchName);
140
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000141 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000142 TC = new toolchains::Darwin_X86(*this, TCTriple,
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000143 DarwinVersion,
144 GCCVersion);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000145 else
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000146 TC = new toolchains::Darwin_GCC(*this, TCTriple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000147 }
148
149 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000150}
151
152// Unknown Host Info
153
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000154/// UnknownHostInfo - Generic host information to use for unknown
155/// hosts.
156class UnknownHostInfo : public HostInfo {
157 /// Cache of tool chains we have created.
158 mutable llvm::StringMap<ToolChain*> ToolChains;
159
160public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000161 UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000162 ~UnknownHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000163
164 virtual bool useDriverDriver() const;
165
Daniel Dunbare33bea42009-03-20 23:39:23 +0000166 virtual types::ID lookupTypeForExtension(const char *Ext) const {
167 return types::lookupTypeForExtension(Ext);
168 }
169
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000170 virtual ToolChain *getToolChain(const ArgList &Args,
171 const char *ArchName) const;
172};
173
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000174UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple)
175 : HostInfo(D, Triple) {
Daniel Dunbare3995642009-03-10 23:50:49 +0000176}
177
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000178UnknownHostInfo::~UnknownHostInfo() {
179 for (llvm::StringMap<ToolChain*>::iterator
180 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
181 delete it->second;
182}
183
Daniel Dunbare3995642009-03-10 23:50:49 +0000184bool UnknownHostInfo::useDriverDriver() const {
185 return false;
186}
187
188ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
189 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000190 assert(!ArchName &&
191 "Unexpected arch name on platform without driver driver support.");
192
193 // Automatically handle some instances of -m32/-m64 we know about.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000194 std::string Arch = getArchName();
195 ArchName = Arch.c_str();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000196 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
Eli Friedman4e2567d2009-06-03 18:59:56 +0000197 if (Triple.getArch() == llvm::Triple::x86 ||
198 Triple.getArch() == llvm::Triple::x86_64) {
199 ArchName =
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000200 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
Eli Friedman4e2567d2009-06-03 18:59:56 +0000201 } else if (Triple.getArch() == llvm::Triple::ppc ||
202 Triple.getArch() == llvm::Triple::ppc64) {
203 ArchName =
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000204 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000205 }
206 }
207
208 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000209 if (!TC) {
210 llvm::Triple TCTriple(getTriple());
211 TCTriple.setArchName(ArchName);
212
213 TC = new toolchains::Generic_GCC(*this, TCTriple);
214 }
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000215
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000216 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000217}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000218
Daniel Dunbar75358d22009-03-30 21:06:03 +0000219// FreeBSD Host Info
220
Daniel Dunbarb85f59d2009-03-30 22:11:38 +0000221/// FreeBSDHostInfo - FreeBSD host information implementation.
Daniel Dunbar75358d22009-03-30 21:06:03 +0000222class FreeBSDHostInfo : public HostInfo {
223 /// Cache of tool chains we have created.
224 mutable llvm::StringMap<ToolChain*> ToolChains;
225
226public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000227 FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
228 : HostInfo(D, Triple) {}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000229 ~FreeBSDHostInfo();
230
231 virtual bool useDriverDriver() const;
232
233 virtual types::ID lookupTypeForExtension(const char *Ext) const {
234 return types::lookupTypeForExtension(Ext);
235 }
236
237 virtual ToolChain *getToolChain(const ArgList &Args,
238 const char *ArchName) const;
239};
240
Daniel Dunbar75358d22009-03-30 21:06:03 +0000241FreeBSDHostInfo::~FreeBSDHostInfo() {
242 for (llvm::StringMap<ToolChain*>::iterator
243 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
244 delete it->second;
245}
246
247bool FreeBSDHostInfo::useDriverDriver() const {
248 return false;
249}
250
251ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
252 const char *ArchName) const {
253 bool Lib32 = false;
254
255 assert(!ArchName &&
256 "Unexpected arch name on platform without driver driver support.");
257
258 // On x86_64 we need to be able to compile 32-bits binaries as well.
259 // Compiling 64-bit binaries on i386 is not supported. We don't have a
260 // lib64.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000261 std::string Arch = getArchName();
262 ArchName = Arch.c_str();
Daniel Dunbar75358d22009-03-30 21:06:03 +0000263 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
264 ArchName = "i386";
265 Lib32 = true;
266 }
267
268 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000269 if (!TC) {
270 llvm::Triple TCTriple(getTriple());
271 TCTriple.setArchName(ArchName);
272
273 TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
274 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000275
276 return TC;
277}
278
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000279// DragonFly Host Info
280
281/// DragonFlyHostInfo - DragonFly host information implementation.
282class DragonFlyHostInfo : public HostInfo {
283 /// Cache of tool chains we have created.
284 mutable llvm::StringMap<ToolChain*> ToolChains;
285
286public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000287 DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
288 : HostInfo(D, Triple) {}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000289 ~DragonFlyHostInfo();
290
291 virtual bool useDriverDriver() const;
292
293 virtual types::ID lookupTypeForExtension(const char *Ext) const {
294 return types::lookupTypeForExtension(Ext);
295 }
296
297 virtual ToolChain *getToolChain(const ArgList &Args,
298 const char *ArchName) const;
299};
300
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000301DragonFlyHostInfo::~DragonFlyHostInfo() {
302 for (llvm::StringMap<ToolChain*>::iterator
303 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
304 delete it->second;
305}
306
307bool DragonFlyHostInfo::useDriverDriver() const {
308 return false;
309}
310
311ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args,
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000312 const char *ArchName) const {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000313 assert(!ArchName &&
314 "Unexpected arch name on platform without driver driver support.");
315
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000316 ToolChain *&TC = ToolChains[getArchName()];
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000317
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000318 if (!TC) {
319 llvm::Triple TCTriple(getTriple());
320 TCTriple.setArchName(getArchName());
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000321
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000322 TC = new toolchains::DragonFly(*this, TCTriple);
323 }
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000324
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000325 return TC;
326}
327
Eli Friedman6b3454a2009-05-26 07:52:18 +0000328// Linux Host Info
329
330/// LinuxHostInfo - Linux host information implementation.
331class LinuxHostInfo : public HostInfo {
332 /// Cache of tool chains we have created.
333 mutable llvm::StringMap<ToolChain*> ToolChains;
334
335public:
336 LinuxHostInfo(const Driver &D, const llvm::Triple& Triple)
337 : HostInfo(D, Triple) {}
338 ~LinuxHostInfo();
339
340 virtual bool useDriverDriver() const;
341
342 virtual types::ID lookupTypeForExtension(const char *Ext) const {
343 return types::lookupTypeForExtension(Ext);
344 }
345
346 virtual ToolChain *getToolChain(const ArgList &Args,
347 const char *ArchName) const;
348};
349
350LinuxHostInfo::~LinuxHostInfo() {
351 for (llvm::StringMap<ToolChain*>::iterator
352 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
353 delete it->second;
354}
355
356bool LinuxHostInfo::useDriverDriver() const {
357 return false;
358}
359
360ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args,
361 const char *ArchName) const {
362
363 assert(!ArchName &&
364 "Unexpected arch name on platform without driver driver support.");
365
Eli Friedman4e2567d2009-06-03 18:59:56 +0000366 // Automatically handle some instances of -m32/-m64 we know about.
367 std::string Arch = getArchName();
368 ArchName = Arch.c_str();
369 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
370 if (Triple.getArch() == llvm::Triple::x86 ||
371 Triple.getArch() == llvm::Triple::x86_64) {
372 ArchName =
373 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
374 } else if (Triple.getArch() == llvm::Triple::ppc ||
375 Triple.getArch() == llvm::Triple::ppc64) {
376 ArchName =
377 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
378 }
379 }
380
Eli Friedman6b3454a2009-05-26 07:52:18 +0000381 ToolChain *&TC = ToolChains[ArchName];
382
383 if (!TC) {
384 llvm::Triple TCTriple(getTriple());
Eli Friedman4e2567d2009-06-03 18:59:56 +0000385 TCTriple.setArchName(ArchName);
Eli Friedman6b3454a2009-05-26 07:52:18 +0000386
387 TC = new toolchains::Linux(*this, TCTriple);
388 }
389
390 return TC;
391}
392
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000393}
394
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000395const HostInfo *
396clang::driver::createDarwinHostInfo(const Driver &D,
397 const llvm::Triple& Triple){
398 return new DarwinHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000399}
400
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000401const HostInfo *
402clang::driver::createFreeBSDHostInfo(const Driver &D,
403 const llvm::Triple& Triple) {
404 return new FreeBSDHostInfo(D, Triple);
Daniel Dunbar75358d22009-03-30 21:06:03 +0000405}
406
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000407const HostInfo *
408clang::driver::createDragonFlyHostInfo(const Driver &D,
409 const llvm::Triple& Triple) {
410 return new DragonFlyHostInfo(D, Triple);
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000411}
412
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000413const HostInfo *
Eli Friedman6b3454a2009-05-26 07:52:18 +0000414clang::driver::createLinuxHostInfo(const Driver &D,
415 const llvm::Triple& Triple) {
416 return new LinuxHostInfo(D, Triple);
417}
418
419const HostInfo *
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000420clang::driver::createUnknownHostInfo(const Driver &D,
421 const llvm::Triple& Triple) {
422 return new UnknownHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000423}