Add LLVM runtime checks to build path
[clang/acc.git] / lib / Driver / HostInfo.cpp
blob602a977135055c26abab19704fab24584a7cebab
1 //===--- 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 //===----------------------------------------------------------------------===//
10 #include "clang/Driver/HostInfo.h"
12 #include "clang/Driver/Arg.h"
13 #include "clang/Driver/ArgList.h"
14 #include "clang/Driver/Driver.h"
15 #include "clang/Driver/DriverDiagnostic.h"
16 #include "clang/Driver/Option.h"
17 #include "clang/Driver/Options.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/Support/Compiler.h"
22 #include "ToolChains.h"
24 #include <cassert>
26 using namespace clang::driver;
28 HostInfo::HostInfo(const Driver &D, const llvm::Triple &_Triple)
29 : TheDriver(D), Triple(_Triple)
34 HostInfo::~HostInfo() {
37 namespace {
39 // Darwin Host Info
41 /// DarwinHostInfo - Darwin host information implementation.
42 class DarwinHostInfo : public HostInfo {
43 /// Darwin version of host.
44 unsigned DarwinVersion[3];
46 /// GCC version to use on this host.
47 unsigned GCCVersion[3];
49 /// Cache of tool chains we have created.
50 mutable llvm::StringMap<ToolChain *> ToolChains;
52 public:
53 DarwinHostInfo(const Driver &D, const llvm::Triple &Triple);
54 ~DarwinHostInfo();
56 virtual bool useDriverDriver() const;
58 virtual types::ID lookupTypeForExtension(const char *Ext) const {
59 types::ID Ty = types::lookupTypeForExtension(Ext);
61 // Darwin always preprocesses assembly files (unless -x is used
62 // explicitly).
63 if (Ty == types::TY_PP_Asm)
64 return types::TY_Asm;
66 return Ty;
69 virtual ToolChain *getToolChain(const ArgList &Args,
70 const char *ArchName) const;
73 DarwinHostInfo::DarwinHostInfo(const Driver &D, const llvm::Triple& Triple)
74 : HostInfo(D, Triple) {
76 assert((getArchName() == "i386" || getArchName() == "x86_64" ||
77 getArchName() == "powerpc" || getArchName() == "powerpc64" ||
78 getArchName() == "arm") &&
79 "Unknown Darwin arch.");
81 assert(memcmp(&getOSName()[0], "darwin", 6) == 0 &&
82 "Unknown Darwin platform.");
83 bool HadExtra;
84 if (!Driver::GetReleaseVersion(&getOSName()[6],
85 DarwinVersion[0], DarwinVersion[1],
86 DarwinVersion[2], HadExtra)) {
87 D.Diag(clang::diag::err_drv_invalid_darwin_version)
88 << getOSName();
91 // We can only call 4.2.1 for now.
92 GCCVersion[0] = 4;
93 GCCVersion[1] = 2;
94 GCCVersion[2] = 1;
97 DarwinHostInfo::~DarwinHostInfo() {
98 for (llvm::StringMap<ToolChain*>::iterator
99 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
100 delete it->second;
103 bool DarwinHostInfo::useDriverDriver() const {
104 return true;
107 ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args,
108 const char *ArchName) const {
109 std::string Arch;
110 if (!ArchName) {
111 // 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);
119 // Normalize arch name; we shouldn't be doing this here.
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";
125 else if (Arch == "ppc64")
126 Arch = "powerpc64";
127 } else {
128 // Otherwise default to the arch of the host.
129 Arch = getArchName();
131 ArchName = Arch.c_str();
133 // Honor -m32 and -m64 when finding the default tool chain.
134 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
135 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") {
139 ArchName = (A->getOption().getId() == options::OPT_m32) ? "powerpc" :
140 "powerpc64";
143 } else {
144 // Normalize arch name; we shouldn't be doing this here.
146 // FIXME: This should be unnecessary once everything moves over to using the
147 // ID based Triple interface.
148 if (strcmp(ArchName, "ppc") == 0)
149 ArchName = "powerpc";
150 else if (strcmp(ArchName, "ppc64") == 0)
151 ArchName = "powerpc64";
154 ToolChain *&TC = ToolChains[ArchName];
155 if (!TC) {
156 llvm::Triple TCTriple(getTriple());
157 TCTriple.setArchName(ArchName);
159 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
160 TC = new toolchains::Darwin_X86(*this, TCTriple,
161 DarwinVersion,
162 GCCVersion);
163 else
164 TC = new toolchains::Darwin_GCC(*this, TCTriple);
167 return TC;
170 // Unknown Host Info
172 /// UnknownHostInfo - Generic host information to use for unknown
173 /// hosts.
174 class UnknownHostInfo : public HostInfo {
175 /// Cache of tool chains we have created.
176 mutable llvm::StringMap<ToolChain*> ToolChains;
178 public:
179 UnknownHostInfo(const Driver &D, const llvm::Triple& Triple);
180 ~UnknownHostInfo();
182 virtual bool useDriverDriver() const;
184 virtual types::ID lookupTypeForExtension(const char *Ext) const {
185 return types::lookupTypeForExtension(Ext);
188 virtual ToolChain *getToolChain(const ArgList &Args,
189 const char *ArchName) const;
192 UnknownHostInfo::UnknownHostInfo(const Driver &D, const llvm::Triple& Triple)
193 : HostInfo(D, Triple) {
196 UnknownHostInfo::~UnknownHostInfo() {
197 for (llvm::StringMap<ToolChain*>::iterator
198 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
199 delete it->second;
202 bool UnknownHostInfo::useDriverDriver() const {
203 return false;
206 ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
207 const char *ArchName) const {
208 assert(!ArchName &&
209 "Unexpected arch name on platform without driver driver support.");
211 // Automatically handle some instances of -m32/-m64 we know about.
212 std::string Arch = getArchName();
213 ArchName = Arch.c_str();
214 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
215 if (Triple.getArch() == llvm::Triple::x86 ||
216 Triple.getArch() == llvm::Triple::x86_64) {
217 ArchName =
218 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
219 } else if (Triple.getArch() == llvm::Triple::ppc ||
220 Triple.getArch() == llvm::Triple::ppc64) {
221 ArchName =
222 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
226 ToolChain *&TC = ToolChains[ArchName];
227 if (!TC) {
228 llvm::Triple TCTriple(getTriple());
229 TCTriple.setArchName(ArchName);
231 TC = new toolchains::Generic_GCC(*this, TCTriple);
234 return TC;
237 // OpenBSD Host Info
239 /// OpenBSDHostInfo - OpenBSD host information implementation.
240 class OpenBSDHostInfo : public HostInfo {
241 /// Cache of tool chains we have created.
242 mutable llvm::StringMap<ToolChain*> ToolChains;
244 public:
245 OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
246 : HostInfo(D, Triple) {}
247 ~OpenBSDHostInfo();
249 virtual bool useDriverDriver() const;
251 virtual types::ID lookupTypeForExtension(const char *Ext) const {
252 return types::lookupTypeForExtension(Ext);
255 virtual ToolChain *getToolChain(const ArgList &Args,
256 const char *ArchName) const;
259 OpenBSDHostInfo::~OpenBSDHostInfo() {
260 for (llvm::StringMap<ToolChain*>::iterator
261 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
262 delete it->second;
265 bool OpenBSDHostInfo::useDriverDriver() const {
266 return false;
269 ToolChain *OpenBSDHostInfo::getToolChain(const ArgList &Args,
270 const char *ArchName) const {
271 assert(!ArchName &&
272 "Unexpected arch name on platform without driver driver support.");
274 std::string Arch = getArchName();
275 ArchName = Arch.c_str();
277 ToolChain *&TC = ToolChains[ArchName];
278 if (!TC) {
279 llvm::Triple TCTriple(getTriple());
280 TCTriple.setArchName(ArchName);
282 TC = new toolchains::OpenBSD(*this, TCTriple);
285 return TC;
288 // FreeBSD Host Info
290 /// FreeBSDHostInfo - FreeBSD host information implementation.
291 class FreeBSDHostInfo : public HostInfo {
292 /// Cache of tool chains we have created.
293 mutable llvm::StringMap<ToolChain*> ToolChains;
295 public:
296 FreeBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
297 : HostInfo(D, Triple) {}
298 ~FreeBSDHostInfo();
300 virtual bool useDriverDriver() const;
302 virtual types::ID lookupTypeForExtension(const char *Ext) const {
303 return types::lookupTypeForExtension(Ext);
306 virtual ToolChain *getToolChain(const ArgList &Args,
307 const char *ArchName) const;
310 FreeBSDHostInfo::~FreeBSDHostInfo() {
311 for (llvm::StringMap<ToolChain*>::iterator
312 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
313 delete it->second;
316 bool FreeBSDHostInfo::useDriverDriver() const {
317 return false;
320 ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
321 const char *ArchName) const {
322 bool Lib32 = false;
324 assert(!ArchName &&
325 "Unexpected arch name on platform without driver driver support.");
327 // On x86_64 we need to be able to compile 32-bits binaries as well.
328 // Compiling 64-bit binaries on i386 is not supported. We don't have a
329 // lib64.
330 std::string Arch = getArchName();
331 ArchName = Arch.c_str();
332 if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
333 ArchName = "i386";
334 Lib32 = true;
337 ToolChain *&TC = ToolChains[ArchName];
338 if (!TC) {
339 llvm::Triple TCTriple(getTriple());
340 TCTriple.setArchName(ArchName);
342 TC = new toolchains::FreeBSD(*this, TCTriple, Lib32);
345 return TC;
348 // DragonFly Host Info
350 /// DragonFlyHostInfo - DragonFly host information implementation.
351 class DragonFlyHostInfo : public HostInfo {
352 /// Cache of tool chains we have created.
353 mutable llvm::StringMap<ToolChain*> ToolChains;
355 public:
356 DragonFlyHostInfo(const Driver &D, const llvm::Triple& Triple)
357 : HostInfo(D, Triple) {}
358 ~DragonFlyHostInfo();
360 virtual bool useDriverDriver() const;
362 virtual types::ID lookupTypeForExtension(const char *Ext) const {
363 return types::lookupTypeForExtension(Ext);
366 virtual ToolChain *getToolChain(const ArgList &Args,
367 const char *ArchName) const;
370 DragonFlyHostInfo::~DragonFlyHostInfo() {
371 for (llvm::StringMap<ToolChain*>::iterator
372 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
373 delete it->second;
376 bool DragonFlyHostInfo::useDriverDriver() const {
377 return false;
380 ToolChain *DragonFlyHostInfo::getToolChain(const ArgList &Args,
381 const char *ArchName) const {
382 assert(!ArchName &&
383 "Unexpected arch name on platform without driver driver support.");
385 ToolChain *&TC = ToolChains[getArchName()];
387 if (!TC) {
388 llvm::Triple TCTriple(getTriple());
389 TCTriple.setArchName(getArchName());
391 TC = new toolchains::DragonFly(*this, TCTriple);
394 return TC;
397 // Linux Host Info
399 /// LinuxHostInfo - Linux host information implementation.
400 class LinuxHostInfo : public HostInfo {
401 /// Cache of tool chains we have created.
402 mutable llvm::StringMap<ToolChain*> ToolChains;
404 public:
405 LinuxHostInfo(const Driver &D, const llvm::Triple& Triple)
406 : HostInfo(D, Triple) {}
407 ~LinuxHostInfo();
409 virtual bool useDriverDriver() const;
411 virtual types::ID lookupTypeForExtension(const char *Ext) const {
412 return types::lookupTypeForExtension(Ext);
415 virtual ToolChain *getToolChain(const ArgList &Args,
416 const char *ArchName) const;
419 LinuxHostInfo::~LinuxHostInfo() {
420 for (llvm::StringMap<ToolChain*>::iterator
421 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
422 delete it->second;
425 bool LinuxHostInfo::useDriverDriver() const {
426 return false;
429 ToolChain *LinuxHostInfo::getToolChain(const ArgList &Args,
430 const char *ArchName) const {
432 assert(!ArchName &&
433 "Unexpected arch name on platform without driver driver support.");
435 // Automatically handle some instances of -m32/-m64 we know about.
436 std::string Arch = getArchName();
437 ArchName = Arch.c_str();
438 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
439 if (Triple.getArch() == llvm::Triple::x86 ||
440 Triple.getArch() == llvm::Triple::x86_64) {
441 ArchName =
442 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
443 } else if (Triple.getArch() == llvm::Triple::ppc ||
444 Triple.getArch() == llvm::Triple::ppc64) {
445 ArchName =
446 (A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
450 ToolChain *&TC = ToolChains[ArchName];
452 if (!TC) {
453 llvm::Triple TCTriple(getTriple());
454 TCTriple.setArchName(ArchName);
456 TC = new toolchains::Linux(*this, TCTriple);
459 return TC;
464 const HostInfo *
465 clang::driver::createDarwinHostInfo(const Driver &D,
466 const llvm::Triple& Triple){
467 return new DarwinHostInfo(D, Triple);
470 const HostInfo *
471 clang::driver::createOpenBSDHostInfo(const Driver &D,
472 const llvm::Triple& Triple) {
473 return new OpenBSDHostInfo(D, Triple);
476 const HostInfo *
477 clang::driver::createFreeBSDHostInfo(const Driver &D,
478 const llvm::Triple& Triple) {
479 return new FreeBSDHostInfo(D, Triple);
482 const HostInfo *
483 clang::driver::createDragonFlyHostInfo(const Driver &D,
484 const llvm::Triple& Triple) {
485 return new DragonFlyHostInfo(D, Triple);
488 const HostInfo *
489 clang::driver::createLinuxHostInfo(const Driver &D,
490 const llvm::Triple& Triple) {
491 return new LinuxHostInfo(D, Triple);
494 const HostInfo *
495 clang::driver::createUnknownHostInfo(const Driver &D,
496 const llvm::Triple& Triple) {
497 return new UnknownHostInfo(D, Triple);