blob: 603b3ab230faa31f0f7cce055a95bba1878edcdb [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)) {
197 if (getArchName() == "i386" || getArchName() == "x86_64") {
198 ArchName =
199 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000200 } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000201 ArchName =
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000202 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000203 }
204 }
205
206 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000207 if (!TC) {
208 llvm::Triple TCTriple(getTriple());
209 TCTriple.setArchName(ArchName);
210
211 TC = new toolchains::Generic_GCC(*this, TCTriple);
212 }
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000213
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000214 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000215}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000216
Daniel Dunbar75358d22009-03-30 21:06:03 +0000217// FreeBSD Host Info
218
Daniel Dunbarb85f59d2009-03-30 22:11:38 +0000219/// FreeBSDHostInfo - FreeBSD host information implementation.
Daniel Dunbar75358d22009-03-30 21:06:03 +0000220class FreeBSDHostInfo : public HostInfo {
221 /// Cache of tool chains we have created.
222 mutable llvm::StringMap<ToolChain*> ToolChains;
223
224public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000225 FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
226 : HostInfo(D, Triple) {}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000227 ~FreeBSDHostInfo();
228
229 virtual bool useDriverDriver() const;
230
231 virtual types::ID lookupTypeForExtension(const char *Ext) const {
232 return types::lookupTypeForExtension(Ext);
233 }
234
235 virtual ToolChain *getToolChain(const ArgList &Args,
236 const char *ArchName) const;
237};
238
Daniel Dunbar75358d22009-03-30 21:06:03 +0000239FreeBSDHostInfo::~FreeBSDHostInfo() {
240 for (llvm::StringMap<ToolChain*>::iterator
241 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
242 delete it->second;
243}
244
245bool FreeBSDHostInfo::useDriverDriver() const {
246 return false;
247}
248
249ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
250 const char *ArchName) const {
251 bool Lib32 = false;
252
253 assert(!ArchName &&
254 "Unexpected arch name on platform without driver driver support.");
255
256 // On x86_64 we need to be able to compile 32-bits binaries as well.
257 // Compiling 64-bit binaries on i386 is not supported. We don't have a
258 // lib64.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000259 std::string Arch = getArchName();
260 ArchName = Arch.c_str();
Daniel Dunbar75358d22009-03-30 21:06:03 +0000261 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
262 ArchName = "i386";
263 Lib32 = true;
264 }
265
266 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000267 if (!TC) {
268 llvm::Triple TCTriple(getTriple());
269 TCTriple.setArchName(ArchName);
270
271 TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
272 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000273
274 return TC;
275}
276
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000277// DragonFly Host Info
278
279/// DragonFlyHostInfo - DragonFly host information implementation.
280class DragonFlyHostInfo : public HostInfo {
281 /// Cache of tool chains we have created.
282 mutable llvm::StringMap<ToolChain*> ToolChains;
283
284public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000285 DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
286 : HostInfo(D, Triple) {}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000287 ~DragonFlyHostInfo();
288
289 virtual bool useDriverDriver() const;
290
291 virtual types::ID lookupTypeForExtension(const char *Ext) const {
292 return types::lookupTypeForExtension(Ext);
293 }
294
295 virtual ToolChain *getToolChain(const ArgList &Args,
296 const char *ArchName) const;
297};
298
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000299DragonFlyHostInfo::~DragonFlyHostInfo() {
300 for (llvm::StringMap<ToolChain*>::iterator
301 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
302 delete it->second;
303}
304
305bool DragonFlyHostInfo::useDriverDriver() const {
306 return false;
307}
308
309ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args,
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000310 const char *ArchName) const {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000311 assert(!ArchName &&
312 "Unexpected arch name on platform without driver driver support.");
313
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000314 ToolChain *&TC = ToolChains[getArchName()];
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000315
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000316 if (!TC) {
317 llvm::Triple TCTriple(getTriple());
318 TCTriple.setArchName(getArchName());
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000319
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000320 TC = new toolchains::DragonFly(*this, TCTriple);
321 }
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000322
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000323 return TC;
324}
325
Eli Friedman6b3454a2009-05-26 07:52:18 +0000326// Linux Host Info
327
328/// LinuxHostInfo - Linux host information implementation.
329class LinuxHostInfo : public HostInfo {
330 /// Cache of tool chains we have created.
331 mutable llvm::StringMap<ToolChain*> ToolChains;
332
333public:
334 LinuxHostInfo(const Driver &D, const llvm::Triple& Triple)
335 : HostInfo(D, Triple) {}
336 ~LinuxHostInfo();
337
338 virtual bool useDriverDriver() const;
339
340 virtual types::ID lookupTypeForExtension(const char *Ext) const {
341 return types::lookupTypeForExtension(Ext);
342 }
343
344 virtual ToolChain *getToolChain(const ArgList &Args,
345 const char *ArchName) const;
346};
347
348LinuxHostInfo::~LinuxHostInfo() {
349 for (llvm::StringMap<ToolChain*>::iterator
350 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
351 delete it->second;
352}
353
354bool LinuxHostInfo::useDriverDriver() const {
355 return false;
356}
357
358ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args,
359 const char *ArchName) const {
360
361 assert(!ArchName &&
362 "Unexpected arch name on platform without driver driver support.");
363
364 ArchName = getArchName().c_str();
365
366 ToolChain *&TC = ToolChains[ArchName];
367
368 if (!TC) {
369 llvm::Triple TCTriple(getTriple());
370 TCTriple.setArchName(getArchName());
371
372 TC = new toolchains::Linux(*this, TCTriple);
373 }
374
375 return TC;
376}
377
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000378}
379
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000380const HostInfo *
381clang::driver::createDarwinHostInfo(const Driver &D,
382 const llvm::Triple& Triple){
383 return new DarwinHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000384}
385
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000386const HostInfo *
387clang::driver::createFreeBSDHostInfo(const Driver &D,
388 const llvm::Triple& Triple) {
389 return new FreeBSDHostInfo(D, Triple);
Daniel Dunbar75358d22009-03-30 21:06:03 +0000390}
391
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000392const HostInfo *
393clang::driver::createDragonFlyHostInfo(const Driver &D,
394 const llvm::Triple& Triple) {
395 return new DragonFlyHostInfo(D, Triple);
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000396}
397
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000398const HostInfo *
Eli Friedman6b3454a2009-05-26 07:52:18 +0000399clang::driver::createLinuxHostInfo(const Driver &D,
400 const llvm::Triple& Triple) {
401 return new LinuxHostInfo(D, Triple);
402}
403
404const HostInfo *
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000405clang::driver::createUnknownHostInfo(const Driver &D,
406 const llvm::Triple& Triple) {
407 return new UnknownHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000408}