blob: f60d25e754f44686f041fed5b58d078ce377fb12 [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" ||
Daniel Dunbarbf54a062009-04-01 20:33:11 +000077 getArchName() == "powerpc" || getArchName() == "powerpc64") &&
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000078 "Unknown Darwin arch.");
Daniel Dunbare3995642009-03-10 23:50:49 +000079
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000080 assert(memcmp(&getOSName()[0], "darwin", 6) == 0 &&
81 "Unknown Darwin platform.");
Daniel Dunbard73fe9b2009-03-26 15:58:36 +000082 bool HadExtra;
Daniel Dunbar10708c42009-05-23 18:55:58 +000083 if (!Driver::GetReleaseVersion(&getOSName()[6],
84 DarwinVersion[0], DarwinVersion[1],
Daniel Dunbard73fe9b2009-03-26 15:58:36 +000085 DarwinVersion[2], HadExtra)) {
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000086 D.Diag(clang::diag::err_drv_invalid_darwin_version)
Daniel Dunbar10708c42009-05-23 18:55:58 +000087 << getOSName();
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000088 }
Daniel Dunbare3995642009-03-10 23:50:49 +000089
90 // We can only call 4.2.1 for now.
91 GCCVersion[0] = 4;
92 GCCVersion[1] = 2;
93 GCCVersion[2] = 1;
94}
95
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000096DarwinHostInfo::~DarwinHostInfo() {
97 for (llvm::StringMap<ToolChain*>::iterator
98 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
99 delete it->second;
100}
101
Daniel Dunbare3995642009-03-10 23:50:49 +0000102bool DarwinHostInfo::useDriverDriver() const {
103 return true;
104}
105
106ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args,
107 const char *ArchName) const {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000108 std::string Arch;
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000109 if (!ArchName) {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000110 Arch = getArchName();
111 ArchName = Arch.c_str();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000112
113 // If no arch name is specified, infer it from the host and
114 // -m32/-m64.
115 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
116 if (getArchName() == "i386" || getArchName() == "x86_64") {
117 ArchName =
118 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000119 } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") {
120 ArchName = (A->getOption().getId() == options::OPT_m32) ? "powerpc" :
121 "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000122 }
123 }
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000124 } else {
125 // Normalize arch name; we shouldn't be doing this here.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000126 //
127 // FIXME: This should be unnecessary once everything moves over to using the
128 // ID based Triple interface.
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000129 if (strcmp(ArchName, "ppc") == 0)
130 ArchName = "powerpc";
131 else if (strcmp(ArchName, "ppc64") == 0)
132 ArchName = "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000133 }
134
135 ToolChain *&TC = ToolChains[ArchName];
136 if (!TC) {
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000137 llvm::Triple TCTriple(getTriple());
138 TCTriple.setArchName(ArchName);
139
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000140 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000141 TC = new toolchains::Darwin_X86(*this, TCTriple,
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000142 DarwinVersion,
143 GCCVersion);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000144 else
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000145 TC = new toolchains::Darwin_GCC(*this, TCTriple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000146 }
147
148 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000149}
150
151// Unknown Host Info
152
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000153/// UnknownHostInfo - Generic host information to use for unknown
154/// hosts.
155class UnknownHostInfo : public HostInfo {
156 /// Cache of tool chains we have created.
157 mutable llvm::StringMap<ToolChain*> ToolChains;
158
159public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000160 UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000161 ~UnknownHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000162
163 virtual bool useDriverDriver() const;
164
Daniel Dunbare33bea42009-03-20 23:39:23 +0000165 virtual types::ID lookupTypeForExtension(const char *Ext) const {
166 return types::lookupTypeForExtension(Ext);
167 }
168
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000169 virtual ToolChain *getToolChain(const ArgList &Args,
170 const char *ArchName) const;
171};
172
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000173UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple)
174 : HostInfo(D, Triple) {
Daniel Dunbare3995642009-03-10 23:50:49 +0000175}
176
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000177UnknownHostInfo::~UnknownHostInfo() {
178 for (llvm::StringMap<ToolChain*>::iterator
179 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
180 delete it->second;
181}
182
Daniel Dunbare3995642009-03-10 23:50:49 +0000183bool UnknownHostInfo::useDriverDriver() const {
184 return false;
185}
186
187ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
188 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000189 assert(!ArchName &&
190 "Unexpected arch name on platform without driver driver support.");
191
192 // Automatically handle some instances of -m32/-m64 we know about.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000193 std::string Arch = getArchName();
194 ArchName = Arch.c_str();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000195 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
196 if (getArchName() == "i386" || getArchName() == "x86_64") {
197 ArchName =
198 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000199 } else if (getArchName() == "powerpc" || getArchName() == "powerpc64") {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000200 ArchName =
Daniel Dunbarbf54a062009-04-01 20:33:11 +0000201 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000202 }
203 }
204
205 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000206 if (!TC) {
207 llvm::Triple TCTriple(getTriple());
208 TCTriple.setArchName(ArchName);
209
210 TC = new toolchains::Generic_GCC(*this, TCTriple);
211 }
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000212
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000213 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000214}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000215
Daniel Dunbar75358d22009-03-30 21:06:03 +0000216// FreeBSD Host Info
217
Daniel Dunbarb85f59d2009-03-30 22:11:38 +0000218/// FreeBSDHostInfo - FreeBSD host information implementation.
Daniel Dunbar75358d22009-03-30 21:06:03 +0000219class FreeBSDHostInfo : public HostInfo {
220 /// Cache of tool chains we have created.
221 mutable llvm::StringMap<ToolChain*> ToolChains;
222
223public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000224 FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
225 : HostInfo(D, Triple) {}
Daniel Dunbar75358d22009-03-30 21:06:03 +0000226 ~FreeBSDHostInfo();
227
228 virtual bool useDriverDriver() const;
229
230 virtual types::ID lookupTypeForExtension(const char *Ext) const {
231 return types::lookupTypeForExtension(Ext);
232 }
233
234 virtual ToolChain *getToolChain(const ArgList &Args,
235 const char *ArchName) const;
236};
237
Daniel Dunbar75358d22009-03-30 21:06:03 +0000238FreeBSDHostInfo::~FreeBSDHostInfo() {
239 for (llvm::StringMap<ToolChain*>::iterator
240 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
241 delete it->second;
242}
243
244bool FreeBSDHostInfo::useDriverDriver() const {
245 return false;
246}
247
248ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
249 const char *ArchName) const {
250 bool Lib32 = false;
251
252 assert(!ArchName &&
253 "Unexpected arch name on platform without driver driver support.");
254
255 // On x86_64 we need to be able to compile 32-bits binaries as well.
256 // Compiling 64-bit binaries on i386 is not supported. We don't have a
257 // lib64.
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000258 std::string Arch = getArchName();
259 ArchName = Arch.c_str();
Daniel Dunbar75358d22009-03-30 21:06:03 +0000260 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
261 ArchName = "i386";
262 Lib32 = true;
263 }
264
265 ToolChain *&TC = ToolChains[ArchName];
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000266 if (!TC) {
267 llvm::Triple TCTriple(getTriple());
268 TCTriple.setArchName(ArchName);
269
270 TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
271 }
Daniel Dunbar75358d22009-03-30 21:06:03 +0000272
273 return TC;
274}
275
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000276// DragonFly Host Info
277
278/// DragonFlyHostInfo - DragonFly host information implementation.
279class DragonFlyHostInfo : public HostInfo {
280 /// Cache of tool chains we have created.
281 mutable llvm::StringMap<ToolChain*> ToolChains;
282
283public:
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000284 DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
285 : HostInfo(D, Triple) {}
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000286 ~DragonFlyHostInfo();
287
288 virtual bool useDriverDriver() const;
289
290 virtual types::ID lookupTypeForExtension(const char *Ext) const {
291 return types::lookupTypeForExtension(Ext);
292 }
293
294 virtual ToolChain *getToolChain(const ArgList &Args,
295 const char *ArchName) const;
296};
297
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000298DragonFlyHostInfo::~DragonFlyHostInfo() {
299 for (llvm::StringMap<ToolChain*>::iterator
300 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
301 delete it->second;
302}
303
304bool DragonFlyHostInfo::useDriverDriver() const {
305 return false;
306}
307
308ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args,
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000309 const char *ArchName) const {
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000310 assert(!ArchName &&
311 "Unexpected arch name on platform without driver driver support.");
312
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000313 ToolChain *&TC = ToolChains[getArchName()];
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000314
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000315 if (!TC) {
316 llvm::Triple TCTriple(getTriple());
317 TCTriple.setArchName(getArchName());
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000318
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000319 TC = new toolchains::DragonFly(*this, TCTriple);
320 }
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000321
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000322 return TC;
323}
324
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000325}
326
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000327const HostInfo *
328clang::driver::createDarwinHostInfo(const Driver &D,
329 const llvm::Triple& Triple){
330 return new DarwinHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000331}
332
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000333const HostInfo *
334clang::driver::createFreeBSDHostInfo(const Driver &D,
335 const llvm::Triple& Triple) {
336 return new FreeBSDHostInfo(D, Triple);
Daniel Dunbar75358d22009-03-30 21:06:03 +0000337}
338
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000339const HostInfo *
340clang::driver::createDragonFlyHostInfo(const Driver &D,
341 const llvm::Triple& Triple) {
342 return new DragonFlyHostInfo(D, Triple);
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000343}
344
Daniel Dunbarcb8ab232009-05-22 02:53:45 +0000345const HostInfo *
346clang::driver::createUnknownHostInfo(const Driver &D,
347 const llvm::Triple& Triple) {
348 return new UnknownHostInfo(D, Triple);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000349}