blob: 07aa28673a859673c6e646b4ae68d5cdbefe851e [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" ||
80 getArchName() == "ppc" || getArchName() == "ppc64") &&
81 "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";
120 } else if (getArchName() == "ppc" || getArchName() == "ppc64") {
121 ArchName =
122 (A->getOption().getId() == options::OPT_m32) ? "ppc" : "ppc64";
123 }
124 }
125 }
126
127 ToolChain *&TC = ToolChains[ArchName];
128 if (!TC) {
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000129 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000130 TC = new toolchains::Darwin_X86(*this, ArchName,
131 getPlatformName().c_str(),
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000132 getOSName().c_str(),
133 DarwinVersion,
134 GCCVersion);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000135 else
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000136 TC = new toolchains::Darwin_GCC(*this, ArchName,
137 getPlatformName().c_str(),
138 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000139 }
140
141 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000142}
143
144// Unknown Host Info
145
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000146/// UnknownHostInfo - Generic host information to use for unknown
147/// hosts.
148class UnknownHostInfo : public HostInfo {
149 /// Cache of tool chains we have created.
150 mutable llvm::StringMap<ToolChain*> ToolChains;
151
152public:
Daniel Dunbare5049522009-03-17 20:45:45 +0000153 UnknownHostInfo(const Driver &D, const char *Arch,
154 const char *Platform, const char *OS);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000155 ~UnknownHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000156
157 virtual bool useDriverDriver() const;
158
Daniel Dunbare33bea42009-03-20 23:39:23 +0000159 virtual types::ID lookupTypeForExtension(const char *Ext) const {
160 return types::lookupTypeForExtension(Ext);
161 }
162
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000163 virtual ToolChain *getToolChain(const ArgList &Args,
164 const char *ArchName) const;
165};
166
Daniel Dunbare5049522009-03-17 20:45:45 +0000167UnknownHostInfo::UnknownHostInfo(const Driver &D, const char *Arch,
168 const char *Platform, const char *OS)
169 : HostInfo(D, Arch, Platform, OS) {
Daniel Dunbare3995642009-03-10 23:50:49 +0000170}
171
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000172UnknownHostInfo::~UnknownHostInfo() {
173 for (llvm::StringMap<ToolChain*>::iterator
174 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
175 delete it->second;
176}
177
Daniel Dunbare3995642009-03-10 23:50:49 +0000178bool UnknownHostInfo::useDriverDriver() const {
179 return false;
180}
181
182ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
183 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000184 assert(!ArchName &&
185 "Unexpected arch name on platform without driver driver support.");
186
187 // Automatically handle some instances of -m32/-m64 we know about.
188 ArchName = getArchName().c_str();
189 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
190 if (getArchName() == "i386" || getArchName() == "x86_64") {
191 ArchName =
192 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
193 } else if (getArchName() == "ppc" || getArchName() == "ppc64") {
194 ArchName =
195 (A->getOption().getId() == options::OPT_m32) ? "ppc" : "ppc64";
196 }
197 }
198
199 ToolChain *&TC = ToolChains[ArchName];
200 if (!TC)
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000201 TC = new toolchains::Generic_GCC(*this, ArchName,
202 getPlatformName().c_str(),
203 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000204
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000205 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000206}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000207
Daniel Dunbar75358d22009-03-30 21:06:03 +0000208// FreeBSD Host Info
209
210/// FreeBSDHostInfo - Similar to UnknownHostInfo, but doesn't depend on
211class FreeBSDHostInfo : public HostInfo {
212 /// Cache of tool chains we have created.
213 mutable llvm::StringMap<ToolChain*> ToolChains;
214
215public:
216 FreeBSDHostInfo(const Driver &D, const char *Arch,
217 const char *Platform, const char *OS);
218 ~FreeBSDHostInfo();
219
220 virtual bool useDriverDriver() const;
221
222 virtual types::ID lookupTypeForExtension(const char *Ext) const {
223 return types::lookupTypeForExtension(Ext);
224 }
225
226 virtual ToolChain *getToolChain(const ArgList &Args,
227 const char *ArchName) const;
228};
229
230FreeBSDHostInfo::FreeBSDHostInfo(const Driver &D, const char *Arch,
231 const char *Platform, const char *OS)
232 : HostInfo(D, Arch, Platform, OS) {
233}
234
235FreeBSDHostInfo::~FreeBSDHostInfo() {
236 for (llvm::StringMap<ToolChain*>::iterator
237 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
238 delete it->second;
239}
240
241bool FreeBSDHostInfo::useDriverDriver() const {
242 return false;
243}
244
245ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
246 const char *ArchName) const {
247 bool Lib32 = false;
248
249 assert(!ArchName &&
250 "Unexpected arch name on platform without driver driver support.");
251
252 // On x86_64 we need to be able to compile 32-bits binaries as well.
253 // Compiling 64-bit binaries on i386 is not supported. We don't have a
254 // lib64.
255 ArchName = getArchName().c_str();
256 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
257 ArchName = "i386";
258 Lib32 = true;
259 }
260
261 ToolChain *&TC = ToolChains[ArchName];
262 if (!TC)
263 TC = new toolchains::FreeBSD(*this, ArchName,
264 getPlatformName().c_str(),
265 getOSName().c_str(), Lib32);
266
267 return TC;
268}
269
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000270}
271
Daniel Dunbare5049522009-03-17 20:45:45 +0000272const HostInfo *clang::driver::createDarwinHostInfo(const Driver &D,
273 const char *Arch,
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000274 const char *Platform,
275 const char *OS) {
Daniel Dunbare5049522009-03-17 20:45:45 +0000276 return new DarwinHostInfo(D, Arch, Platform, OS);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000277}
278
Daniel Dunbar75358d22009-03-30 21:06:03 +0000279const HostInfo *clang::driver::createFreeBSDHostInfo(const Driver &D,
280 const char *Arch,
281 const char *Platform,
282 const char *OS) {
283 return new FreeBSDHostInfo(D, Arch, Platform, OS);
284}
285
Daniel Dunbare5049522009-03-17 20:45:45 +0000286const HostInfo *clang::driver::createUnknownHostInfo(const Driver &D,
287 const char *Arch,
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000288 const char *Platform,
289 const char *OS) {
Daniel Dunbare5049522009-03-17 20:45:45 +0000290 return new UnknownHostInfo(D, Arch, Platform, OS);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000291}