blob: 1bee69fd581233259bee47138b9cf24526fa093c [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 Dunbare5049522009-03-17 20:45:45 +000028HostInfo::HostInfo(const Driver &D, const char *_Arch, const char *_Platform,
Daniel Dunbare3995642009-03-10 23:50:49 +000029 const char *_OS)
Daniel Dunbare5049522009-03-17 20:45:45 +000030 : TheDriver(D), Arch(_Arch), Platform(_Platform), OS(_OS)
Daniel Dunbare3995642009-03-10 23:50:49 +000031{
32
33}
34
35HostInfo::~HostInfo() {
36}
37
Chris Lattneraae82f12009-03-17 22:24:01 +000038namespace {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000039
Daniel Dunbare3995642009-03-10 23:50:49 +000040// Darwin Host Info
41
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000042/// DarwinHostInfo - Darwin host information implementation.
43class DarwinHostInfo : public HostInfo {
44 /// Darwin version of host.
45 unsigned DarwinVersion[3];
46
47 /// GCC version to use on this host.
48 unsigned GCCVersion[3];
49
50 /// Cache of tool chains we have created.
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000051 mutable llvm::StringMap<ToolChain *> ToolChains;
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000052
53public:
Daniel Dunbare5049522009-03-17 20:45:45 +000054 DarwinHostInfo(const Driver &D, const char *Arch,
55 const char *Platform, const char *OS);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000056 ~DarwinHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000057
58 virtual bool useDriverDriver() const;
59
Daniel Dunbare33bea42009-03-20 23:39:23 +000060 virtual types::ID lookupTypeForExtension(const char *Ext) const {
61 types::ID Ty = types::lookupTypeForExtension(Ext);
62
63 // Darwin always preprocesses assembly files (unless -x is used
64 // explicitly).
65 if (Ty == types::TY_PP_Asm)
66 return types::TY_Asm;
67
68 return Ty;
69 }
70
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000071 virtual ToolChain *getToolChain(const ArgList &Args,
72 const char *ArchName) const;
73};
74
Daniel Dunbare5049522009-03-17 20:45:45 +000075DarwinHostInfo::DarwinHostInfo(const Driver &D, const char *_Arch,
76 const char *_Platform, const char *_OS)
77 : HostInfo(D, _Arch, _Platform, _OS) {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000078
79 assert((getArchName() == "i386" || getArchName() == "x86_64" ||
Daniel Dunbarbf54a062009-04-01 20:33:11 +000080 getArchName() == "powerpc" || getArchName() == "powerpc64") &&
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000081 "Unknown Darwin arch.");
Daniel Dunbare3995642009-03-10 23:50:49 +000082
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000083 assert(memcmp(&getOSName()[0], "darwin", 6) == 0 &&
84 "Unknown Darwin platform.");
85 const char *Release = &getOSName()[6];
Daniel Dunbard73fe9b2009-03-26 15:58:36 +000086 bool HadExtra;
87 if (!Driver::GetReleaseVersion(Release, DarwinVersion[0], DarwinVersion[1],
88 DarwinVersion[2], HadExtra)) {
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000089 D.Diag(clang::diag::err_drv_invalid_darwin_version)
90 << Release;
91 }
Daniel Dunbare3995642009-03-10 23:50:49 +000092
93 // We can only call 4.2.1 for now.
94 GCCVersion[0] = 4;
95 GCCVersion[1] = 2;
96 GCCVersion[2] = 1;
97}
98
Daniel Dunbar7e4534d2009-03-18 01:09:40 +000099DarwinHostInfo::~DarwinHostInfo() {
100 for (llvm::StringMap<ToolChain*>::iterator
101 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
102 delete it->second;
103}
104
Daniel Dunbare3995642009-03-10 23:50:49 +0000105bool DarwinHostInfo::useDriverDriver() const {
106 return true;
107}
108
109ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args,
110 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000111 if (!ArchName) {
112 ArchName = getArchName().c_str();
113
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.
127 if (strcmp(ArchName, "ppc") == 0)
128 ArchName = "powerpc";
129 else if (strcmp(ArchName, "ppc64") == 0)
130 ArchName = "powerpc64";
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000131 }
132
133 ToolChain *&TC = ToolChains[ArchName];
134 if (!TC) {
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000135 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000136 TC = new toolchains::Darwin_X86(*this, ArchName,
137 getPlatformName().c_str(),
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000138 getOSName().c_str(),
139 DarwinVersion,
140 GCCVersion);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000141 else
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000142 TC = new toolchains::Darwin_GCC(*this, ArchName,
143 getPlatformName().c_str(),
144 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000145 }
146
147 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000148}
149
150// Unknown Host Info
151
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000152/// UnknownHostInfo - Generic host information to use for unknown
153/// hosts.
154class UnknownHostInfo : public HostInfo {
155 /// Cache of tool chains we have created.
156 mutable llvm::StringMap<ToolChain*> ToolChains;
157
158public:
Daniel Dunbare5049522009-03-17 20:45:45 +0000159 UnknownHostInfo(const Driver &D, const char *Arch,
160 const char *Platform, const char *OS);
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 Dunbare5049522009-03-17 20:45:45 +0000173UnknownHostInfo::UnknownHostInfo(const Driver &D, const char *Arch,
174 const char *Platform, const char *OS)
175 : HostInfo(D, Arch, Platform, OS) {
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.
194 ArchName = getArchName().c_str();
195 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];
206 if (!TC)
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000207 TC = new toolchains::Generic_GCC(*this, ArchName,
208 getPlatformName().c_str(),
209 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000210
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000211 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000212}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000213
Daniel Dunbar75358d22009-03-30 21:06:03 +0000214// FreeBSD Host Info
215
Daniel Dunbarb85f59d2009-03-30 22:11:38 +0000216/// FreeBSDHostInfo - FreeBSD host information implementation.
Daniel Dunbar75358d22009-03-30 21:06:03 +0000217class FreeBSDHostInfo : public HostInfo {
218 /// Cache of tool chains we have created.
219 mutable llvm::StringMap<ToolChain*> ToolChains;
220
221public:
222 FreeBSDHostInfo(const Driver &D, const char *Arch,
223 const char *Platform, const char *OS);
224 ~FreeBSDHostInfo();
225
226 virtual bool useDriverDriver() const;
227
228 virtual types::ID lookupTypeForExtension(const char *Ext) const {
229 return types::lookupTypeForExtension(Ext);
230 }
231
232 virtual ToolChain *getToolChain(const ArgList &Args,
233 const char *ArchName) const;
234};
235
236FreeBSDHostInfo::FreeBSDHostInfo(const Driver &D, const char *Arch,
237 const char *Platform, const char *OS)
238 : HostInfo(D, Arch, Platform, OS) {
239}
240
241FreeBSDHostInfo::~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.
261 ArchName = getArchName().c_str();
262 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
263 ArchName = "i386";
264 Lib32 = true;
265 }
266
267 ToolChain *&TC = ToolChains[ArchName];
268 if (!TC)
269 TC = new toolchains::FreeBSD(*this, ArchName,
270 getPlatformName().c_str(),
271 getOSName().c_str(), Lib32);
272
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:
284 DragonFlyHostInfo(const Driver &D, const char *Arch,
285 const char *Platform, const char *OS);
286 ~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
298DragonFlyHostInfo::DragonFlyHostInfo(const Driver &D, const char *Arch,
299 const char *Platform, const char *OS)
300 : HostInfo(D, Arch, Platform, OS) {
301}
302
303DragonFlyHostInfo::~DragonFlyHostInfo() {
304 for (llvm::StringMap<ToolChain*>::iterator
305 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
306 delete it->second;
307}
308
309bool DragonFlyHostInfo::useDriverDriver() const {
310 return false;
311}
312
313ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args,
314 const char *ArchName) const {
315
316 assert(!ArchName &&
317 "Unexpected arch name on platform without driver driver support.");
318
319
320 ArchName = getArchName().c_str();
321
322 ToolChain *&TC = ToolChains[ArchName];
323
324
325 if (!TC)
326 TC = new toolchains::DragonFly(*this, ArchName,
327 getPlatformName().c_str(),
328 getOSName().c_str());
329 return TC;
330}
331
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000332}
333
Daniel Dunbare5049522009-03-17 20:45:45 +0000334const HostInfo *clang::driver::createDarwinHostInfo(const Driver &D,
335 const char *Arch,
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000336 const char *Platform,
337 const char *OS) {
Daniel Dunbare5049522009-03-17 20:45:45 +0000338 return new DarwinHostInfo(D, Arch, Platform, OS);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000339}
340
Daniel Dunbar75358d22009-03-30 21:06:03 +0000341const HostInfo *clang::driver::createFreeBSDHostInfo(const Driver &D,
342 const char *Arch,
343 const char *Platform,
344 const char *OS) {
345 return new FreeBSDHostInfo(D, Arch, Platform, OS);
346}
347
Daniel Dunbar11e1b402009-05-02 18:28:39 +0000348const HostInfo *clang::driver::createDragonFlyHostInfo(const Driver &D,
349 const char *Arch,
350 const char *Platform,
351 const char *OS) {
352 return new DragonFlyHostInfo(D, Arch, Platform, OS);
353}
354
Daniel Dunbare5049522009-03-17 20:45:45 +0000355const HostInfo *clang::driver::createUnknownHostInfo(const Driver &D,
356 const char *Arch,
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000357 const char *Platform,
358 const char *OS) {
Daniel Dunbare5049522009-03-17 20:45:45 +0000359 return new UnknownHostInfo(D, Arch, Platform, OS);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000360}