blob: 1b0bdfaad30b2f4a9cb099484a87d50e4677b3a3 [file] [log] [blame]
Daniel Dunbar39176082009-03-20 00:20:03 +00001//===--- ToolChains.cpp - ToolChain Implementations ---------------------*-===//
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 "ToolChains.h"
11
Daniel Dunbarf3cad362009-03-25 04:13:45 +000012#include "clang/Driver/Arg.h"
13#include "clang/Driver/ArgList.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000014#include "clang/Driver/Driver.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000015#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000016#include "clang/Driver/HostInfo.h"
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +000017#include "clang/Driver/Option.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000018
19#include "llvm/ADT/StringExtras.h"
Daniel Dunbarec069ed2009-03-25 06:58:31 +000020#include "llvm/Support/raw_ostream.h"
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000021#include "llvm/System/Path.h"
22
Daniel Dunbar39176082009-03-20 00:20:03 +000023using namespace clang::driver;
24using namespace clang::driver::toolchains;
25
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000026/// Darwin_X86 - Darwin tool chain for i386 and x86_64.
27
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000028Darwin_X86::Darwin_X86(const HostInfo &Host, const char *Arch,
29 const char *Platform, const char *OS,
30 const unsigned (&_DarwinVersion)[3],
31 const unsigned (&_GCCVersion)[3])
32 : ToolChain(Host, Arch, Platform, OS)
33{
34 DarwinVersion[0] = _DarwinVersion[0];
35 DarwinVersion[1] = _DarwinVersion[1];
36 DarwinVersion[2] = _DarwinVersion[2];
37 GCCVersion[0] = _GCCVersion[0];
38 GCCVersion[1] = _GCCVersion[1];
39 GCCVersion[2] = _GCCVersion[2];
40
Daniel Dunbar02633b52009-03-26 16:23:12 +000041 llvm::raw_string_ostream(MacosxVersionMin)
42 << "10." << DarwinVersion[0] - 4 << '.' << DarwinVersion[1];
43
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000044 ToolChainDir = "i686-apple-darwin";
45 ToolChainDir += llvm::utostr(DarwinVersion[0]);
46 ToolChainDir += "/";
47 ToolChainDir += llvm::utostr(GCCVersion[0]);
48 ToolChainDir += '.';
49 ToolChainDir += llvm::utostr(GCCVersion[1]);
50 ToolChainDir += '.';
51 ToolChainDir += llvm::utostr(GCCVersion[2]);
52
53 std::string Path;
54 if (getArchName() == "x86_64") {
55 Path = getHost().getDriver().Dir;
56 Path += "/../lib/gcc/";
57 Path += getToolChainDir();
58 Path += "/x86_64";
59 getFilePaths().push_back(Path);
60
61 Path = "/usr/lib/gcc/";
62 Path += getToolChainDir();
63 Path += "/x86_64";
64 getFilePaths().push_back(Path);
65 }
66
67 Path = getHost().getDriver().Dir;
68 Path += "/../lib/gcc/";
69 Path += getToolChainDir();
70 getFilePaths().push_back(Path);
71
72 Path = "/usr/lib/gcc/";
73 Path += getToolChainDir();
74 getFilePaths().push_back(Path);
75
76 Path = getHost().getDriver().Dir;
77 Path += "/../libexec/gcc/";
78 Path += getToolChainDir();
79 getProgramPaths().push_back(Path);
80
81 Path = "/usr/libexec/gcc/";
82 Path += getToolChainDir();
83 getProgramPaths().push_back(Path);
84
Daniel Dunbar82fa7c52009-03-24 04:07:10 +000085 Path = getHost().getDriver().Dir;
86 Path += "/../libexec";
87 getProgramPaths().push_back(Path);
88
Daniel Dunbarc50b00d2009-03-23 16:15:50 +000089 getProgramPaths().push_back(getHost().getDriver().Dir);
90}
91
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +000092Darwin_X86::~Darwin_X86() {
93 // Free tool implementations.
94 for (llvm::DenseMap<unsigned, Tool*>::iterator
95 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
96 delete it->second;
97}
98
99Tool &Darwin_X86::SelectTool(const Compilation &C,
100 const JobAction &JA) const {
101 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000102 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000103 Key = Action::AnalyzeJobClass;
104 else
105 Key = JA.getKind();
106
107 Tool *&T = Tools[Key];
108 if (!T) {
109 switch (Key) {
110 case Action::InputClass:
111 case Action::BindArchClass:
112 assert(0 && "Invalid tool kind.");
113 case Action::PreprocessJobClass:
114 T = new tools::gcc::Preprocess(*this); break;
115 case Action::PrecompileJobClass:
116 T = new tools::gcc::Precompile(*this); break;
117 case Action::AnalyzeJobClass:
118 T = new tools::Clang(*this); break;
119 case Action::CompileJobClass:
120 T = new tools::gcc::Compile(*this); break;
121 case Action::AssembleJobClass:
Daniel Dunbar8cac5f72009-03-20 16:06:39 +0000122 T = new tools::darwin::Assemble(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000123 case Action::LinkJobClass:
Daniel Dunbar02633b52009-03-26 16:23:12 +0000124 T = new tools::darwin::Link(*this, MacosxVersionMin.c_str()); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000125 case Action::LipoJobClass:
126 T = new tools::darwin::Lipo(*this); break;
127 }
128 }
129
130 return *T;
131}
132
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000133DerivedArgList *Darwin_X86::TranslateArgs(InputArgList &Args) const {
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000134 DerivedArgList *DAL = new DerivedArgList(Args, false);
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000135 const OptTable &Opts = getHost().getDriver().getOpts();
136
137 // FIXME: We really want to get out of the tool chain level argument
138 // translation business, as it makes the driver functionality much
139 // more opaque. For now, we follow gcc closely solely for the
140 // purpose of easily achieving feature parity & testability. Once we
141 // have something that works, we should reevaluate each translation
142 // and try to push it down into tool specific logic.
143
144 if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ, false)) {
145 const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
Daniel Dunbar02633b52009-03-26 16:23:12 +0000146 DAL->append(DAL->MakeJoinedArg(O, MacosxVersionMin.c_str()));
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000147 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000148
149 for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
150 Arg *A = *it;
151
152 if (A->getOption().matches(options::OPT_Xarch__)) {
153 // FIXME: Canonicalize name.
154 if (getArchName() != A->getValue(Args, 0))
155 continue;
156
157 // FIXME: The arg is leaked here, and we should have a nicer
158 // interface for this.
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000159 unsigned Prev, Index = Prev = A->getIndex() + 1;
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000160 Arg *XarchArg = Opts.ParseOneArg(Args, Index);
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000161
162 // If the argument parsing failed or more than one argument was
163 // consumed, the -Xarch_ argument's parameter tried to consume
164 // extra arguments. Emit an error and ignore.
165 //
166 // We also want to disallow any options which would alter the
167 // driver behavior; that isn't going to work in our model. We
168 // use isDriverOption() as an approximation, although things
169 // like -O4 are going to slip through.
170 if (!XarchArg || Index > Prev + 1 ||
171 XarchArg->getOption().isDriverOption()) {
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000172 getHost().getDriver().Diag(clang::diag::err_drv_invalid_Xarch_argument)
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000173 << A->getAsString(Args);
174 continue;
175 }
176
177 A = XarchArg;
178 }
179
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000180 // Sob. These is strictly gcc compatible for the time being. Apple
181 // gcc translates options twice, which means that self-expanding
182 // options add duplicates.
183 options::ID id = A->getOption().getId();
184 switch (id) {
185 default:
186 DAL->append(A);
187 break;
188
189 case options::OPT_mkernel:
190 case options::OPT_fapple_kext:
191 DAL->append(A);
192 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_static)));
193 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_static)));
194 break;
195
196 case options::OPT_dependency_file:
197 DAL->append(DAL->MakeSeparateArg(Opts.getOption(options::OPT_MF),
198 A->getValue(Args)));
199 break;
200
201 case options::OPT_gfull:
202 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_g_Flag)));
203 DAL->append(DAL->MakeFlagArg(
204 Opts.getOption(options::OPT_fno_eliminate_unused_debug_symbols)));
205 break;
206
207 case options::OPT_gused:
208 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_g_Flag)));
209 DAL->append(DAL->MakeFlagArg(
210 Opts.getOption(options::OPT_feliminate_unused_debug_symbols)));
211 break;
212
213 case options::OPT_fterminated_vtables:
214 case options::OPT_findirect_virtual_calls:
215 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_fapple_kext)));
216 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_static)));
217 break;
218
219 case options::OPT_shared:
220 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_dynamiclib)));
221 break;
222
223 case options::OPT_fconstant_cfstrings:
224 DAL->append(DAL->MakeFlagArg(
225 Opts.getOption(options::OPT_mconstant_cfstrings)));
226 break;
227
228 case options::OPT_fno_constant_cfstrings:
229 DAL->append(DAL->MakeFlagArg(
230 Opts.getOption(options::OPT_mno_constant_cfstrings)));
231 break;
232
233 case options::OPT_Wnonportable_cfstrings:
234 DAL->append(DAL->MakeFlagArg(
235 Opts.getOption(options::OPT_mwarn_nonportable_cfstrings)));
236 break;
237
238 case options::OPT_Wno_nonportable_cfstrings:
239 DAL->append(DAL->MakeFlagArg(
240 Opts.getOption(options::OPT_mno_warn_nonportable_cfstrings)));
241 break;
242
243 case options::OPT_fpascal_strings:
244 DAL->append(DAL->MakeFlagArg(
245 Opts.getOption(options::OPT_mpascal_strings)));
246 break;
247
248 case options::OPT_fno_pascal_strings:
249 DAL->append(DAL->MakeFlagArg(
250 Opts.getOption(options::OPT_mno_pascal_strings)));
251 break;
252 }
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000253 }
254
Daniel Dunbarec069ed2009-03-25 06:58:31 +0000255 // FIXME: Actually, gcc always adds this, but it is filtered for
256 // duplicates somewhere. This also changes the order of things, so
257 // look it up.
258 if (getArchName() == "x86_64")
259 if (!Args.hasArg(options::OPT_m64, false))
260 DAL->append(DAL->MakeFlagArg(Opts.getOption(options::OPT_m64)));
261
262 if (!Args.hasArg(options::OPT_mtune_EQ, false))
263 DAL->append(DAL->MakeJoinedArg(Opts.getOption(options::OPT_mtune_EQ),
264 "core2"));
265
Daniel Dunbar4e7e9cf2009-03-25 06:12:34 +0000266 return DAL;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000267}
268
269bool Darwin_X86::IsMathErrnoDefault() const {
270 return false;
271}
272
273bool Darwin_X86::IsUnwindTablesDefault() const {
274 // FIXME: Gross; we should probably have some separate target
275 // definition, possibly even reusing the one in clang.
276 return getArchName() == "x86_64";
277}
278
279const char *Darwin_X86::GetDefaultRelocationModel() const {
280 return "pic";
281}
282
283const char *Darwin_X86::GetForcedPicModel() const {
284 if (getArchName() == "x86_64")
285 return "pic";
286 return 0;
287}
288
Daniel Dunbar39176082009-03-20 00:20:03 +0000289/// Generic_GCC - A tool chain using the 'gcc' command to perform
290/// all subcommands; this relies on gcc translating the majority of
291/// command line options.
292
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000293Generic_GCC::Generic_GCC(const HostInfo &Host, const char *Arch,
294 const char *Platform, const char *OS)
295 : ToolChain(Host, Arch, Platform, OS)
296{
Daniel Dunbar82fa7c52009-03-24 04:07:10 +0000297 std::string Path(getHost().getDriver().Dir);
298 Path += "/../libexec";
299 getProgramPaths().push_back(Path);
300
Daniel Dunbarc50b00d2009-03-23 16:15:50 +0000301 getProgramPaths().push_back(getHost().getDriver().Dir);
302}
303
Daniel Dunbar39176082009-03-20 00:20:03 +0000304Generic_GCC::~Generic_GCC() {
305 // Free tool implementations.
306 for (llvm::DenseMap<unsigned, Tool*>::iterator
307 it = Tools.begin(), ie = Tools.end(); it != ie; ++it)
308 delete it->second;
309}
310
311Tool &Generic_GCC::SelectTool(const Compilation &C,
312 const JobAction &JA) const {
313 Action::ActionClass Key;
Daniel Dunbaraf80e1f2009-03-24 18:57:02 +0000314 if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
Daniel Dunbar39176082009-03-20 00:20:03 +0000315 Key = Action::AnalyzeJobClass;
316 else
317 Key = JA.getKind();
318
319 Tool *&T = Tools[Key];
320 if (!T) {
321 switch (Key) {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000322 case Action::InputClass:
323 case Action::BindArchClass:
Daniel Dunbar39176082009-03-20 00:20:03 +0000324 assert(0 && "Invalid tool kind.");
325 case Action::PreprocessJobClass:
326 T = new tools::gcc::Preprocess(*this); break;
327 case Action::PrecompileJobClass:
328 T = new tools::gcc::Precompile(*this); break;
329 case Action::AnalyzeJobClass:
330 T = new tools::Clang(*this); break;
331 case Action::CompileJobClass:
332 T = new tools::gcc::Compile(*this); break;
333 case Action::AssembleJobClass:
334 T = new tools::gcc::Assemble(*this); break;
335 case Action::LinkJobClass:
336 T = new tools::gcc::Link(*this); break;
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000337
338 // This is a bit ungeneric, but the only platform using a driver
339 // driver is Darwin.
340 case Action::LipoJobClass:
341 T = new tools::darwin::Lipo(*this); break;
Daniel Dunbar39176082009-03-20 00:20:03 +0000342 }
343 }
344
345 return *T;
346}
347
348bool Generic_GCC::IsMathErrnoDefault() const {
349 return true;
350}
351
352bool Generic_GCC::IsUnwindTablesDefault() const {
Daniel Dunbar8eddb3f2009-03-20 00:57:52 +0000353 // FIXME: Gross; we should probably have some separate target
354 // definition, possibly even reusing the one in clang.
Daniel Dunbar39176082009-03-20 00:20:03 +0000355 return getArchName() == "x86_64";
356}
357
358const char *Generic_GCC::GetDefaultRelocationModel() const {
359 return "static";
360}
361
362const char *Generic_GCC::GetForcedPicModel() const {
363 return 0;
364}
Daniel Dunbarf3cad362009-03-25 04:13:45 +0000365
366DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
367 return new DerivedArgList(Args, true);
368}