blob: 831e11b98e42dbae2e18297ef087edf020451fa3 [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 Dunbarf2edbf32009-06-16 21:39:33 +0000111 // If we aren't looking for a specific arch, infer the default architecture
112 // based on -arch and -m32/-m64 command line options.
113 if (Arg *A = Args.getLastArg(options::OPT_arch)) {
114 // The gcc driver behavior with multiple -arch flags wasn't consistent for
115 // things which rely on a default architecture. We just use the last -arch
116 // to find the default tool chain.
117 Arch = A->getValue(Args);
118
119 // Normalize arch name; we shouldn't be doing this here.
120 //
121 // FIXME: This should be unnecessary once everything moves over to using
122 // the ID based Triple interface.
123 if (Arch == "ppc")
124 Arch = "powerpc";
Daniel Dunbar407899b2009-06-16 21:46:01 +0000125 else if (Arch == "ppc64")
Daniel Dunbarf2edbf32009-06-16 21:39:33 +0000126 Arch = "powerpc64";
127 } else {
128 // Otherwise default to the arch of the host.
129 Arch = getArchName();
130 }
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000131 ArchName = Arch.c_str();
Daniel Dunbarf2edbf32009-06-16 21:39:33 +0000132
133 // Honor -m32 and -m64 when finding the default tool chain.
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000134 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
Daniel Dunbarf2edbf32009-06-16 21:39:33 +0000135 if (Arch == "i386" || Arch == "x86_64") {
136 ArchName = (A->getOption().getId() == options::OPT_m32) ? "i386" :
137 "x86_64";
138 } else if (Arch == "powerpc" || Arch == "powerpc64") {
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000139 ArchName = (A->getOption().getId() == options::OPT_m32) ? "powerpc" :
140 "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000141 }
142 }
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000143 } else {
144 // Normalize arch name; we shouldn't be doing this here.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000145 //
146 // FIXME: This should be unnecessary once everything moves over to using the
147 // ID based Triple interface.
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000148 if (strcmp(ArchName, "ppc") == 0)
149 ArchName = "powerpc";
150 else if (strcmp(ArchName, "ppc64") == 0)
151 ArchName = "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000152 }
153
154 ToolChain *&TC = ToolChains[ArchName];
155 if (!TC) {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000156 llvm::Triple TCTriple(getTriple());
157 TCTriple.setArchName(ArchName);
158
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000159 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000160 TC = new toolchains::Darwin_X86(*this, TCTriple,
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000161 DarwinVersion,
162 GCCVersion);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000163 else
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000164 TC = new toolchains::Darwin_GCC(*this, TCTriple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000165 }
166
167 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000168}
169
170// Unknown Host Info
171
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000172/// UnknownHostInfo - Generic host information to use for unknown
173/// hosts.
174class UnknownHostInfo : public HostInfo {
175 /// Cache of tool chains we have created.
176 mutable llvm::StringMap<ToolChain*> ToolChains;
177
178public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000179 UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000180 ~UnknownHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000181
182 virtual bool useDriverDriver() const;
183
Daniel Dunbare33bea42009-03-20 23:39:23 +0000184 virtual types::ID lookupTypeForExtension(const char *Ext) const {
185 return types::lookupTypeForExtension(Ext);
186 }
187
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000188 virtual ToolChain *getToolChain(const ArgList &Args,
189 const char *ArchName) const;
190};
191
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000192UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple)
193 : HostInfo(D, Triple) {
Daniel Dunbare3995642009-03-10 23:50:49 +0000194}
195
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000196UnknownHostInfo::~UnknownHostInfo() {
197 for (llvm::StringMap<ToolChain*>::iterator
198 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
199 delete it->second;
200}
201
Daniel Dunbare3995642009-03-10 23:50:49 +0000202bool UnknownHostInfo::useDriverDriver() const {
203 return false;
204}
205
206ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
207 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000208 assert(!ArchName &&
209 "Unexpected arch name on platform without driver driver support.");
210
211 // Automatically handle some instances of -m32/-m64 we know about.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000212 std::string Arch = getArchName();
213 ArchName = Arch.c_str();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000214 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
Eli Friedman4e2567d2009-06-03 18:59:56 +0000215 if (Triple.getArch() == llvm::Triple::x86 ||
216 Triple.getArch() == llvm::Triple::x86_64) {
217 ArchName =
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000218 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
Eli Friedman4e2567d2009-06-03 18:59:56 +0000219 } else if (Triple.getArch() == llvm::Triple::ppc ||
220 Triple.getArch() == llvm::Triple::ppc64) {
221 ArchName =
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000222 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000223 }
224 }
225
226 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000227 if (!TC) {
228 llvm::Triple TCTriple(getTriple());
229 TCTriple.setArchName(ArchName);
230
231 TC = new toolchains::Generic_GCC(*this, TCTriple);
232 }
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000233
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000234 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000235}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000236
Daniel Dunbar75358d22009-03-30 21:06:03 +0000237// FreeBSD Host Info
238
Daniel Dunbarb85f59d2009-03-30 22:11:38 +0000239/// FreeBSDHostInfo - FreeBSD host information implementation.
Daniel Dunbar75358d22009-03-30 21:06:03 +0000240class FreeBSDHostInfo : public HostInfo {
241 /// Cache of tool chains we have created.
242 mutable llvm::StringMap<ToolChain*> ToolChains;
243
244public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000245 FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
246 : HostInfo(D, Triple) {}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000247 ~FreeBSDHostInfo();
248
249 virtual bool useDriverDriver() const;
250
251 virtual types::ID lookupTypeForExtension(const char *Ext) const {
252 return types::lookupTypeForExtension(Ext);
253 }
254
255 virtual ToolChain *getToolChain(const ArgList &Args,
256 const char *ArchName) const;
257};
258
Daniel Dunbar75358d22009-03-30 21:06:03 +0000259FreeBSDHostInfo::~FreeBSDHostInfo() {
260 for (llvm::StringMap<ToolChain*>::iterator
261 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
262 delete it->second;
263}
264
265bool FreeBSDHostInfo::useDriverDriver() const {
266 return false;
267}
268
269ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
270 const char *ArchName) const {
271 bool Lib32 = false;
272
273 assert(!ArchName &&
274 "Unexpected arch name on platform without driver driver support.");
275
276 // On x86_64 we need to be able to compile 32-bits binaries as well.
277 // Compiling 64-bit binaries on i386 is not supported. We don't have a
278 // lib64.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000279 std::string Arch = getArchName();
280 ArchName = Arch.c_str();
Daniel Dunbar75358d22009-03-30 21:06:03 +0000281 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
282 ArchName = "i386";
283 Lib32 = true;
284 }
285
286 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000287 if (!TC) {
288 llvm::Triple TCTriple(getTriple());
289 TCTriple.setArchName(ArchName);
290
291 TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
292 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000293
294 return TC;
295}
296
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000297// DragonFly Host Info
298
299/// DragonFlyHostInfo - DragonFly host information implementation.
300class DragonFlyHostInfo : public HostInfo {
301 /// Cache of tool chains we have created.
302 mutable llvm::StringMap<ToolChain*> ToolChains;
303
304public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000305 DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
306 : HostInfo(D, Triple) {}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000307 ~DragonFlyHostInfo();
308
309 virtual bool useDriverDriver() const;
310
311 virtual types::ID lookupTypeForExtension(const char *Ext) const {
312 return types::lookupTypeForExtension(Ext);
313 }
314
315 virtual ToolChain *getToolChain(const ArgList &Args,
316 const char *ArchName) const;
317};
318
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000319DragonFlyHostInfo::~DragonFlyHostInfo() {
320 for (llvm::StringMap<ToolChain*>::iterator
321 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
322 delete it->second;
323}
324
325bool DragonFlyHostInfo::useDriverDriver() const {
326 return false;
327}
328
329ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args,
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000330 const char *ArchName) const {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000331 assert(!ArchName &&
332 "Unexpected arch name on platform without driver driver support.");
333
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000334 ToolChain *&TC = ToolChains[getArchName()];
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000335
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000336 if (!TC) {
337 llvm::Triple TCTriple(getTriple());
338 TCTriple.setArchName(getArchName());
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000339
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000340 TC = new toolchains::DragonFly(*this, TCTriple);
341 }
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000342
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000343 return TC;
344}
345
Eli Friedman6b3454a2009-05-26 07:52:18 +0000346// Linux Host Info
347
348/// LinuxHostInfo - Linux host information implementation.
349class LinuxHostInfo : public HostInfo {
350 /// Cache of tool chains we have created.
351 mutable llvm::StringMap<ToolChain*> ToolChains;
352
353public:
354 LinuxHostInfo(const Driver &D, const llvm::Triple& Triple)
355 : HostInfo(D, Triple) {}
356 ~LinuxHostInfo();
357
358 virtual bool useDriverDriver() const;
359
360 virtual types::ID lookupTypeForExtension(const char *Ext) const {
361 return types::lookupTypeForExtension(Ext);
362 }
363
364 virtual ToolChain *getToolChain(const ArgList &Args,
365 const char *ArchName) const;
366};
367
368LinuxHostInfo::~LinuxHostInfo() {
369 for (llvm::StringMap<ToolChain*>::iterator
370 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
371 delete it->second;
372}
373
374bool LinuxHostInfo::useDriverDriver() const {
375 return false;
376}
377
378ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args,
379 const char *ArchName) const {
380
381 assert(!ArchName &&
382 "Unexpected arch name on platform without driver driver support.");
383
Eli Friedman4e2567d2009-06-03 18:59:56 +0000384 // Automatically handle some instances of -m32/-m64 we know about.
385 std::string Arch = getArchName();
386 ArchName = Arch.c_str();
387 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
388 if (Triple.getArch() == llvm::Triple::x86 ||
389 Triple.getArch() == llvm::Triple::x86_64) {
390 ArchName =
391 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
392 } else if (Triple.getArch() == llvm::Triple::ppc ||
393 Triple.getArch() == llvm::Triple::ppc64) {
394 ArchName =
395 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
396 }
397 }
398
Eli Friedman6b3454a2009-05-26 07:52:18 +0000399 ToolChain *&TC = ToolChains[ArchName];
400
401 if (!TC) {
402 llvm::Triple TCTriple(getTriple());
Eli Friedman4e2567d2009-06-03 18:59:56 +0000403 TCTriple.setArchName(ArchName);
Eli Friedman6b3454a2009-05-26 07:52:18 +0000404
405 TC = new toolchains::Linux(*this, TCTriple);
406 }
407
408 return TC;
409}
410
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000411}
412
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000413const HostInfo *
414clang::driver::createDarwinHostInfo(const Driver &D,
415 const llvm::Triple& Triple){
416 return new DarwinHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000417}
418
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000419const HostInfo *
420clang::driver::createFreeBSDHostInfo(const Driver &D,
421 const llvm::Triple& Triple) {
422 return new FreeBSDHostInfo(D, Triple);
Daniel Dunbar75358d22009-03-30 21:06:03 +0000423}
424
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000425const HostInfo *
426clang::driver::createDragonFlyHostInfo(const Driver &D,
427 const llvm::Triple& Triple) {
428 return new DragonFlyHostInfo(D, Triple);
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000429}
430
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000431const HostInfo *
Eli Friedman6b3454a2009-05-26 07:52:18 +0000432clang::driver::createLinuxHostInfo(const Driver &D,
433 const llvm::Triple& Triple) {
434 return new LinuxHostInfo(D, Triple);
435}
436
437const HostInfo *
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000438clang::driver::createUnknownHostInfo(const Driver &D,
439 const llvm::Triple& Triple) {
440 return new UnknownHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000441}