blob: 39a688a4f5cdf67a49b1b5002e2c5701b2643d73 [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
60 virtual ToolChain *getToolChain(const ArgList &Args,
61 const char *ArchName) const;
62};
63
Daniel Dunbarfc6a8992009-03-20 18:21:51 +000064/// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
65/// return the grouped values as integers. Numbers which are not
66/// provided are set to 0.
67///
68/// \return True if the entire string was parsed (9.2), or all groups
69/// were parsed (10.3.5extrastuff).
70static bool GetReleaseVersion(const char *Str, unsigned &Major,
71 unsigned &Minor, unsigned &Micro) {
72 Major = Minor = Micro = 0;
73 if (*Str == '\0')
74 return true;
75
76 char *End;
77 Major = (unsigned) strtol(Str, &End, 10);
78 if (*Str != '\0' && *End == '\0')
79 return true;
80 if (*End != '.')
81 return false;
82
83 Str = End+1;
84 Minor = (unsigned) strtol(Str, &End, 10);
85 if (*Str != '\0' && *End == '\0')
86 return true;
87 if (*End != '.')
88 return false;
89
90 Str = End+1;
91 Micro = (unsigned) strtol(Str, &End, 10);
92 return true;
93}
94
Daniel Dunbare5049522009-03-17 20:45:45 +000095DarwinHostInfo::DarwinHostInfo(const Driver &D, const char *_Arch,
96 const char *_Platform, const char *_OS)
97 : HostInfo(D, _Arch, _Platform, _OS) {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +000098
99 assert((getArchName() == "i386" || getArchName() == "x86_64" ||
100 getArchName() == "ppc" || getArchName() == "ppc64") &&
101 "Unknown Darwin arch.");
Daniel Dunbare3995642009-03-10 23:50:49 +0000102
Daniel Dunbarfc6a8992009-03-20 18:21:51 +0000103 assert(memcmp(&getOSName()[0], "darwin", 6) == 0 &&
104 "Unknown Darwin platform.");
105 const char *Release = &getOSName()[6];
106 if (!GetReleaseVersion(Release, DarwinVersion[0], DarwinVersion[1],
107 DarwinVersion[2])) {
108 D.Diag(clang::diag::err_drv_invalid_darwin_version)
109 << Release;
110 }
Daniel Dunbare3995642009-03-10 23:50:49 +0000111
112 // We can only call 4.2.1 for now.
113 GCCVersion[0] = 4;
114 GCCVersion[1] = 2;
115 GCCVersion[2] = 1;
116}
117
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000118DarwinHostInfo::~DarwinHostInfo() {
119 for (llvm::StringMap<ToolChain*>::iterator
120 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
121 delete it->second;
122}
123
Daniel Dunbare3995642009-03-10 23:50:49 +0000124bool DarwinHostInfo::useDriverDriver() const {
125 return true;
126}
127
128ToolChain *DarwinHostInfo::getToolChain(const ArgList &Args,
129 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000130 if (!ArchName) {
131 ArchName = getArchName().c_str();
132
133 // If no arch name is specified, infer it from the host and
134 // -m32/-m64.
135 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
136 if (getArchName() == "i386" || getArchName() == "x86_64") {
137 ArchName =
138 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
139 } else if (getArchName() == "ppc" || getArchName() == "ppc64") {
140 ArchName =
141 (A->getOption().getId() == options::OPT_m32) ? "ppc" : "ppc64";
142 }
143 }
144 }
145
146 ToolChain *&TC = ToolChains[ArchName];
147 if (!TC) {
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000148 if (strcmp(ArchName, "i386") == 0 || strcmp(ArchName, "x86_64") == 0)
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000149 TC = new toolchains::Darwin_X86(*this, ArchName,
150 getPlatformName().c_str(),
151 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000152 else
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000153 TC = new toolchains::Darwin_GCC(*this, ArchName,
154 getPlatformName().c_str(),
155 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000156 }
157
158 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000159}
160
161// Unknown Host Info
162
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000163/// UnknownHostInfo - Generic host information to use for unknown
164/// hosts.
165class UnknownHostInfo : public HostInfo {
166 /// Cache of tool chains we have created.
167 mutable llvm::StringMap<ToolChain*> ToolChains;
168
169public:
Daniel Dunbare5049522009-03-17 20:45:45 +0000170 UnknownHostInfo(const Driver &D, const char *Arch,
171 const char *Platform, const char *OS);
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000172 ~UnknownHostInfo();
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000173
174 virtual bool useDriverDriver() const;
175
176 virtual ToolChain *getToolChain(const ArgList &Args,
177 const char *ArchName) const;
178};
179
Daniel Dunbare5049522009-03-17 20:45:45 +0000180UnknownHostInfo::UnknownHostInfo(const Driver &D, const char *Arch,
181 const char *Platform, const char *OS)
182 : HostInfo(D, Arch, Platform, OS) {
Daniel Dunbare3995642009-03-10 23:50:49 +0000183}
184
Daniel Dunbar7e4534d2009-03-18 01:09:40 +0000185UnknownHostInfo::~UnknownHostInfo() {
186 for (llvm::StringMap<ToolChain*>::iterator
187 it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
188 delete it->second;
189}
190
Daniel Dunbare3995642009-03-10 23:50:49 +0000191bool UnknownHostInfo::useDriverDriver() const {
192 return false;
193}
194
195ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
196 const char *ArchName) const {
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000197 assert(!ArchName &&
198 "Unexpected arch name on platform without driver driver support.");
199
200 // Automatically handle some instances of -m32/-m64 we know about.
201 ArchName = getArchName().c_str();
202 if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
203 if (getArchName() == "i386" || getArchName() == "x86_64") {
204 ArchName =
205 (A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
206 } else if (getArchName() == "ppc" || getArchName() == "ppc64") {
207 ArchName =
208 (A->getOption().getId() == options::OPT_m32) ? "ppc" : "ppc64";
209 }
210 }
211
212 ToolChain *&TC = ToolChains[ArchName];
213 if (!TC)
Daniel Dunbar83b08eb2009-03-17 21:38:00 +0000214 TC = new toolchains::Generic_GCC(*this, ArchName,
215 getPlatformName().c_str(),
216 getOSName().c_str());
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000217
Daniel Dunbarb25c7c12009-03-18 01:39:08 +0000218 return TC;
Daniel Dunbare3995642009-03-10 23:50:49 +0000219}
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000220
221}
222
Daniel Dunbare5049522009-03-17 20:45:45 +0000223const HostInfo *clang::driver::createDarwinHostInfo(const Driver &D,
224 const char *Arch,
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000225 const char *Platform,
226 const char *OS) {
Daniel Dunbare5049522009-03-17 20:45:45 +0000227 return new DarwinHostInfo(D, Arch, Platform, OS);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000228}
229
Daniel Dunbare5049522009-03-17 20:45:45 +0000230const HostInfo *clang::driver::createUnknownHostInfo(const Driver &D,
231 const char *Arch,
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000232 const char *Platform,
233 const char *OS) {
Daniel Dunbare5049522009-03-17 20:45:45 +0000234 return new UnknownHostInfo(D, Arch, Platform, OS);
Daniel Dunbar1fd6c4b2009-03-17 19:00:50 +0000235}