blob: d342010062c91b15e030f2852c3df029b8c4a7fa [file] [log] [blame]
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001//===--- Tools.cpp - Tools 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 "Tools.h"
11
Daniel Dunbar1d460332009-03-18 10:01:51 +000012#include "clang/Driver/Action.h"
Daniel Dunbar871adcf2009-03-18 07:06:02 +000013#include "clang/Driver/Arg.h"
Daniel Dunbarb488c1d2009-03-18 08:07:30 +000014#include "clang/Driver/ArgList.h"
Daniel Dunbaree848a72009-10-29 02:39:57 +000015#include "clang/Driver/Driver.h"
16#include "clang/Driver/DriverDiagnostic.h"
Daniel Dunbar871adcf2009-03-18 07:06:02 +000017#include "clang/Driver/Compilation.h"
18#include "clang/Driver/Job.h"
Daniel Dunbarb488c1d2009-03-18 08:07:30 +000019#include "clang/Driver/HostInfo.h"
20#include "clang/Driver/Option.h"
21#include "clang/Driver/ToolChain.h"
Daniel Dunbar871adcf2009-03-18 07:06:02 +000022#include "clang/Driver/Util.h"
23
Daniel Dunbar88137642009-09-09 22:32:48 +000024#include "llvm/ADT/SmallString.h"
Douglas Gregor55d3f7a2009-10-29 00:41:01 +000025#include "llvm/ADT/StringSwitch.h"
Daniel Dunbar5b750fe2009-09-09 22:32:34 +000026#include "llvm/ADT/Twine.h"
Daniel Dunbar02633b52009-03-26 16:23:12 +000027#include "llvm/Support/Format.h"
28#include "llvm/Support/raw_ostream.h"
Daniel Dunbar871adcf2009-03-18 07:06:02 +000029
30#include "InputInfo.h"
Daniel Dunbar02633b52009-03-26 16:23:12 +000031#include "ToolChains.h"
Daniel Dunbar871adcf2009-03-18 07:06:02 +000032
Daniel Dunbar47ac7d22009-03-18 06:00:36 +000033using namespace clang::driver;
34using namespace clang::driver::tools;
35
Daniel Dunbar88a3d6c2009-09-10 01:21:05 +000036/// CheckPreprocessingOptions - Perform some validation of preprocessing
37/// arguments that is shared with gcc.
38static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
39 if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
40 if (!Args.hasArg(options::OPT_E))
41 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
42 << A->getAsString(Args) << "-E";
43}
44
Daniel Dunbare2fd6642009-09-10 01:21:12 +000045/// CheckCodeGenerationOptions - Perform some validation of code generation
46/// arguments that is shared with gcc.
47static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
48 // In gcc, only ARM checks this, but it seems reasonable to check universally.
49 if (Args.hasArg(options::OPT_static))
50 if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
51 options::OPT_mdynamic_no_pic))
52 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
53 << A->getAsString(Args) << "-static";
54}
55
Mike Stump1eb44332009-09-09 15:08:12 +000056void Clang::AddPreprocessingOptions(const Driver &D,
Douglas Gregordf91ef32009-04-18 00:34:01 +000057 const ArgList &Args,
Daniel Dunbarc21c4852009-04-08 23:54:23 +000058 ArgStringList &CmdArgs,
59 const InputInfo &Output,
60 const InputInfoList &Inputs) const {
Daniel Dunbarc21c4852009-04-08 23:54:23 +000061 Arg *A;
Daniel Dunbar3a183d32009-06-08 21:48:20 +000062
Daniel Dunbar88a3d6c2009-09-10 01:21:05 +000063 CheckPreprocessingOptions(D, Args);
64
65 Args.AddLastArg(CmdArgs, options::OPT_C);
66 Args.AddLastArg(CmdArgs, options::OPT_CC);
Daniel Dunbar3a183d32009-06-08 21:48:20 +000067
68 // Handle dependency file generation.
Daniel Dunbarc21c4852009-04-08 23:54:23 +000069 if ((A = Args.getLastArg(options::OPT_M)) ||
70 (A = Args.getLastArg(options::OPT_MM)) ||
71 (A = Args.getLastArg(options::OPT_MD)) ||
72 (A = Args.getLastArg(options::OPT_MMD))) {
73 // Determine the output location.
74 const char *DepFile;
75 if (Output.getType() == types::TY_Dependencies) {
76 if (Output.isPipe())
77 DepFile = "-";
78 else
79 DepFile = Output.getFilename();
80 } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
81 DepFile = MF->getValue(Args);
82 } else if (A->getOption().getId() == options::OPT_M ||
83 A->getOption().getId() == options::OPT_MM) {
84 DepFile = "-";
85 } else {
86 DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
87 }
88 CmdArgs.push_back("-dependency-file");
89 CmdArgs.push_back(DepFile);
90
91 // Add an -MT option if the user didn't specify their own.
Daniel Dunbare0be8b12009-09-08 16:39:16 +000092 //
Daniel Dunbarc21c4852009-04-08 23:54:23 +000093 // FIXME: This should use -MQ, when we support it.
94 if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
95 const char *DepTarget;
96
97 // If user provided -o, that is the dependency target, except
98 // when we are only generating a dependency file.
99 Arg *OutputOpt = Args.getLastArg(options::OPT_o);
100 if (OutputOpt && Output.getType() != types::TY_Dependencies) {
101 DepTarget = OutputOpt->getValue(Args);
102 } else {
103 // Otherwise derive from the base input.
104 //
105 // FIXME: This should use the computed output file location.
106 llvm::sys::Path P(Inputs[0].getBaseInput());
107
108 P.eraseSuffix();
109 P.appendSuffix("o");
Daniel Dunbar88137642009-09-09 22:32:48 +0000110 DepTarget = Args.MakeArgString(P.getLast());
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000111 }
112
113 CmdArgs.push_back("-MT");
114 CmdArgs.push_back(DepTarget);
115 }
116
117 if (A->getOption().getId() == options::OPT_M ||
118 A->getOption().getId() == options::OPT_MD)
119 CmdArgs.push_back("-sys-header-deps");
120 }
121
122 Args.AddLastArg(CmdArgs, options::OPT_MP);
123 Args.AddAllArgs(CmdArgs, options::OPT_MT);
124
Douglas Gregordf91ef32009-04-18 00:34:01 +0000125 // Add -i* options, and automatically translate to
126 // -include-pch/-include-pth for transparent PCH support. It's
127 // wonky, but we include looking for .gch so we can support seamless
128 // replacement into a build system already set up to be generating
129 // .gch files.
Daniel Dunbare0be8b12009-09-08 16:39:16 +0000130 //
131 // FIXME: Use iterator.
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000132 for (ArgList::const_iterator
133 it = Args.begin(), ie = Args.end(); it != ie; ++it) {
134 const Arg *A = *it;
135 if (!A->getOption().matches(options::OPT_clang_i_Group))
136 continue;
137
138 if (A->getOption().matches(options::OPT_include)) {
Daniel Dunbar0ebd9322009-10-15 20:02:44 +0000139 // Use PCH if the user requested it, except for C++ (for now).
140 bool UsePCH = D.CCCUsePCH;
141 if (types::isCXX(Inputs[0].getType()))
142 UsePCH = false;
143
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000144 bool FoundPTH = false;
Douglas Gregordf91ef32009-04-18 00:34:01 +0000145 bool FoundPCH = false;
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000146 llvm::sys::Path P(A->getValue(Args));
Daniel Dunbar0ebd9322009-10-15 20:02:44 +0000147 if (UsePCH) {
Douglas Gregordf91ef32009-04-18 00:34:01 +0000148 P.appendSuffix("pch");
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000149 if (P.exists())
Douglas Gregordf91ef32009-04-18 00:34:01 +0000150 FoundPCH = true;
Mike Stump1eb44332009-09-09 15:08:12 +0000151 else
Douglas Gregordf91ef32009-04-18 00:34:01 +0000152 P.eraseSuffix();
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000153 }
154
Douglas Gregordf91ef32009-04-18 00:34:01 +0000155 if (!FoundPCH) {
156 P.appendSuffix("pth");
Mike Stump1eb44332009-09-09 15:08:12 +0000157 if (P.exists())
Douglas Gregordf91ef32009-04-18 00:34:01 +0000158 FoundPTH = true;
159 else
160 P.eraseSuffix();
Mike Stump1eb44332009-09-09 15:08:12 +0000161 }
162
Douglas Gregordf91ef32009-04-18 00:34:01 +0000163 if (!FoundPCH && !FoundPTH) {
164 P.appendSuffix("gch");
165 if (P.exists()) {
Daniel Dunbar0ebd9322009-10-15 20:02:44 +0000166 FoundPCH = UsePCH;
167 FoundPTH = !UsePCH;
Douglas Gregordf91ef32009-04-18 00:34:01 +0000168 }
Mike Stump1eb44332009-09-09 15:08:12 +0000169 else
Douglas Gregordf91ef32009-04-18 00:34:01 +0000170 P.eraseSuffix();
171 }
172
173 if (FoundPCH || FoundPTH) {
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000174 A->claim();
Daniel Dunbar0ebd9322009-10-15 20:02:44 +0000175 if (UsePCH)
Douglas Gregordf91ef32009-04-18 00:34:01 +0000176 CmdArgs.push_back("-include-pch");
177 else
178 CmdArgs.push_back("-include-pth");
Daniel Dunbar88137642009-09-09 22:32:48 +0000179 CmdArgs.push_back(Args.MakeArgString(P.str()));
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000180 continue;
181 }
182 }
183
184 // Not translated, render as usual.
185 A->claim();
186 A->render(Args, CmdArgs);
187 }
188
189 Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
190 Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
191
192 // Add -Wp, and -Xassembler if using the preprocessor.
193
194 // FIXME: There is a very unfortunate problem here, some troubled
195 // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
196 // really support that we would have to parse and then translate
197 // those options. :(
198 Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
199 options::OPT_Xpreprocessor);
Daniel Dunbar607d7f62009-10-29 01:53:44 +0000200
201 // -I- is a deprecated GCC feature, reject it.
202 if (Arg *A = Args.getLastArg(options::OPT_I_))
203 D.Diag(clang::diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000204}
205
Daniel Dunbar728a5122009-09-10 06:49:20 +0000206/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
207//
208// FIXME: tblgen this.
Daniel Dunbarb163ef72009-09-10 04:57:17 +0000209static llvm::StringRef getARMTargetCPU(const ArgList &Args) {
Daniel Dunbar728a5122009-09-10 06:49:20 +0000210 // FIXME: Warn on inconsistent use of -mcpu and -march.
Daniel Dunbarb163ef72009-09-10 04:57:17 +0000211
212 // If we have -mcpu=, use that.
213 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
214 return A->getValue(Args);
215
216 // Otherwise, if we have -march= choose the base CPU for that arch.
217 if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
218 llvm::StringRef MArch = A->getValue(Args);
219
220 if (MArch == "armv2" || MArch == "armv2a")
221 return "arm2";
222 if (MArch == "armv3")
223 return "arm6";
224 if (MArch == "armv3m")
225 return "arm7m";
226 if (MArch == "armv4" || MArch == "armv4t")
227 return "arm7tdmi";
228 if (MArch == "armv5" || MArch == "armv5t")
229 return "arm10tdmi";
230 if (MArch == "armv5e" || MArch == "armv5te")
231 return "arm1026ejs";
232 if (MArch == "armv5tej")
233 return "arm926ejs";
234 if (MArch == "armv6" || MArch == "armv6k")
235 return "arm1136jf-s";
236 if (MArch == "armv6j")
237 return "arm1136j-s";
238 if (MArch == "armv6z" || MArch == "armv6zk")
239 return "arm1176jzf-s";
240 if (MArch == "armv6t2")
241 return "arm1156t2-s";
242 if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
243 return "cortex-a8";
244 if (MArch == "armv7r" || MArch == "armv7-r")
245 return "cortex-r4";
246 if (MArch == "armv7m" || MArch == "armv7-m")
247 return "cortex-m3";
248 if (MArch == "ep9312")
249 return "ep9312";
250 if (MArch == "iwmmxt")
251 return "iwmmxt";
252 if (MArch == "xscale")
253 return "xscale";
254 }
255
256 // Otherwise return the most base CPU LLVM supports.
257 return "arm7tdmi";
258}
259
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000260/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
Daniel Dunbar728a5122009-09-10 06:49:20 +0000261/// CPU.
262//
263// FIXME: This is redundant with -mcpu, why does LLVM use this.
264// FIXME: tblgen this, or kill it!
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000265static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
Daniel Dunbar728a5122009-09-10 06:49:20 +0000266 if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" ||
267 CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" ||
268 CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" ||
269 CPU == "arm940t" || CPU == "ep9312")
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000270 return "v4t";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000271
272 if (CPU == "arm10tdmi" || CPU == "arm1020t")
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000273 return "v5";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000274
275 if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" ||
276 CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" ||
277 CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" ||
278 CPU == "iwmmxt")
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000279 return "v5e";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000280
281 if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" ||
282 CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore")
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000283 return "v6";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000284
285 if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s")
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000286 return "v6t2";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000287
288 if (CPU == "cortex-a8" || CPU == "cortex-a9")
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000289 return "v7";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000290
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000291 return "";
Daniel Dunbar728a5122009-09-10 06:49:20 +0000292}
293
294/// getLLVMTriple - Get the LLVM triple to use for a particular toolchain, which
295/// may depend on command line arguments.
296static std::string getLLVMTriple(const ToolChain &TC, const ArgList &Args) {
297 switch (TC.getTriple().getArch()) {
298 default:
299 return TC.getTripleString();
300
301 case llvm::Triple::arm:
302 case llvm::Triple::thumb: {
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +0000303 // FIXME: Factor into subclasses.
Daniel Dunbar728a5122009-09-10 06:49:20 +0000304 llvm::Triple Triple = TC.getTriple();
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +0000305
306 // Thumb2 is the default for V7 on Darwin.
307 //
308 // FIXME: Thumb should just be another -target-feaure, not in the triple.
309 llvm::StringRef Suffix = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
310 bool ThumbDefault =
311 (Suffix == "v7" && TC.getTriple().getOS() == llvm::Triple::Darwin);
Daniel Dunbar1d65e4b2009-09-10 22:59:51 +0000312 std::string ArchName = "arm";
Daniel Dunbarf4aa4f612009-09-11 01:14:50 +0000313 if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
314 ArchName = "thumb";
315 Triple.setArchName(ArchName + Suffix.str());
316
Daniel Dunbar728a5122009-09-10 06:49:20 +0000317 return Triple.getTriple();
318 }
319 }
320}
321
Daniel Dunbarb163ef72009-09-10 04:57:17 +0000322void Clang::AddARMTargetArgs(const ArgList &Args,
323 ArgStringList &CmdArgs) const {
Daniel Dunbarcbd19332009-09-10 23:00:09 +0000324 const Driver &D = getToolChain().getHost().getDriver();
325
Daniel Dunbar2030d8f2009-09-14 00:34:46 +0000326 // Select the ABI to use.
327 //
328 // FIXME: Support -meabi.
329 const char *ABIName = 0;
330 if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
331 ABIName = A->getValue(Args);
332 } else {
333 // Select the default based on the platform.
334 switch (getToolChain().getTriple().getOS()) {
335 // FIXME: Is this right for non-Darwin and non-Linux?
336 default:
337 ABIName = "aapcs";
338 break;
339
340 case llvm::Triple::Darwin:
341 ABIName = "apcs-gnu";
342 break;
343
344 case llvm::Triple::Linux:
345 ABIName = "aapcs-linux";
346 break;
347 }
348 }
349 CmdArgs.push_back("-target-abi");
350 CmdArgs.push_back(ABIName);
351
Daniel Dunbarb163ef72009-09-10 04:57:17 +0000352 // Set the CPU based on -march= and -mcpu=.
353 CmdArgs.push_back(Args.MakeArgString("-mcpu=" + getARMTargetCPU(Args)));
354
Daniel Dunbarcbd19332009-09-10 23:00:09 +0000355 // Select the float ABI as determined by -msoft-float, -mhard-float, and
356 // -mfloat-abi=.
357 llvm::StringRef FloatABI;
358 if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
359 options::OPT_mhard_float,
360 options::OPT_mfloat_abi_EQ)) {
361 if (A->getOption().matches(options::OPT_msoft_float))
362 FloatABI = "soft";
363 else if (A->getOption().matches(options::OPT_mhard_float))
364 FloatABI = "hard";
365 else {
366 FloatABI = A->getValue(Args);
367 if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
368 D.Diag(clang::diag::err_drv_invalid_mfloat_abi)
369 << A->getAsString(Args);
370 FloatABI = "soft";
371 }
372 }
373 }
374
375 // If unspecified, choose the default based on the platform.
376 if (FloatABI.empty()) {
377 // FIXME: This is wrong for non-Darwin, we don't have a mechanism yet for
378 // distinguishing things like linux-eabi vs linux-elf.
379 switch (getToolChain().getTriple().getOS()) {
380 case llvm::Triple::Darwin: {
381 // Darwin defaults to "softfp" for v6 and v7.
382 //
383 // FIXME: Factor out an ARM class so we can cache the arch somewhere.
384 llvm::StringRef ArchName = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
385 if (ArchName.startswith("v6") || ArchName.startswith("v7"))
386 FloatABI = "softfp";
387 else
388 FloatABI = "soft";
389 break;
390 }
391
392 default:
393 // Assume "soft", but warn the user we are guessing.
394 FloatABI = "soft";
395 D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
396 break;
397 }
398 }
399
400 if (FloatABI == "soft") {
401 // Floating point operations and argument passing are soft.
402 //
403 // FIXME: This changes CPP defines, we need -target-soft-float.
404 CmdArgs.push_back("-soft-float");
405 CmdArgs.push_back("-float-abi=soft");
406 } else if (FloatABI == "softfp") {
407 // Floating point operations are hard, but argument passing is soft.
408 CmdArgs.push_back("-float-abi=soft");
409 } else {
410 // Floating point operations and argument passing are hard.
411 assert(FloatABI == "hard" && "Invalid float abi!");
412 CmdArgs.push_back("-float-abi=hard");
413 }
Daniel Dunbarb163ef72009-09-10 04:57:17 +0000414}
415
Daniel Dunbar6acda162009-09-09 22:33:08 +0000416void Clang::AddX86TargetArgs(const ArgList &Args,
417 ArgStringList &CmdArgs) const {
Daniel Dunbare6ad3f92009-09-10 22:59:57 +0000418 if (!Args.hasFlag(options::OPT_mred_zone,
419 options::OPT_mno_red_zone,
420 true) ||
421 Args.hasArg(options::OPT_mkernel) ||
422 Args.hasArg(options::OPT_fapple_kext))
423 CmdArgs.push_back("--disable-red-zone");
424
Daniel Dunbare6ad3f92009-09-10 22:59:57 +0000425 if (Args.hasFlag(options::OPT_msoft_float,
426 options::OPT_mno_soft_float,
427 false))
428 CmdArgs.push_back("--no-implicit-float");
429
Daniel Dunbar6acda162009-09-09 22:33:08 +0000430 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
431 // FIXME: We may need some translation here from the options gcc takes to
432 // names the LLVM backend understand?
433 CmdArgs.push_back("-mcpu");
434 CmdArgs.push_back(A->getValue(Args));
435 } else {
436 // Select default CPU.
437
438 // FIXME: Need target hooks.
439 if (memcmp(getToolChain().getOS().c_str(), "darwin", 6) == 0) {
440 if (getToolChain().getArchName() == "x86_64")
441 CmdArgs.push_back("--mcpu=core2");
442 else if (getToolChain().getArchName() == "i386")
443 CmdArgs.push_back("--mcpu=yonah");
444 } else {
445 if (getToolChain().getArchName() == "x86_64")
446 CmdArgs.push_back("--mcpu=x86-64");
447 else if (getToolChain().getArchName() == "i386")
448 CmdArgs.push_back("--mcpu=pentium4");
449 }
450 }
451
452 // FIXME: Use iterator.
453 for (ArgList::const_iterator
454 it = Args.begin(), ie = Args.end(); it != ie; ++it) {
455 const Arg *A = *it;
456 if (A->getOption().matches(options::OPT_m_x86_Features_Group)) {
457 llvm::StringRef Name = A->getOption().getName();
458
459 // Skip over "-m".
460 assert(Name.startswith("-m") && "Invalid feature name.");
461 Name = Name.substr(2);
462
463 bool IsNegative = Name.startswith("no-");
464 if (IsNegative)
465 Name = Name.substr(3);
466
467 A->claim();
468 CmdArgs.push_back("-target-feature");
469 CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
470 }
471 }
472}
473
Fariborz Jahanian85caf032009-10-01 20:30:46 +0000474static bool needsExceptions(const ArgList &Args, types::ID InputType,
475 const llvm::Triple &Triple) {
Rafael Espindolaf759df02009-10-01 13:33:33 +0000476 if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
477 options::OPT_fno_exceptions)) {
478 if (A->getOption().matches(options::OPT_fexceptions))
479 return true;
480 else
481 return false;
482 }
483 switch (InputType) {
484 case types::TY_CXX: case types::TY_CXXHeader:
485 case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
486 case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
487 case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
488 return true;
Fariborz Jahanian85caf032009-10-01 20:30:46 +0000489
Rafael Espindolaf759df02009-10-01 13:33:33 +0000490 case types::TY_ObjC: case types::TY_ObjCHeader:
491 case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
492 if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
493 return true;
Fariborz Jahanian85caf032009-10-01 20:30:46 +0000494 if (Triple.getOS() != llvm::Triple::Darwin)
Rafael Espindolaf759df02009-10-01 13:33:33 +0000495 return false;
Fariborz Jahanian85caf032009-10-01 20:30:46 +0000496 return (Triple.getDarwinMajorNumber() >= 9 &&
497 Triple.getArch() == llvm::Triple::x86_64);
498
Rafael Espindolaf759df02009-10-01 13:33:33 +0000499 default:
500 return false;
501 }
502}
503
Daniel Dunbar47ac7d22009-03-18 06:00:36 +0000504void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbar871adcf2009-03-18 07:06:02 +0000505 Job &Dest,
506 const InputInfo &Output,
Daniel Dunbar62cf6012009-03-18 06:07:59 +0000507 const InputInfoList &Inputs,
Daniel Dunbar1d460332009-03-18 10:01:51 +0000508 const ArgList &Args,
Daniel Dunbar47ac7d22009-03-18 06:00:36 +0000509 const char *LinkingOutput) const {
Daniel Dunbar5c1aaaf2009-04-07 19:18:24 +0000510 const Driver &D = getToolChain().getHost().getDriver();
Daniel Dunbarb488c1d2009-03-18 08:07:30 +0000511 ArgStringList CmdArgs;
512
Daniel Dunbar077ba6a2009-03-31 20:53:55 +0000513 assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
514
Daniel Dunbaraf07f932009-03-31 17:35:15 +0000515 CmdArgs.push_back("-triple");
Daniel Dunbar728a5122009-09-10 06:49:20 +0000516
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000517 const char *TripleStr =
Daniel Dunbar728a5122009-09-10 06:49:20 +0000518 Args.MakeArgString(getLLVMTriple(getToolChain(), Args));
Daniel Dunbaraf07f932009-03-31 17:35:15 +0000519 CmdArgs.push_back(TripleStr);
520
Daniel Dunbar1d460332009-03-18 10:01:51 +0000521 if (isa<AnalyzeJobAction>(JA)) {
522 assert(JA.getType() == types::TY_Plist && "Invalid output type.");
523 CmdArgs.push_back("-analyze");
524 } else if (isa<PreprocessJobAction>(JA)) {
Daniel Dunbarcd8e4c42009-03-30 06:36:42 +0000525 if (Output.getType() == types::TY_Dependencies)
526 CmdArgs.push_back("-Eonly");
527 else
528 CmdArgs.push_back("-E");
Daniel Dunbar1d460332009-03-18 10:01:51 +0000529 } else if (isa<PrecompileJobAction>(JA)) {
Daniel Dunbar0ebd9322009-10-15 20:02:44 +0000530 // Use PCH if the user requested it, except for C++ (for now).
531 bool UsePCH = D.CCCUsePCH;
532 if (types::isCXX(Inputs[0].getType()))
533 UsePCH = false;
534
535 if (UsePCH)
Douglas Gregordf91ef32009-04-18 00:34:01 +0000536 CmdArgs.push_back("-emit-pch");
537 else
538 CmdArgs.push_back("-emit-pth");
Daniel Dunbar1d460332009-03-18 10:01:51 +0000539 } else {
540 assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000541
Daniel Dunbar1d460332009-03-18 10:01:51 +0000542 if (JA.getType() == types::TY_Nothing) {
543 CmdArgs.push_back("-fsyntax-only");
544 } else if (JA.getType() == types::TY_LLVMAsm) {
545 CmdArgs.push_back("-emit-llvm");
546 } else if (JA.getType() == types::TY_LLVMBC) {
547 CmdArgs.push_back("-emit-llvm-bc");
548 } else if (JA.getType() == types::TY_PP_Asm) {
Daniel Dunbare3b8d072009-09-17 00:47:53 +0000549 CmdArgs.push_back("-S");
Daniel Dunbar5915fbf2009-09-01 16:57:46 +0000550 } else if (JA.getType() == types::TY_AST) {
551 CmdArgs.push_back("-emit-pch");
Daniel Dunbar1d460332009-03-18 10:01:51 +0000552 }
Daniel Dunbarb488c1d2009-03-18 08:07:30 +0000553 }
554
Daniel Dunbar1d460332009-03-18 10:01:51 +0000555 // The make clang go fast button.
556 CmdArgs.push_back("-disable-free");
557
Daniel Dunbarc9abc042009-04-08 05:11:16 +0000558 // Set the main file name, so that debug info works even with
559 // -save-temps.
560 CmdArgs.push_back("-main-file-name");
561 CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
562
Daniel Dunbar3bbc7532009-04-08 18:03:55 +0000563 // Some flags which affect the language (via preprocessor
564 // defines). See darwin::CC1::AddCPPArgs.
565 if (Args.hasArg(options::OPT_static))
566 CmdArgs.push_back("-static-define");
567
Daniel Dunbar1d460332009-03-18 10:01:51 +0000568 if (isa<AnalyzeJobAction>(JA)) {
Ted Kremenekb8bb3e72009-09-25 05:55:59 +0000569 // Enable region store model by default.
570 CmdArgs.push_back("-analyzer-store=region");
571
Daniel Dunbar1d460332009-03-18 10:01:51 +0000572 // Add default argument set.
Daniel Dunbard8fc0f22009-05-22 00:38:15 +0000573 if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
574 CmdArgs.push_back("-warn-dead-stores");
Ted Kremenek11727512009-07-24 20:03:11 +0000575 CmdArgs.push_back("-warn-security-syntactic");
Daniel Dunbard8fc0f22009-05-22 00:38:15 +0000576 CmdArgs.push_back("-checker-cfref");
577 CmdArgs.push_back("-analyzer-eagerly-assume");
578 CmdArgs.push_back("-warn-objc-methodsigs");
579 // Do not enable the missing -dealloc check.
580 // '-warn-objc-missing-dealloc',
581 CmdArgs.push_back("-warn-objc-unused-ivars");
582 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000583
Daniel Dunbard8fc0f22009-05-22 00:38:15 +0000584 // Set the output format. The default is plist, for (lame) historical
585 // reasons.
586 CmdArgs.push_back("-analyzer-output");
587 if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
588 CmdArgs.push_back(A->getValue(Args));
589 else
590 CmdArgs.push_back("plist");
Daniel Dunbar1d460332009-03-18 10:01:51 +0000591
592 // Add -Xanalyzer arguments when running as analyzer.
593 Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
Mike Stump1eb44332009-09-09 15:08:12 +0000594 }
595
Daniel Dunbare2fd6642009-09-10 01:21:12 +0000596 CheckCodeGenerationOptions(D, Args);
597
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000598 // Perform argument translation for LLVM backend. This
599 // takes some care in reconciling with llvm-gcc. The
600 // issue is that llvm-gcc translates these options based on
601 // the values in cc1, whereas we are processing based on
602 // the driver arguments.
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000603
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000604 // This comes from the default translation the driver + cc1
605 // would do to enable flag_pic.
606 //
607 // FIXME: Centralize this code.
608 bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
609 Args.hasArg(options::OPT_fpic) ||
610 Args.hasArg(options::OPT_fPIE) ||
611 Args.hasArg(options::OPT_fpie));
612 bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
613 Args.hasArg(options::OPT_static));
614 const char *Model = getToolChain().GetForcedPicModel();
615 if (!Model) {
616 if (Args.hasArg(options::OPT_mdynamic_no_pic))
617 Model = "dynamic-no-pic";
618 else if (PICDisabled)
619 Model = "static";
620 else if (PICEnabled)
621 Model = "pic";
Daniel Dunbar1d460332009-03-18 10:01:51 +0000622 else
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000623 Model = getToolChain().GetDefaultRelocationModel();
Daniel Dunbar1d460332009-03-18 10:01:51 +0000624 }
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000625 CmdArgs.push_back("--relocation-model");
626 CmdArgs.push_back(Model);
627
628 // Infer the __PIC__ value.
629 //
630 // FIXME: This isn't quite right on Darwin, which always sets
631 // __PIC__=2.
632 if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
633 if (Args.hasArg(options::OPT_fPIC))
634 CmdArgs.push_back("-pic-level=2");
635 else
636 CmdArgs.push_back("-pic-level=1");
637 }
638
639 if (Args.hasArg(options::OPT_ftime_report))
640 CmdArgs.push_back("--time-passes");
641 // FIXME: Set --enable-unsafe-fp-math.
Benjamin Kramer21656dd2009-08-05 19:47:38 +0000642 if (Args.hasFlag(options::OPT_fno_omit_frame_pointer,
643 options::OPT_fomit_frame_pointer))
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000644 CmdArgs.push_back("--disable-fp-elim");
645 if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
646 options::OPT_fno_zero_initialized_in_bss,
647 true))
648 CmdArgs.push_back("--nozero-initialized-in-bss");
649 if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm))
650 CmdArgs.push_back("--asm-verbose");
651 if (Args.hasArg(options::OPT_fdebug_pass_structure))
652 CmdArgs.push_back("--debug-pass=Structure");
653 if (Args.hasArg(options::OPT_fdebug_pass_arguments))
654 CmdArgs.push_back("--debug-pass=Arguments");
Daniel Dunbar6bea73b2009-09-16 06:17:29 +0000655
656 // This is a coarse approximation of what llvm-gcc actually does, both
657 // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
658 // complicated ways.
659 bool AsynchronousUnwindTables =
660 Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
661 options::OPT_fno_asynchronous_unwind_tables,
662 getToolChain().IsUnwindTablesDefault() &&
663 !Args.hasArg(options::OPT_mkernel));
664 if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
665 AsynchronousUnwindTables))
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000666 CmdArgs.push_back("--unwind-tables=1");
667 else
668 CmdArgs.push_back("--unwind-tables=0");
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000669
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000670 // FIXME: Handle -mtune=.
671 (void) Args.hasArg(options::OPT_mtune_EQ);
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000672
Benjamin Kramer8e9ef0d2009-08-05 14:30:52 +0000673 if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
674 CmdArgs.push_back("-code-model");
675 CmdArgs.push_back(A->getValue(Args));
676 }
677
Daniel Dunbar6acda162009-09-09 22:33:08 +0000678 // Add target specific cpu and features flags.
679 switch(getToolChain().getTriple().getArch()) {
680 default:
681 break;
Daniel Dunbar868bd0a2009-05-06 03:16:41 +0000682
Daniel Dunbarb163ef72009-09-10 04:57:17 +0000683 case llvm::Triple::arm:
684 case llvm::Triple::thumb:
685 AddARMTargetArgs(Args, CmdArgs);
686 break;
687
Daniel Dunbar6acda162009-09-09 22:33:08 +0000688 case llvm::Triple::x86:
689 case llvm::Triple::x86_64:
690 AddX86TargetArgs(Args, CmdArgs);
691 break;
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000692 }
693
694 if (Args.hasFlag(options::OPT_fmath_errno,
695 options::OPT_fno_math_errno,
696 getToolChain().IsMathErrnoDefault()))
697 CmdArgs.push_back("--fmath-errno=1");
698 else
699 CmdArgs.push_back("--fmath-errno=0");
700
701 if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
702 CmdArgs.push_back("--limit-float-precision");
703 CmdArgs.push_back(A->getValue(Args));
704 }
705
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000706 Arg *Unsupported;
707 if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
Daniel Dunbar95a0da72009-05-13 19:05:04 +0000708 (Unsupported = Args.getLastArg(options::OPT_MQ)) ||
709 (Unsupported = Args.getLastArg(options::OPT_iframework)))
Daniel Dunbare027a4b2009-05-22 19:02:20 +0000710 D.Diag(clang::diag::err_drv_clang_unsupported)
Daniel Dunbarbc85be82009-04-29 18:32:25 +0000711 << Unsupported->getOption().getName();
Daniel Dunbar1d460332009-03-18 10:01:51 +0000712
713 Args.AddAllArgs(CmdArgs, options::OPT_v);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000714 Args.AddLastArg(CmdArgs, options::OPT_P);
Daniel Dunbar2ac9fc22009-04-07 21:42:00 +0000715 Args.AddLastArg(CmdArgs, options::OPT_mmacosx_version_min_EQ);
Daniel Dunbarff8857a2009-04-10 20:11:50 +0000716 Args.AddLastArg(CmdArgs, options::OPT_miphoneos_version_min_EQ);
Mike Stump1eb44332009-09-09 15:08:12 +0000717 Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000718
719 // Special case debug options to only pass -g to clang. This is
720 // wrong.
721 if (Args.hasArg(options::OPT_g_Group))
722 CmdArgs.push_back("-g");
723
724 Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
Rafael Espindola8d737cc2009-10-26 13:36:57 +0000725 Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000726
Daniel Dunbar2ac9fc22009-04-07 21:42:00 +0000727 Args.AddLastArg(CmdArgs, options::OPT_isysroot);
728
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000729 // Add preprocessing options like -I, -D, etc. if we are using the
730 // preprocessor.
731 //
732 // FIXME: Support -fpreprocessed
733 types::ID InputType = Inputs[0].getType();
734 if (types::getPreprocessedType(InputType) != types::TY_INVALID)
Douglas Gregordf91ef32009-04-18 00:34:01 +0000735 AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000736
Daniel Dunbar20f0eac2009-09-17 06:53:36 +0000737 // Manually translate -O to -O2 and -O4 to -O3; let clang reject
Daniel Dunbar337a6272009-03-24 20:17:30 +0000738 // others.
739 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000740 if (A->getOption().getId() == options::OPT_O4)
Daniel Dunbar337a6272009-03-24 20:17:30 +0000741 CmdArgs.push_back("-O3");
742 else if (A->getValue(Args)[0] == '\0')
Daniel Dunbar20f0eac2009-09-17 06:53:36 +0000743 CmdArgs.push_back("-O2");
Daniel Dunbar1d460332009-03-18 10:01:51 +0000744 else
Daniel Dunbar5697aa02009-03-18 23:39:35 +0000745 A->render(Args, CmdArgs);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000746 }
747
Daniel Dunbar6e8371e2009-10-29 02:24:45 +0000748 Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
749 Args.AddLastArg(CmdArgs, options::OPT_pedantic);
750 Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000751 Args.AddLastArg(CmdArgs, options::OPT_w);
Daniel Dunbard573d262009-04-07 22:13:21 +0000752
753 // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
754 // (-ansi is equivalent to -std=c89).
755 //
756 // If a std is supplied, only add -trigraphs if it follows the
757 // option.
758 if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
759 if (Std->getOption().matches(options::OPT_ansi))
Nuno Lopes528365d2009-10-16 14:28:06 +0000760 if (types::isCXX(InputType))
761 CmdArgs.push_back("-std=c++98");
762 else
763 CmdArgs.push_back("-std=c89");
Daniel Dunbard573d262009-04-07 22:13:21 +0000764 else
765 Std->render(Args, CmdArgs);
766
767 if (Arg *A = Args.getLastArg(options::OPT_trigraphs))
768 if (A->getIndex() > Std->getIndex())
769 A->render(Args, CmdArgs);
Daniel Dunbara3ff2022009-04-26 01:10:38 +0000770 } else {
771 // Honor -std-default.
772 Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
773 "-std=", /*Joined=*/true);
Daniel Dunbard573d262009-04-07 22:13:21 +0000774 Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
Daniel Dunbara3ff2022009-04-26 01:10:38 +0000775 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000776
Daniel Dunbar1d460332009-03-18 10:01:51 +0000777 if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
778 CmdArgs.push_back("-ftemplate-depth");
779 CmdArgs.push_back(A->getValue(Args));
780 }
781
Douglas Gregore650c8c2009-07-07 00:12:59 +0000782 if (Args.hasArg(options::OPT__relocatable_pch, true))
783 CmdArgs.push_back("--relocatable-pch");
Mike Stump1eb44332009-09-09 15:08:12 +0000784
David Chisnall8a5a9aa2009-08-31 16:41:57 +0000785 if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
786 CmdArgs.push_back("-fconstant-string-class");
787 CmdArgs.push_back(A->getValue(Args));
788 }
789
Daniel Dunbar48d1ef72009-04-07 21:16:11 +0000790 // Forward -f options which we can pass directly.
Daniel Dunbar3aaf0822009-04-07 21:51:40 +0000791 Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
Daniel Dunbar3aaf0822009-04-07 21:51:40 +0000792 Args.AddLastArg(CmdArgs, options::OPT_ffreestanding);
793 Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
794 Args.AddLastArg(CmdArgs, options::OPT_fgnu_runtime);
795 Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions);
Douglas Gregorfffd93f2009-05-01 21:53:04 +0000796 Args.AddLastArg(CmdArgs, options::OPT_fmessage_length_EQ);
Daniel Dunbar3aaf0822009-04-07 21:51:40 +0000797 Args.AddLastArg(CmdArgs, options::OPT_fms_extensions);
798 Args.AddLastArg(CmdArgs, options::OPT_fnext_runtime);
799 Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics);
800 Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
801 Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only);
802 Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
Fariborz Jahanian34e65772009-05-22 20:17:16 +0000803 Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
Daniel Dunbar3aaf0822009-04-07 21:51:40 +0000804 // FIXME: Should we remove this?
805 Args.AddLastArg(CmdArgs, options::OPT_fobjc_nonfragile_abi);
Daniel Dunbard6884a02009-05-04 05:16:21 +0000806 Args.AddLastArg(CmdArgs, options::OPT_fobjc_tight_layout);
Chris Lattner182e0922009-04-21 05:34:31 +0000807 Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
Daniel Dunbar3aaf0822009-04-07 21:51:40 +0000808 Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
809 Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
810 Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
811 Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000812
Daniel Dunbar5345c392009-09-03 04:54:28 +0000813 Args.AddLastArg(CmdArgs, options::OPT_pthread);
814
Bill Wendling45483f72009-06-28 07:36:13 +0000815 // Forward stack protector flags.
816 if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
817 options::OPT_fstack_protector_all,
818 options::OPT_fstack_protector)) {
819 if (A->getOption().matches(options::OPT_fno_stack_protector))
820 CmdArgs.push_back("--stack-protector=0");
821 else if (A->getOption().matches(options::OPT_fstack_protector))
822 CmdArgs.push_back("--stack-protector=1");
823 else
824 CmdArgs.push_back("--stack-protector=2");
825 }
826
Daniel Dunbar48d1ef72009-04-07 21:16:11 +0000827 // Forward -f options with positive and negative forms; we translate
828 // these by hand.
829
830 // -fbuiltin is default, only pass non-default.
831 if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
832 CmdArgs.push_back("-fbuiltin=0");
833
Daniel Dunbar7695fba2009-04-19 21:20:32 +0000834 // -fblocks default varies depending on platform and language; only
835 // pass if specified.
Daniel Dunbar48d1ef72009-04-07 21:16:11 +0000836 if (Arg *A = Args.getLastArg(options::OPT_fblocks, options::OPT_fno_blocks)) {
837 if (A->getOption().matches(options::OPT_fblocks))
838 CmdArgs.push_back("-fblocks");
839 else
840 CmdArgs.push_back("-fblocks=0");
841 }
842
Fariborz Jahanian85caf032009-10-01 20:30:46 +0000843 if (needsExceptions(Args, InputType, getToolChain().getTriple()))
Rafael Espindolaf759df02009-10-01 13:33:33 +0000844 CmdArgs.push_back("-fexceptions");
845 else
846 CmdArgs.push_back("-fexceptions=0");
Mike Stump738f8c22009-07-31 23:15:31 +0000847
848 // -frtti is default, only pass non-default.
849 if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
850 CmdArgs.push_back("-frtti=0");
851
Eli Friedman5a779732009-06-05 07:21:14 +0000852 // -fsigned-char/-funsigned-char default varies depending on platform; only
853 // pass if specified.
854 if (Arg *A = Args.getLastArg(options::OPT_fsigned_char,
855 options::OPT_funsigned_char)) {
856 if (A->getOption().matches(options::OPT_fsigned_char))
857 CmdArgs.push_back("-fsigned-char");
858 else
859 CmdArgs.push_back("-fsigned-char=0");
860 }
861
Daniel Dunbaree848a72009-10-29 02:39:57 +0000862 // -fno-pascal-strings is default, only pass non-default. If the tool chain
863 // happened to translate to -mpascal-strings, we want to back translate here.
Daniel Dunbar82d00682009-04-07 23:51:44 +0000864 //
865 // FIXME: This is gross; that translation should be pulled from the
866 // tool chain.
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000867 if (Args.hasFlag(options::OPT_fpascal_strings,
Daniel Dunbar82d00682009-04-07 23:51:44 +0000868 options::OPT_fno_pascal_strings,
869 false) ||
870 Args.hasFlag(options::OPT_mpascal_strings,
871 options::OPT_mno_pascal_strings,
872 false))
Daniel Dunbar48d1ef72009-04-07 21:16:11 +0000873 CmdArgs.push_back("-fpascal-strings");
874
875 // -fcommon is default, only pass non-default.
876 if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
877 CmdArgs.push_back("-fno-common");
878
Daniel Dunbar70d3c922009-04-15 02:37:43 +0000879 // -fsigned-bitfields is default, and clang doesn't yet support
880 // --funsigned-bitfields.
Mike Stump1eb44332009-09-09 15:08:12 +0000881 if (!Args.hasFlag(options::OPT_fsigned_bitfields,
Daniel Dunbar70d3c922009-04-15 02:37:43 +0000882 options::OPT_funsigned_bitfields))
883 D.Diag(clang::diag::warn_drv_clang_unsupported)
884 << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
885
Daniel Dunbar49138fc2009-04-19 21:09:34 +0000886 // -fdiagnostics-fixit-info is default, only pass non-default.
Mike Stump1eb44332009-09-09 15:08:12 +0000887 if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
Daniel Dunbar49138fc2009-04-19 21:09:34 +0000888 options::OPT_fno_diagnostics_fixit_info))
889 CmdArgs.push_back("-fno-diagnostics-fixit-info");
890
Daniel Dunbar9e820ee2009-04-16 06:32:38 +0000891 // Enable -fdiagnostics-show-option by default.
Mike Stump1eb44332009-09-09 15:08:12 +0000892 if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
Daniel Dunbar9e820ee2009-04-16 06:32:38 +0000893 options::OPT_fno_diagnostics_show_option))
894 CmdArgs.push_back("-fdiagnostics-show-option");
Torok Edwina46c71a2009-06-04 07:27:53 +0000895 if (!Args.hasFlag(options::OPT_fcolor_diagnostics,
Daniel Dunbar75eb1d62009-06-08 21:13:54 +0000896 options::OPT_fno_color_diagnostics))
Torok Edwina46c71a2009-06-04 07:27:53 +0000897 CmdArgs.push_back("-fno-color-diagnostics");
Daniel Dunbar75eb1d62009-06-08 21:13:54 +0000898 if (!Args.hasFlag(options::OPT_fshow_source_location,
899 options::OPT_fno_show_source_location))
900 CmdArgs.push_back("-fno-show-source-location");
Daniel Dunbar9e820ee2009-04-16 06:32:38 +0000901
Daniel Dunbar7695fba2009-04-19 21:20:32 +0000902 // -fdollars-in-identifiers default varies depending on platform and
903 // language; only pass if specified.
Mike Stump1eb44332009-09-09 15:08:12 +0000904 if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
Daniel Dunbar7695fba2009-04-19 21:20:32 +0000905 options::OPT_fno_dollars_in_identifiers)) {
906 if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
907 CmdArgs.push_back("-fdollars-in-identifiers=1");
908 else
909 CmdArgs.push_back("-fdollars-in-identifiers=0");
910 }
911
Daniel Dunbare027a4b2009-05-22 19:02:20 +0000912 // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
913 // practical purposes.
Mike Stump1eb44332009-09-09 15:08:12 +0000914 if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
Daniel Dunbare027a4b2009-05-22 19:02:20 +0000915 options::OPT_fno_unit_at_a_time)) {
916 if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
Edward O'Callaghanc3769102009-10-13 16:41:34 +0000917 D.Diag(clang::diag::warn_drv_clang_unsupported) << A->getAsString(Args);
Daniel Dunbare027a4b2009-05-22 19:02:20 +0000918 }
Eli Friedmanceb5c5b2009-07-14 21:58:17 +0000919
Daniel Dunbar2ba91572009-09-10 03:37:02 +0000920 // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
Daniel Dunbarf84a4a42009-09-10 04:57:27 +0000921 //
922 // FIXME: This is disabled until clang-cc supports -fno-builtin-foo. PR4941.
923#if 0
Daniel Dunbar2ba91572009-09-10 03:37:02 +0000924 if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
925 (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
926 getToolChain().getTriple().getArch() == llvm::Triple::thumb)) {
927 if (!Args.hasArg(options::OPT_fbuiltin_strcat))
928 CmdArgs.push_back("-fno-builtin-strcat");
929 if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
930 CmdArgs.push_back("-fno-builtin-strcpy");
931 }
Daniel Dunbarf84a4a42009-09-10 04:57:27 +0000932#endif
Daniel Dunbar2ba91572009-09-10 03:37:02 +0000933
Mike Stump1eb44332009-09-09 15:08:12 +0000934 if (Arg *A = Args.getLastArg(options::OPT_traditional,
Eli Friedmanceb5c5b2009-07-14 21:58:17 +0000935 options::OPT_traditional_cpp))
936 D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
937
Daniel Dunbar1d460332009-03-18 10:01:51 +0000938 Args.AddLastArg(CmdArgs, options::OPT_dM);
Chris Lattnerd82df3a2009-04-12 01:56:53 +0000939 Args.AddLastArg(CmdArgs, options::OPT_dD);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000940
941 Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
Daniel Dunbare5280282009-06-03 16:16:27 +0000942 Args.AddAllArgValues(CmdArgs, options::OPT_mllvm);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000943
Daniel Dunbarcd8e4c42009-03-30 06:36:42 +0000944 if (Output.getType() == types::TY_Dependencies) {
945 // Handled with other dependency code.
Daniel Dunbara5a7bd02009-03-30 00:34:04 +0000946 } else if (Output.isPipe()) {
Daniel Dunbarb488c1d2009-03-18 08:07:30 +0000947 CmdArgs.push_back("-o");
948 CmdArgs.push_back("-");
Daniel Dunbar115a7922009-03-19 07:29:38 +0000949 } else if (Output.isFilename()) {
Daniel Dunbarb488c1d2009-03-18 08:07:30 +0000950 CmdArgs.push_back("-o");
Daniel Dunbar115a7922009-03-19 07:29:38 +0000951 CmdArgs.push_back(Output.getFilename());
952 } else {
953 assert(Output.isNothing() && "Invalid output.");
Daniel Dunbarb488c1d2009-03-18 08:07:30 +0000954 }
955
Daniel Dunbar1d460332009-03-18 10:01:51 +0000956 for (InputInfoList::const_iterator
957 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
958 const InputInfo &II = *it;
959 CmdArgs.push_back("-x");
960 CmdArgs.push_back(types::getTypeName(II.getType()));
961 if (II.isPipe())
962 CmdArgs.push_back("-");
Daniel Dunbar115a7922009-03-19 07:29:38 +0000963 else if (II.isFilename())
964 CmdArgs.push_back(II.getFilename());
Daniel Dunbar1d460332009-03-18 10:01:51 +0000965 else
Daniel Dunbar115a7922009-03-19 07:29:38 +0000966 II.getInputArg().renderAsInput(Args, CmdArgs);
Daniel Dunbar1d460332009-03-18 10:01:51 +0000967 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000968
969 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +0000970 Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +0000971 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbara880db02009-03-23 19:03:36 +0000972
Daniel Dunbar5c1aaaf2009-04-07 19:18:24 +0000973 // Explicitly warn that these options are unsupported, even though
974 // we are allowing compilation to continue.
975 // FIXME: Use iterator.
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000976 for (ArgList::const_iterator
Daniel Dunbar5c1aaaf2009-04-07 19:18:24 +0000977 it = Args.begin(), ie = Args.end(); it != ie; ++it) {
978 const Arg *A = *it;
979 if (A->getOption().matches(options::OPT_pg)) {
980 A->claim();
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000981 D.Diag(clang::diag::warn_drv_clang_unsupported)
Daniel Dunbar5c1aaaf2009-04-07 19:18:24 +0000982 << A->getAsString(Args);
983 }
984 }
985
Daniel Dunbar68fb4692009-04-03 20:51:31 +0000986 // Claim some arguments which clang supports automatically.
987
988 // -fpch-preprocess is used with gcc to add a special marker in the
989 // -output to include the PCH file. Clang's PTH solution is
990 // -completely transparent, so we do not need to deal with it at
991 // -all.
992 Args.ClaimAllArgs(options::OPT_fpch_preprocess);
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000993
Daniel Dunbara880db02009-03-23 19:03:36 +0000994 // Claim some arguments which clang doesn't support, but we don't
995 // care to warn the user about.
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000996
Daniel Dunbara880db02009-03-23 19:03:36 +0000997 // FIXME: Use iterator.
Daniel Dunbarc21c4852009-04-08 23:54:23 +0000998 for (ArgList::const_iterator
Daniel Dunbara880db02009-03-23 19:03:36 +0000999 it = Args.begin(), ie = Args.end(); it != ie; ++it) {
1000 const Arg *A = *it;
Daniel Dunbar06ef3c32009-04-16 03:44:10 +00001001 if (A->getOption().matches(options::OPT_clang_ignored_f_Group) ||
Daniel Dunbar16fd3a92009-04-07 02:59:27 +00001002 A->getOption().matches(options::OPT_clang_ignored_m_Group))
Daniel Dunbara880db02009-03-23 19:03:36 +00001003 A->claim();
1004 }
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001005}
1006
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001007void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
1008 Job &Dest,
1009 const InputInfo &Output,
1010 const InputInfoList &Inputs,
Daniel Dunbar1d460332009-03-18 10:01:51 +00001011 const ArgList &Args,
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001012 const char *LinkingOutput) const {
Daniel Dunbara8304f62009-05-02 20:14:53 +00001013 const Driver &D = getToolChain().getHost().getDriver();
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001014 ArgStringList CmdArgs;
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001015
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001016 for (ArgList::const_iterator
Daniel Dunbar1d460332009-03-18 10:01:51 +00001017 it = Args.begin(), ie = Args.end(); it != ie; ++it) {
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001018 Arg *A = *it;
Daniel Dunbar75877192009-03-19 07:55:12 +00001019 if (A->getOption().hasForwardToGCC()) {
1020 // It is unfortunate that we have to claim here, as this means
1021 // we will basically never report anything interesting for
Daniel Dunbar6ecc7a92009-05-02 21:41:52 +00001022 // platforms using a generic gcc, even if we are just using gcc
1023 // to get to the assembler.
Daniel Dunbar75877192009-03-19 07:55:12 +00001024 A->claim();
Daniel Dunbar1d460332009-03-18 10:01:51 +00001025 A->render(Args, CmdArgs);
Daniel Dunbar75877192009-03-19 07:55:12 +00001026 }
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001027 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001028
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001029 RenderExtraToolArgs(CmdArgs);
1030
1031 // If using a driver driver, force the arch.
Daniel Dunbar7cfe31a2009-05-22 02:21:04 +00001032 const std::string &Arch = getToolChain().getArchName();
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001033 if (getToolChain().getHost().useDriverDriver()) {
1034 CmdArgs.push_back("-arch");
Daniel Dunbarbf54a062009-04-01 20:33:11 +00001035
1036 // FIXME: Remove these special cases.
Daniel Dunbar7cfe31a2009-05-22 02:21:04 +00001037 if (Arch == "powerpc")
1038 CmdArgs.push_back("ppc");
1039 else if (Arch == "powerpc64")
1040 CmdArgs.push_back("ppc64");
1041 else
Daniel Dunbar88137642009-09-09 22:32:48 +00001042 CmdArgs.push_back(Args.MakeArgString(Arch));
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001043 }
1044
Daniel Dunbar6ecc7a92009-05-02 21:41:52 +00001045 // Try to force gcc to match the tool chain we want, if we recognize
1046 // the arch.
Daniel Dunbar7cfe31a2009-05-22 02:21:04 +00001047 //
1048 // FIXME: The triple class should directly provide the information we want
1049 // here.
1050 if (Arch == "i386" || Arch == "powerpc")
Daniel Dunbar6ecc7a92009-05-02 21:41:52 +00001051 CmdArgs.push_back("-m32");
Daniel Dunbar7cfe31a2009-05-22 02:21:04 +00001052 else if (Arch == "x86_64" || Arch == "powerpc64")
Daniel Dunbar6ecc7a92009-05-02 21:41:52 +00001053 CmdArgs.push_back("-m64");
1054
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001055 if (Output.isPipe()) {
1056 CmdArgs.push_back("-o");
1057 CmdArgs.push_back("-");
Daniel Dunbar115a7922009-03-19 07:29:38 +00001058 } else if (Output.isFilename()) {
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001059 CmdArgs.push_back("-o");
Daniel Dunbar115a7922009-03-19 07:29:38 +00001060 CmdArgs.push_back(Output.getFilename());
1061 } else {
1062 assert(Output.isNothing() && "Unexpected output");
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001063 CmdArgs.push_back("-fsyntax-only");
Daniel Dunbar115a7922009-03-19 07:29:38 +00001064 }
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001065
1066
1067 // Only pass -x if gcc will understand it; otherwise hope gcc
1068 // understands the suffix correctly. The main use case this would go
1069 // wrong in is for linker inputs if they happened to have an odd
1070 // suffix; really the only way to get this to happen is a command
1071 // like '-x foobar a.c' which will treat a.c like a linker input.
1072 //
1073 // FIXME: For the linker case specifically, can we safely convert
1074 // inputs into '-Wl,' options?
1075 for (InputInfoList::const_iterator
1076 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1077 const InputInfo &II = *it;
Daniel Dunbara8304f62009-05-02 20:14:53 +00001078
Daniel Dunbar5915fbf2009-09-01 16:57:46 +00001079 // Don't try to pass LLVM or AST inputs to a generic gcc.
Daniel Dunbara8304f62009-05-02 20:14:53 +00001080 if (II.getType() == types::TY_LLVMBC)
1081 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00001082 << getToolChain().getTripleString();
Daniel Dunbar5915fbf2009-09-01 16:57:46 +00001083 else if (II.getType() == types::TY_AST)
1084 D.Diag(clang::diag::err_drv_no_ast_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00001085 << getToolChain().getTripleString();
Daniel Dunbara8304f62009-05-02 20:14:53 +00001086
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001087 if (types::canTypeBeUserSpecified(II.getType())) {
1088 CmdArgs.push_back("-x");
1089 CmdArgs.push_back(types::getTypeName(II.getType()));
1090 }
1091
1092 if (II.isPipe())
1093 CmdArgs.push_back("-");
Daniel Dunbar115a7922009-03-19 07:29:38 +00001094 else if (II.isFilename())
1095 CmdArgs.push_back(II.getFilename());
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001096 else
Daniel Dunbar115a7922009-03-19 07:29:38 +00001097 // Don't render as input, we need gcc to do the translations.
1098 II.getInputArg().render(Args, CmdArgs);
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001099 }
1100
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001101 const char *GCCName =
Daniel Dunbar78d8a082009-04-01 23:34:41 +00001102 getToolChain().getHost().getDriver().CCCGenericGCCName.c_str();
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001103 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00001104 Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00001105 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001106}
1107
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001108void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1109 CmdArgs.push_back("-E");
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001110}
1111
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001112void gcc::Precompile::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1113 // The type is good enough.
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001114}
1115
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001116void gcc::Compile::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1117 CmdArgs.push_back("-S");
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001118}
1119
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001120void gcc::Assemble::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1121 CmdArgs.push_back("-c");
Daniel Dunbar47ac7d22009-03-18 06:00:36 +00001122}
Daniel Dunbarb488c1d2009-03-18 08:07:30 +00001123
1124void gcc::Link::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1125 // The types are (hopefully) good enough.
1126}
1127
Daniel Dunbar40f12652009-03-29 17:08:39 +00001128const char *darwin::CC1::getCC1Name(types::ID Type) const {
1129 switch (Type) {
1130 default:
1131 assert(0 && "Unexpected type for Darwin CC1 tool.");
1132 case types::TY_Asm:
1133 case types::TY_C: case types::TY_CHeader:
1134 case types::TY_PP_C: case types::TY_PP_CHeader:
1135 return "cc1";
1136 case types::TY_ObjC: case types::TY_ObjCHeader:
1137 case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
1138 return "cc1obj";
1139 case types::TY_CXX: case types::TY_CXXHeader:
1140 case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
1141 return "cc1plus";
1142 case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
1143 case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
1144 return "cc1objplus";
1145 }
1146}
1147
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001148const char *darwin::CC1::getBaseInputName(const ArgList &Args,
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001149 const InputInfoList &Inputs) {
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001150 llvm::sys::Path P(Inputs[0].getBaseInput());
Daniel Dunbar88137642009-09-09 22:32:48 +00001151 return Args.MakeArgString(P.getLast());
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001152}
1153
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001154const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001155 const InputInfoList &Inputs) {
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001156 const char *Str = getBaseInputName(Args, Inputs);
1157
1158 if (const char *End = strchr(Str, '.'))
Daniel Dunbar88137642009-09-09 22:32:48 +00001159 return Args.MakeArgString(std::string(Str, End));
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001160
1161 return Str;
1162}
1163
1164const char *
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001165darwin::CC1::getDependencyFileName(const ArgList &Args,
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001166 const InputInfoList &Inputs) {
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001167 // FIXME: Think about this more.
1168 std::string Res;
1169
1170 if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
1171 std::string Str(OutputOpt->getValue(Args));
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001172
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001173 Res = Str.substr(0, Str.rfind('.'));
1174 } else
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001175 Res = darwin::CC1::getBaseInputStem(Args, Inputs);
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001176
Daniel Dunbar88137642009-09-09 22:32:48 +00001177 return Args.MakeArgString(Res + ".d");
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001178}
1179
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001180void darwin::CC1::AddCC1Args(const ArgList &Args,
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001181 ArgStringList &CmdArgs) const {
Daniel Dunbare2fd6642009-09-10 01:21:12 +00001182 const Driver &D = getToolChain().getHost().getDriver();
1183
1184 CheckCodeGenerationOptions(D, Args);
1185
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001186 // Derived from cc1 spec.
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001187 if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
1188 !Args.hasArg(options::OPT_mdynamic_no_pic))
1189 CmdArgs.push_back("-fPIC");
1190
Daniel Dunbar2ba91572009-09-10 03:37:02 +00001191 if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1192 getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
1193 if (!Args.hasArg(options::OPT_fbuiltin_strcat))
1194 CmdArgs.push_back("-fno-builtin-strcat");
1195 if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
1196 CmdArgs.push_back("-fno-builtin-strcpy");
1197 }
1198
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001199 // gcc has some code here to deal with when no -mmacosx-version-min
1200 // and no -miphoneos-version-min is present, but this never happens
1201 // due to tool chain specific argument translation.
1202
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001203 if (Args.hasArg(options::OPT_g_Flag) &&
1204 !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
1205 CmdArgs.push_back("-feliminate-unused-debug-symbols");
1206}
1207
1208void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
1209 const InputInfoList &Inputs,
1210 const ArgStringList &OutputArgs) const {
1211 const Driver &D = getToolChain().getHost().getDriver();
1212
1213 // Derived from cc1_options spec.
1214 if (Args.hasArg(options::OPT_fast) ||
1215 Args.hasArg(options::OPT_fastf) ||
1216 Args.hasArg(options::OPT_fastcp))
1217 CmdArgs.push_back("-O3");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001218
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001219 if (Arg *A = Args.getLastArg(options::OPT_pg))
1220 if (Args.hasArg(options::OPT_fomit_frame_pointer))
1221 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1222 << A->getAsString(Args) << "-fomit-frame-pointer";
1223
1224 AddCC1Args(Args, CmdArgs);
1225
1226 if (!Args.hasArg(options::OPT_Q))
1227 CmdArgs.push_back("-quiet");
1228
1229 CmdArgs.push_back("-dumpbase");
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001230 CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001231
1232 Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
1233
1234 Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
1235 Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
1236
1237 // FIXME: The goal is to use the user provided -o if that is our
1238 // final output, otherwise to drive from the original input
1239 // name. Find a clean way to go about this.
1240 if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
1241 Args.hasArg(options::OPT_o)) {
1242 Arg *OutputOpt = Args.getLastArg(options::OPT_o);
1243 CmdArgs.push_back("-auxbase-strip");
1244 CmdArgs.push_back(OutputOpt->getValue(Args));
1245 } else {
1246 CmdArgs.push_back("-auxbase");
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001247 CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001248 }
1249
1250 Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
1251
1252 Args.AddAllArgs(CmdArgs, options::OPT_O);
1253 // FIXME: -Wall is getting some special treatment. Investigate.
1254 Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
1255 Args.AddLastArg(CmdArgs, options::OPT_w);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001256 Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001257 options::OPT_trigraphs);
Daniel Dunbara3ff2022009-04-26 01:10:38 +00001258 if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1259 // Honor -std-default.
1260 Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1261 "-std=", /*Joined=*/true);
1262 }
1263
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001264 if (Args.hasArg(options::OPT_v))
1265 CmdArgs.push_back("-version");
1266 if (Args.hasArg(options::OPT_pg))
1267 CmdArgs.push_back("-p");
1268 Args.AddLastArg(CmdArgs, options::OPT_p);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001269
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001270 // The driver treats -fsyntax-only specially.
Daniel Dunbar2ba91572009-09-10 03:37:02 +00001271 if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1272 getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
1273 // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
1274 // used to inhibit the default -fno-builtin-str{cat,cpy}.
1275 //
1276 // FIXME: Should we grow a better way to deal with "removing" args?
1277 //
1278 // FIXME: Use iterator.
1279 for (ArgList::const_iterator it = Args.begin(),
1280 ie = Args.end(); it != ie; ++it) {
1281 const Arg *A = *it;
Daniel Dunbar728a5122009-09-10 06:49:20 +00001282 if (A->getOption().matches(options::OPT_f_Group) ||
Daniel Dunbar2ba91572009-09-10 03:37:02 +00001283 A->getOption().matches(options::OPT_fsyntax_only)) {
1284 if (!A->getOption().matches(options::OPT_fbuiltin_strcat) &&
1285 !A->getOption().matches(options::OPT_fbuiltin_strcpy)) {
1286 A->claim();
1287 A->render(Args, CmdArgs);
1288 }
1289 }
1290 }
1291 } else
1292 Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001293
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001294 Args.AddAllArgs(CmdArgs, options::OPT_undef);
1295 if (Args.hasArg(options::OPT_Qn))
1296 CmdArgs.push_back("-fno-ident");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001297
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001298 // FIXME: This isn't correct.
1299 //Args.AddLastArg(CmdArgs, options::OPT__help)
1300 //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
1301
1302 CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1303
1304 // FIXME: Still don't get what is happening here. Investigate.
1305 Args.AddAllArgs(CmdArgs, options::OPT__param);
1306
1307 if (Args.hasArg(options::OPT_fmudflap) ||
1308 Args.hasArg(options::OPT_fmudflapth)) {
1309 CmdArgs.push_back("-fno-builtin");
1310 CmdArgs.push_back("-fno-merge-constants");
1311 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001312
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001313 if (Args.hasArg(options::OPT_coverage)) {
1314 CmdArgs.push_back("-fprofile-arcs");
1315 CmdArgs.push_back("-ftest-coverage");
1316 }
1317
1318 if (types::isCXX(Inputs[0].getType()))
1319 CmdArgs.push_back("-D__private_extern__=extern");
1320}
1321
1322void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
1323 const InputInfoList &Inputs,
1324 const ArgStringList &OutputArgs) const {
1325 // Derived from cpp_options
1326 AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001327
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001328 CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1329
1330 AddCC1Args(Args, CmdArgs);
1331
1332 // NOTE: The code below has some commonality with cpp_options, but
1333 // in classic gcc style ends up sending things in different
1334 // orders. This may be a good merge candidate once we drop pedantic
1335 // compatibility.
1336
1337 Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001338 Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001339 options::OPT_trigraphs);
Daniel Dunbara3ff2022009-04-26 01:10:38 +00001340 if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1341 // Honor -std-default.
1342 Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1343 "-std=", /*Joined=*/true);
1344 }
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001345 Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
1346 Args.AddLastArg(CmdArgs, options::OPT_w);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001347
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001348 // The driver treats -fsyntax-only specially.
1349 Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
1350
1351 if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
1352 !Args.hasArg(options::OPT_fno_working_directory))
1353 CmdArgs.push_back("-fworking-directory");
1354
1355 Args.AddAllArgs(CmdArgs, options::OPT_O);
1356 Args.AddAllArgs(CmdArgs, options::OPT_undef);
1357 if (Args.hasArg(options::OPT_save_temps))
1358 CmdArgs.push_back("-fpch-preprocess");
1359}
1360
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001361void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001362 ArgStringList &CmdArgs,
Mike Stump1eb44332009-09-09 15:08:12 +00001363 const InputInfoList &Inputs) const {
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001364 const Driver &D = getToolChain().getHost().getDriver();
1365
Daniel Dunbar88a3d6c2009-09-10 01:21:05 +00001366 CheckPreprocessingOptions(D, Args);
1367
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001368 // Derived from cpp_unique_options.
Daniel Dunbar88a3d6c2009-09-10 01:21:05 +00001369 // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
1370 Args.AddLastArg(CmdArgs, options::OPT_C);
1371 Args.AddLastArg(CmdArgs, options::OPT_CC);
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001372 if (!Args.hasArg(options::OPT_Q))
1373 CmdArgs.push_back("-quiet");
1374 Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
1375 Args.AddLastArg(CmdArgs, options::OPT_v);
1376 Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
1377 Args.AddLastArg(CmdArgs, options::OPT_P);
1378
1379 // FIXME: Handle %I properly.
1380 if (getToolChain().getArchName() == "x86_64") {
1381 CmdArgs.push_back("-imultilib");
1382 CmdArgs.push_back("x86_64");
1383 }
1384
1385 if (Args.hasArg(options::OPT_MD)) {
1386 CmdArgs.push_back("-MD");
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001387 CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001388 }
1389
1390 if (Args.hasArg(options::OPT_MMD)) {
1391 CmdArgs.push_back("-MMD");
Daniel Dunbara5a7bd02009-03-30 00:34:04 +00001392 CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001393 }
1394
1395 Args.AddLastArg(CmdArgs, options::OPT_M);
1396 Args.AddLastArg(CmdArgs, options::OPT_MM);
1397 Args.AddAllArgs(CmdArgs, options::OPT_MF);
1398 Args.AddLastArg(CmdArgs, options::OPT_MG);
1399 Args.AddLastArg(CmdArgs, options::OPT_MP);
1400 Args.AddAllArgs(CmdArgs, options::OPT_MQ);
1401 Args.AddAllArgs(CmdArgs, options::OPT_MT);
1402 if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
1403 (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
1404 if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
1405 CmdArgs.push_back("-MQ");
1406 CmdArgs.push_back(OutputOpt->getValue(Args));
1407 }
1408 }
1409
1410 Args.AddLastArg(CmdArgs, options::OPT_remap);
1411 if (Args.hasArg(options::OPT_g3))
1412 CmdArgs.push_back("-dD");
1413 Args.AddLastArg(CmdArgs, options::OPT_H);
1414
1415 AddCPPArgs(Args, CmdArgs);
1416
1417 Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
1418 Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
1419
1420 for (InputInfoList::const_iterator
1421 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1422 const InputInfo &II = *it;
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001423
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001424 if (II.isPipe())
1425 CmdArgs.push_back("-");
1426 else
1427 CmdArgs.push_back(II.getFilename());
1428 }
1429
1430 Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
1431 options::OPT_Xpreprocessor);
1432
1433 if (Args.hasArg(options::OPT_fmudflap)) {
1434 CmdArgs.push_back("-D_MUDFLAP");
1435 CmdArgs.push_back("-include");
1436 CmdArgs.push_back("mf-runtime.h");
1437 }
1438
1439 if (Args.hasArg(options::OPT_fmudflapth)) {
1440 CmdArgs.push_back("-D_MUDFLAP");
1441 CmdArgs.push_back("-D_MUDFLAPTH");
1442 CmdArgs.push_back("-include");
1443 CmdArgs.push_back("mf-runtime.h");
1444 }
1445}
1446
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001447void darwin::CC1::AddCPPArgs(const ArgList &Args,
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001448 ArgStringList &CmdArgs) const {
1449 // Derived from cpp spec.
1450
1451 if (Args.hasArg(options::OPT_static)) {
1452 // The gcc spec is broken here, it refers to dynamic but
1453 // that has been translated. Start by being bug compatible.
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001454
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001455 // if (!Args.hasArg(arglist.parser.dynamicOption))
1456 CmdArgs.push_back("-D__STATIC__");
1457 } else
1458 CmdArgs.push_back("-D__DYNAMIC__");
1459
1460 if (Args.hasArg(options::OPT_pthread))
1461 CmdArgs.push_back("-D_REENTRANT");
1462}
1463
Daniel Dunbar40f12652009-03-29 17:08:39 +00001464void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001465 Job &Dest, const InputInfo &Output,
1466 const InputInfoList &Inputs,
1467 const ArgList &Args,
Daniel Dunbar40f12652009-03-29 17:08:39 +00001468 const char *LinkingOutput) const {
1469 ArgStringList CmdArgs;
1470
1471 assert(Inputs.size() == 1 && "Unexpected number of inputs!");
1472
1473 CmdArgs.push_back("-E");
1474
1475 if (Args.hasArg(options::OPT_traditional) ||
Daniel Dunbar40f12652009-03-29 17:08:39 +00001476 Args.hasArg(options::OPT_traditional_cpp))
1477 CmdArgs.push_back("-traditional-cpp");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001478
Daniel Dunbar40f12652009-03-29 17:08:39 +00001479 ArgStringList OutputArgs;
1480 if (Output.isFilename()) {
1481 OutputArgs.push_back("-o");
1482 OutputArgs.push_back(Output.getFilename());
1483 } else {
1484 assert(Output.isPipe() && "Unexpected CC1 output.");
1485 }
1486
Daniel Dunbar9120f172009-03-29 22:27:40 +00001487 if (Args.hasArg(options::OPT_E)) {
1488 AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1489 } else {
1490 AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1491 CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1492 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001493
Daniel Dunbar8a2073a2009-04-03 01:27:06 +00001494 Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
1495
Daniel Dunbar40f12652009-03-29 17:08:39 +00001496 const char *CC1Name = getCC1Name(Inputs[0].getType());
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001497 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00001498 Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00001499 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar40f12652009-03-29 17:08:39 +00001500}
1501
1502void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001503 Job &Dest, const InputInfo &Output,
1504 const InputInfoList &Inputs,
1505 const ArgList &Args,
Daniel Dunbar40f12652009-03-29 17:08:39 +00001506 const char *LinkingOutput) const {
1507 const Driver &D = getToolChain().getHost().getDriver();
1508 ArgStringList CmdArgs;
1509
1510 assert(Inputs.size() == 1 && "Unexpected number of inputs!");
1511
1512 types::ID InputType = Inputs[0].getType();
1513 const Arg *A;
Eli Friedmanceb5c5b2009-07-14 21:58:17 +00001514 if ((A = Args.getLastArg(options::OPT_traditional)))
Daniel Dunbar40f12652009-03-29 17:08:39 +00001515 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
1516 << A->getAsString(Args) << "-E";
1517
1518 if (Output.getType() == types::TY_LLVMAsm)
1519 CmdArgs.push_back("-emit-llvm");
1520 else if (Output.getType() == types::TY_LLVMBC)
1521 CmdArgs.push_back("-emit-llvm-bc");
Daniel Dunbar5915fbf2009-09-01 16:57:46 +00001522 else if (Output.getType() == types::TY_AST)
1523 D.Diag(clang::diag::err_drv_no_ast_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00001524 << getToolChain().getTripleString();
Daniel Dunbar40f12652009-03-29 17:08:39 +00001525
1526 ArgStringList OutputArgs;
1527 if (Output.getType() != types::TY_PCH) {
1528 OutputArgs.push_back("-o");
1529 if (Output.isPipe())
1530 OutputArgs.push_back("-");
1531 else if (Output.isNothing())
1532 OutputArgs.push_back("/dev/null");
1533 else
1534 OutputArgs.push_back(Output.getFilename());
1535 }
1536
1537 // There is no need for this level of compatibility, but it makes
1538 // diffing easier.
1539 bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
1540 Args.hasArg(options::OPT_S));
1541
1542 if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
Daniel Dunbara3ec60e2009-03-29 18:40:18 +00001543 AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
Daniel Dunbar40f12652009-03-29 17:08:39 +00001544 if (OutputArgsEarly) {
1545 AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1546 } else {
1547 AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1548 CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1549 }
1550 } else {
1551 CmdArgs.push_back("-fpreprocessed");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001552
Daniel Dunbar40f12652009-03-29 17:08:39 +00001553 for (InputInfoList::const_iterator
1554 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1555 const InputInfo &II = *it;
1556
Daniel Dunbar5915fbf2009-09-01 16:57:46 +00001557 // Reject AST inputs.
1558 if (II.getType() == types::TY_AST) {
1559 D.Diag(clang::diag::err_drv_no_ast_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00001560 << getToolChain().getTripleString();
Daniel Dunbar5915fbf2009-09-01 16:57:46 +00001561 return;
1562 }
1563
Daniel Dunbar40f12652009-03-29 17:08:39 +00001564 if (II.isPipe())
1565 CmdArgs.push_back("-");
1566 else
1567 CmdArgs.push_back(II.getFilename());
1568 }
1569
1570 if (OutputArgsEarly) {
1571 AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1572 } else {
1573 AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1574 CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1575 }
1576 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001577
Daniel Dunbar40f12652009-03-29 17:08:39 +00001578 if (Output.getType() == types::TY_PCH) {
1579 assert(Output.isFilename() && "Invalid PCH output.");
1580
1581 CmdArgs.push_back("-o");
1582 // NOTE: gcc uses a temp .s file for this, but there doesn't seem
1583 // to be a good reason.
1584 CmdArgs.push_back("/dev/null");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001585
Daniel Dunbar40f12652009-03-29 17:08:39 +00001586 CmdArgs.push_back("--output-pch=");
1587 CmdArgs.push_back(Output.getFilename());
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001588 }
Daniel Dunbar40f12652009-03-29 17:08:39 +00001589
1590 const char *CC1Name = getCC1Name(Inputs[0].getType());
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001591 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00001592 Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00001593 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar40f12652009-03-29 17:08:39 +00001594}
1595
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001596void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001597 Job &Dest, const InputInfo &Output,
1598 const InputInfoList &Inputs,
1599 const ArgList &Args,
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001600 const char *LinkingOutput) const {
1601 ArgStringList CmdArgs;
1602
1603 assert(Inputs.size() == 1 && "Unexpected number of inputs.");
1604 const InputInfo &Input = Inputs[0];
1605
1606 // Bit of a hack, this is only used for original inputs.
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001607 //
Daniel Dunbar8e4fea62009-04-01 00:27:44 +00001608 // FIXME: This is broken for preprocessed .s inputs.
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001609 if (Input.isFilename() &&
Daniel Dunbar8e4fea62009-04-01 00:27:44 +00001610 strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
1611 if (Args.hasArg(options::OPT_gstabs))
1612 CmdArgs.push_back("--gstabs");
1613 else if (Args.hasArg(options::OPT_g_Group))
1614 CmdArgs.push_back("--gdwarf2");
1615 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001616
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001617 // Derived from asm spec.
Daniel Dunbarcc6f8032009-09-09 18:36:27 +00001618 AddDarwinArch(Args, CmdArgs);
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001619
Daniel Dunbar1d4612b2009-09-18 08:15:13 +00001620 if (!getDarwinToolChain().isIPhoneOS() ||
Daniel Dunbarcc6f8032009-09-09 18:36:27 +00001621 Args.hasArg(options::OPT_force__cpusubtype__ALL))
1622 CmdArgs.push_back("-force_cpusubtype_ALL");
1623
Daniel Dunbar0e2679d2009-08-24 22:26:16 +00001624 if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
1625 (Args.hasArg(options::OPT_mkernel) ||
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001626 Args.hasArg(options::OPT_static) ||
Daniel Dunbar0e2679d2009-08-24 22:26:16 +00001627 Args.hasArg(options::OPT_fapple_kext)))
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001628 CmdArgs.push_back("-static");
1629
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001630 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
1631 options::OPT_Xassembler);
1632
1633 assert(Output.isFilename() && "Unexpected lipo output.");
1634 CmdArgs.push_back("-o");
1635 CmdArgs.push_back(Output.getFilename());
1636
1637 if (Input.isPipe()) {
1638 CmdArgs.push_back("-");
1639 } else {
1640 assert(Input.isFilename() && "Invalid input.");
1641 CmdArgs.push_back(Input.getFilename());
1642 }
1643
1644 // asm_final spec is empty.
1645
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001646 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00001647 Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00001648 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar8cac5f72009-03-20 16:06:39 +00001649}
Daniel Dunbarff7488d2009-03-20 00:52:38 +00001650
Daniel Dunbar02633b52009-03-26 16:23:12 +00001651/// Helper routine for seeing if we should use dsymutil; this is a
1652/// gcc compatible hack, we should remove it and use the input
1653/// type information.
1654static bool isSourceSuffix(const char *Str) {
1655 // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm',
1656 // 'mm'.
Douglas Gregor55d3f7a2009-10-29 00:41:01 +00001657 return llvm::StringSwitch<bool>(Str)
1658 .Case("C", true)
1659 .Case("c", true)
1660 .Case("m", true)
1661 .Case("cc", true)
1662 .Case("cp", true)
1663 .Case("mm", true)
1664 .Case("CPP", true)
1665 .Case("c++", true)
1666 .Case("cpp", true)
1667 .Case("cxx", true)
1668 .Default(false);
Daniel Dunbar02633b52009-03-26 16:23:12 +00001669}
1670
Daniel Dunbar78dbd582009-09-04 18:35:31 +00001671// FIXME: Can we tablegen this?
1672static const char *GetArmArchForMArch(llvm::StringRef Value) {
1673 if (Value == "armv6k")
1674 return "armv6";
1675
1676 if (Value == "armv5tej")
1677 return "armv5";
1678
1679 if (Value == "xscale")
1680 return "xscale";
1681
1682 if (Value == "armv4t")
1683 return "armv4t";
1684
1685 if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
1686 Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
1687 Value == "armv7m")
1688 return "armv7";
1689
1690 return 0;
1691}
1692
1693// FIXME: Can we tablegen this?
1694static const char *GetArmArchForMCpu(llvm::StringRef Value) {
1695 if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
1696 Value == "arm946e-s" || Value == "arm966e-s" ||
1697 Value == "arm968e-s" || Value == "arm10e" ||
1698 Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
1699 Value == "arm1026ej-s")
1700 return "armv5";
1701
1702 if (Value == "xscale")
1703 return "xscale";
1704
1705 if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
1706 Value == "arm1176jz-s" || Value == "arm1176jzf-s")
1707 return "armv6";
1708
1709 if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
1710 return "armv7";
1711
1712 return 0;
1713}
1714
Daniel Dunbarfbefe6b2009-09-09 18:36:20 +00001715void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
1716 ArgStringList &CmdArgs) const {
Daniel Dunbar02633b52009-03-26 16:23:12 +00001717 // Derived from darwin_arch spec.
1718 CmdArgs.push_back("-arch");
Daniel Dunbar78dbd582009-09-04 18:35:31 +00001719
1720 switch (getToolChain().getTriple().getArch()) {
1721 default:
Daniel Dunbar88137642009-09-09 22:32:48 +00001722 CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
Daniel Dunbar78dbd582009-09-04 18:35:31 +00001723 break;
1724
1725 case llvm::Triple::arm: {
Daniel Dunbar78dbd582009-09-04 18:35:31 +00001726 if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1727 if (const char *Arch = GetArmArchForMArch(A->getValue(Args))) {
1728 CmdArgs.push_back(Arch);
1729 return;
1730 }
1731 }
1732
1733 if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1734 if (const char *Arch = GetArmArchForMCpu(A->getValue(Args))) {
1735 CmdArgs.push_back(Arch);
1736 return;
1737 }
1738 }
1739
1740 CmdArgs.push_back("arm");
1741 CmdArgs.push_back("-force_cpusubtype_ALL");
1742 return;
1743 }
1744 }
Daniel Dunbar02633b52009-03-26 16:23:12 +00001745}
1746
Daniel Dunbarfbefe6b2009-09-09 18:36:20 +00001747void darwin::DarwinTool::AddDarwinSubArch(const ArgList &Args,
1748 ArgStringList &CmdArgs) const {
Daniel Dunbar02633b52009-03-26 16:23:12 +00001749 // Derived from darwin_subarch spec, not sure what the distinction
1750 // exists for but at least for this chain it is the same.
1751 AddDarwinArch(Args, CmdArgs);
1752}
1753
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001754void darwin::Link::AddLinkArgs(const ArgList &Args,
Daniel Dunbar02633b52009-03-26 16:23:12 +00001755 ArgStringList &CmdArgs) const {
1756 const Driver &D = getToolChain().getHost().getDriver();
1757
1758 // Derived from the "link" spec.
1759 Args.AddAllArgs(CmdArgs, options::OPT_static);
1760 if (!Args.hasArg(options::OPT_static))
1761 CmdArgs.push_back("-dynamic");
1762 if (Args.hasArg(options::OPT_fgnu_runtime)) {
1763 // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
1764 // here. How do we wish to handle such things?
1765 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001766
Daniel Dunbar02633b52009-03-26 16:23:12 +00001767 if (!Args.hasArg(options::OPT_dynamiclib)) {
1768 if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
1769 AddDarwinArch(Args, CmdArgs);
1770 CmdArgs.push_back("-force_cpusubtype_ALL");
1771 } else
1772 AddDarwinSubArch(Args, CmdArgs);
1773
1774 Args.AddLastArg(CmdArgs, options::OPT_bundle);
1775 Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
1776 Args.AddAllArgs(CmdArgs, options::OPT_client__name);
1777
1778 Arg *A;
1779 if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
1780 (A = Args.getLastArg(options::OPT_current__version)) ||
1781 (A = Args.getLastArg(options::OPT_install__name)))
1782 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
1783 << A->getAsString(Args) << "-dynamiclib";
1784
1785 Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
1786 Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
1787 Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
1788 } else {
1789 CmdArgs.push_back("-dylib");
1790
1791 Arg *A;
1792 if ((A = Args.getLastArg(options::OPT_bundle)) ||
1793 (A = Args.getLastArg(options::OPT_bundle__loader)) ||
1794 (A = Args.getLastArg(options::OPT_client__name)) ||
1795 (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
1796 (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
1797 (A = Args.getLastArg(options::OPT_private__bundle)))
1798 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1799 << A->getAsString(Args) << "-dynamiclib";
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001800
Daniel Dunbar02633b52009-03-26 16:23:12 +00001801 Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
1802 "-dylib_compatibility_version");
1803 Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
1804 "-dylib_current_version");
1805
1806 if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
1807 AddDarwinArch(Args, CmdArgs);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001808 // NOTE: We don't add -force_cpusubtype_ALL on this path. Ok.
Daniel Dunbar02633b52009-03-26 16:23:12 +00001809 } else
1810 AddDarwinSubArch(Args, CmdArgs);
1811
1812 Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
1813 "-dylib_install_name");
1814 }
1815
1816 Args.AddLastArg(CmdArgs, options::OPT_all__load);
1817 Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
1818 Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
Daniel Dunbar1d4612b2009-09-18 08:15:13 +00001819 if (getDarwinToolChain().isIPhoneOS())
Daniel Dunbard82f8fa2009-09-04 18:35:41 +00001820 Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
Daniel Dunbar02633b52009-03-26 16:23:12 +00001821 Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
1822 Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
1823 Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
1824 Args.AddLastArg(CmdArgs, options::OPT_dynamic);
1825 Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
1826 Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
1827 Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
1828 Args.AddAllArgs(CmdArgs, options::OPT_image__base);
1829 Args.AddAllArgs(CmdArgs, options::OPT_init);
1830
Daniel Dunbar30392de2009-09-04 18:35:21 +00001831 if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ) &&
1832 !Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
1833 // Add default version min.
Daniel Dunbar1d4612b2009-09-18 08:15:13 +00001834 if (!getDarwinToolChain().isIPhoneOS()) {
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001835 CmdArgs.push_back("-macosx_version_min");
1836 CmdArgs.push_back(getDarwinToolChain().getMacosxVersionStr());
Daniel Dunbar30392de2009-09-04 18:35:21 +00001837 } else {
1838 CmdArgs.push_back("-iphoneos_version_min");
1839 CmdArgs.push_back(getDarwinToolChain().getIPhoneOSVersionStr());
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001840 }
Daniel Dunbar02633b52009-03-26 16:23:12 +00001841 }
1842
Daniel Dunbar30392de2009-09-04 18:35:21 +00001843 // Adding all arguments doesn't make sense here but this is what
1844 // gcc does.
1845 Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
1846 "-macosx_version_min");
Daniel Dunbar02633b52009-03-26 16:23:12 +00001847 Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
1848 "-iphoneos_version_min");
1849 Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
1850 Args.AddLastArg(CmdArgs, options::OPT_multi__module);
1851 Args.AddLastArg(CmdArgs, options::OPT_single__module);
1852 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
1853 Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001854
Daniel Dunbar02633b52009-03-26 16:23:12 +00001855 if (Args.hasArg(options::OPT_fpie))
1856 CmdArgs.push_back("-pie");
1857
1858 Args.AddLastArg(CmdArgs, options::OPT_prebind);
1859 Args.AddLastArg(CmdArgs, options::OPT_noprebind);
1860 Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
1861 Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
1862 Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
1863 Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
1864 Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
1865 Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
1866 Args.AddAllArgs(CmdArgs, options::OPT_segprot);
1867 Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
1868 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
1869 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
1870 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
1871 Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
1872 Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
1873 Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
Daniel Dunbard82f8fa2009-09-04 18:35:41 +00001874
Daniel Dunbar02633b52009-03-26 16:23:12 +00001875 Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
Daniel Dunbar1d4612b2009-09-18 08:15:13 +00001876 if (getDarwinToolChain().isIPhoneOS()) {
Daniel Dunbard82f8fa2009-09-04 18:35:41 +00001877 if (!Args.hasArg(options::OPT_isysroot)) {
1878 CmdArgs.push_back("-syslibroot");
1879 CmdArgs.push_back("/Developer/SDKs/Extra");
1880 }
1881 }
1882
Daniel Dunbar02633b52009-03-26 16:23:12 +00001883 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
1884 Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
1885 Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
1886 Args.AddAllArgs(CmdArgs, options::OPT_undefined);
1887 Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
Daniel Dunbar02633b52009-03-26 16:23:12 +00001888
Daniel Dunbard82f8fa2009-09-04 18:35:41 +00001889 Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
Daniel Dunbar02633b52009-03-26 16:23:12 +00001890 if (!Args.hasArg(options::OPT_weak__reference__mismatches)) {
1891 CmdArgs.push_back("-weak_reference_mismatches");
1892 CmdArgs.push_back("non-weak");
1893 }
1894
1895 Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
1896 Args.AddAllArgs(CmdArgs, options::OPT_y);
1897 Args.AddLastArg(CmdArgs, options::OPT_w);
1898 Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
1899 Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
1900 Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
1901 Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
1902 Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
1903 Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
1904 Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
1905 Args.AddLastArg(CmdArgs, options::OPT_whyload);
1906 Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
1907 Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
1908 Args.AddLastArg(CmdArgs, options::OPT_dylinker);
1909 Args.AddLastArg(CmdArgs, options::OPT_Mach);
1910}
1911
1912void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001913 Job &Dest, const InputInfo &Output,
1914 const InputInfoList &Inputs,
1915 const ArgList &Args,
Daniel Dunbar02633b52009-03-26 16:23:12 +00001916 const char *LinkingOutput) const {
1917 assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
Daniel Dunbare0be8b12009-09-08 16:39:16 +00001918
Daniel Dunbar02633b52009-03-26 16:23:12 +00001919 // The logic here is derived from gcc's behavior; most of which
1920 // comes from specs (starting with link_command). Consult gcc for
1921 // more information.
Daniel Dunbar02633b52009-03-26 16:23:12 +00001922 ArgStringList CmdArgs;
1923
1924 // I'm not sure why this particular decomposition exists in gcc, but
1925 // we follow suite for ease of comparison.
1926 AddLinkArgs(Args, CmdArgs);
1927
Daniel Dunbar02633b52009-03-26 16:23:12 +00001928 Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
1929 Args.AddAllArgs(CmdArgs, options::OPT_s);
1930 Args.AddAllArgs(CmdArgs, options::OPT_t);
1931 Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
1932 Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
1933 Args.AddAllArgs(CmdArgs, options::OPT_A);
1934 Args.AddLastArg(CmdArgs, options::OPT_e);
1935 Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
1936 Args.AddAllArgs(CmdArgs, options::OPT_r);
1937
Daniel Dunbar02633b52009-03-26 16:23:12 +00001938 CmdArgs.push_back("-o");
1939 CmdArgs.push_back(Output.getFilename());
1940
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001941
Daniel Dunbarae54af22009-09-18 08:14:24 +00001942 unsigned MacosxVersionMin[3];
Daniel Dunbar48d5aae2009-09-18 08:14:46 +00001943 getDarwinToolChain().getMacosxVersionMin(Args, MacosxVersionMin);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001944
Daniel Dunbar02633b52009-03-26 16:23:12 +00001945 if (!Args.hasArg(options::OPT_A) &&
1946 !Args.hasArg(options::OPT_nostdlib) &&
1947 !Args.hasArg(options::OPT_nostartfiles)) {
1948 // Derived from startfile spec.
1949 if (Args.hasArg(options::OPT_dynamiclib)) {
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001950 // Derived from darwin_dylib1 spec.
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001951 if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 5))
Daniel Dunbar02633b52009-03-26 16:23:12 +00001952 CmdArgs.push_back("-ldylib1.o");
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001953 else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 6))
Daniel Dunbar02633b52009-03-26 16:23:12 +00001954 CmdArgs.push_back("-ldylib1.10.5.o");
1955 } else {
1956 if (Args.hasArg(options::OPT_bundle)) {
Daniel Dunbar8a8d8af2009-04-01 03:17:40 +00001957 if (!Args.hasArg(options::OPT_static)) {
1958 // Derived from darwin_bundle1 spec.
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001959 if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 6))
Daniel Dunbar8a8d8af2009-04-01 03:17:40 +00001960 CmdArgs.push_back("-lbundle1.o");
1961 }
Daniel Dunbar02633b52009-03-26 16:23:12 +00001962 } else {
1963 if (Args.hasArg(options::OPT_pg)) {
1964 if (Args.hasArg(options::OPT_static) ||
1965 Args.hasArg(options::OPT_object) ||
1966 Args.hasArg(options::OPT_preload)) {
1967 CmdArgs.push_back("-lgcrt0.o");
1968 } else {
1969 CmdArgs.push_back("-lgcrt1.o");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001970
Daniel Dunbar02633b52009-03-26 16:23:12 +00001971 // darwin_crt2 spec is empty.
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001972 }
Daniel Dunbar02633b52009-03-26 16:23:12 +00001973 } else {
1974 if (Args.hasArg(options::OPT_static) ||
1975 Args.hasArg(options::OPT_object) ||
1976 Args.hasArg(options::OPT_preload)) {
1977 CmdArgs.push_back("-lcrt0.o");
1978 } else {
1979 // Derived from darwin_crt1 spec.
Daniel Dunbar1d4612b2009-09-18 08:15:13 +00001980 if (getDarwinToolChain().isIPhoneOS()) {
Daniel Dunbarae33f8f2009-09-04 18:35:47 +00001981 CmdArgs.push_back("-lcrt1.o");
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001982 } else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin,
1983 10, 5))
Daniel Dunbar02633b52009-03-26 16:23:12 +00001984 CmdArgs.push_back("-lcrt1.o");
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001985 else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin,
1986 10, 6))
Daniel Dunbar02633b52009-03-26 16:23:12 +00001987 CmdArgs.push_back("-lcrt1.10.5.o");
Daniel Dunbar8a8d8af2009-04-01 03:17:40 +00001988 else
1989 CmdArgs.push_back("-lcrt1.10.6.o");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00001990
Daniel Dunbar8a8d8af2009-04-01 03:17:40 +00001991 // darwin_crt2 spec is empty.
Daniel Dunbar02633b52009-03-26 16:23:12 +00001992 }
1993 }
1994 }
1995 }
1996
1997 if (Args.hasArg(options::OPT_shared_libgcc) &&
1998 !Args.hasArg(options::OPT_miphoneos_version_min_EQ) &&
Daniel Dunbar608d04c2009-09-18 08:14:55 +00001999 getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 5)) {
Daniel Dunbar88137642009-09-09 22:32:48 +00002000 const char *Str =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002001 Args.MakeArgString(getToolChain().GetFilePath(C, "crt3.o"));
Daniel Dunbar88137642009-09-09 22:32:48 +00002002 CmdArgs.push_back(Str);
Daniel Dunbar02633b52009-03-26 16:23:12 +00002003 }
2004 }
2005
2006 Args.AddAllArgs(CmdArgs, options::OPT_L);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002007
Daniel Dunbar02633b52009-03-26 16:23:12 +00002008 if (Args.hasArg(options::OPT_fopenmp))
2009 // This is more complicated in gcc...
2010 CmdArgs.push_back("-lgomp");
2011
Daniel Dunbar6b200b22009-09-18 08:14:36 +00002012 getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002013
Daniel Dunbar02633b52009-03-26 16:23:12 +00002014 for (InputInfoList::const_iterator
2015 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2016 const InputInfo &II = *it;
2017 if (II.isFilename())
2018 CmdArgs.push_back(II.getFilename());
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002019 else
Daniel Dunbar02633b52009-03-26 16:23:12 +00002020 II.getInputArg().renderAsInput(Args, CmdArgs);
2021 }
2022
2023 if (LinkingOutput) {
2024 CmdArgs.push_back("-arch_multiple");
2025 CmdArgs.push_back("-final_output");
2026 CmdArgs.push_back(LinkingOutput);
2027 }
2028
2029 if (Args.hasArg(options::OPT_fprofile_arcs) ||
2030 Args.hasArg(options::OPT_fprofile_generate) ||
2031 Args.hasArg(options::OPT_fcreate_profile) ||
2032 Args.hasArg(options::OPT_coverage))
2033 CmdArgs.push_back("-lgcov");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002034
Daniel Dunbar02633b52009-03-26 16:23:12 +00002035 if (Args.hasArg(options::OPT_fnested_functions))
2036 CmdArgs.push_back("-allow_stack_execute");
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002037
Daniel Dunbar02633b52009-03-26 16:23:12 +00002038 if (!Args.hasArg(options::OPT_nostdlib) &&
2039 !Args.hasArg(options::OPT_nodefaultlibs)) {
Daniel Dunbaredfa02b2009-04-08 06:06:21 +00002040 // FIXME: g++ is more complicated here, it tries to put -lstdc++
2041 // before -lm, for example.
2042 if (getToolChain().getHost().getDriver().CCCIsCXX)
2043 CmdArgs.push_back("-lstdc++");
2044
Daniel Dunbar02633b52009-03-26 16:23:12 +00002045 // link_ssp spec is empty.
2046
Daniel Dunbar6cd41542009-09-18 08:15:03 +00002047 // Let the tool chain choose which runtime library to link.
2048 getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
Daniel Dunbar02633b52009-03-26 16:23:12 +00002049 }
2050
2051 if (!Args.hasArg(options::OPT_A) &&
2052 !Args.hasArg(options::OPT_nostdlib) &&
2053 !Args.hasArg(options::OPT_nostartfiles)) {
2054 // endfile_spec is empty.
2055 }
2056
2057 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2058 Args.AddAllArgs(CmdArgs, options::OPT_F);
2059
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002060 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002061 Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002062 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar02633b52009-03-26 16:23:12 +00002063
Daniel Dunbar0b46e1b2009-04-04 00:55:30 +00002064 // Find the first non-empty base input (we want to ignore linker
2065 // inputs).
2066 const char *BaseInput = "";
2067 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
2068 if (Inputs[i].getBaseInput()[0] != '\0') {
2069 BaseInput = Inputs[i].getBaseInput();
2070 break;
2071 }
2072 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002073
Daniel Dunbar3ed29452009-04-24 03:03:52 +00002074 // Run dsymutil if we are making an executable in a single step.
2075 //
2076 // FIXME: Currently we don't want to do this when we are part of a
2077 // universal build step, as this would end up creating stray temp
2078 // files.
2079 if (!LinkingOutput &&
2080 Args.getLastArg(options::OPT_g_Group) &&
Daniel Dunbar02633b52009-03-26 16:23:12 +00002081 !Args.getLastArg(options::OPT_gstabs) &&
2082 !Args.getLastArg(options::OPT_g0)) {
2083 // FIXME: This is gross, but matches gcc. The test only considers
2084 // the suffix (not the -x type), and then only of the first
Daniel Dunbar0b46e1b2009-04-04 00:55:30 +00002085 // source input. Awesome.
2086 const char *Suffix = strrchr(BaseInput, '.');
Daniel Dunbar02633b52009-03-26 16:23:12 +00002087 if (Suffix && isSourceSuffix(Suffix + 1)) {
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002088 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002089 Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil"));
Daniel Dunbar02633b52009-03-26 16:23:12 +00002090 ArgStringList CmdArgs;
2091 CmdArgs.push_back(Output.getFilename());
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002092 C.getJobs().addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar02633b52009-03-26 16:23:12 +00002093 }
2094 }
2095}
2096
Daniel Dunbarff7488d2009-03-20 00:52:38 +00002097void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002098 Job &Dest, const InputInfo &Output,
2099 const InputInfoList &Inputs,
2100 const ArgList &Args,
Daniel Dunbarff7488d2009-03-20 00:52:38 +00002101 const char *LinkingOutput) const {
2102 ArgStringList CmdArgs;
2103
2104 CmdArgs.push_back("-create");
2105 assert(Output.isFilename() && "Unexpected lipo output.");
Daniel Dunbara428df82009-03-24 00:24:37 +00002106
2107 CmdArgs.push_back("-output");
Daniel Dunbarff7488d2009-03-20 00:52:38 +00002108 CmdArgs.push_back(Output.getFilename());
Daniel Dunbara428df82009-03-24 00:24:37 +00002109
Daniel Dunbarff7488d2009-03-20 00:52:38 +00002110 for (InputInfoList::const_iterator
2111 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2112 const InputInfo &II = *it;
2113 assert(II.isFilename() && "Unexpected lipo input.");
2114 CmdArgs.push_back(II.getFilename());
2115 }
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002116 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002117 Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002118 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbarff7488d2009-03-20 00:52:38 +00002119}
Daniel Dunbar68a31d42009-03-31 17:45:15 +00002120
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002121void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2122 Job &Dest, const InputInfo &Output,
2123 const InputInfoList &Inputs,
2124 const ArgList &Args,
Mike Stump1eb44332009-09-09 15:08:12 +00002125 const char *LinkingOutput) const {
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002126 ArgStringList CmdArgs;
2127
2128 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2129 options::OPT_Xassembler);
2130
2131 CmdArgs.push_back("-o");
2132 if (Output.isPipe())
2133 CmdArgs.push_back("-");
2134 else
2135 CmdArgs.push_back(Output.getFilename());
2136
2137 for (InputInfoList::const_iterator
2138 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2139 const InputInfo &II = *it;
2140 if (II.isPipe())
2141 CmdArgs.push_back("-");
2142 else
2143 CmdArgs.push_back(II.getFilename());
2144 }
2145
2146 const char *Exec =
Edward O'Callaghanff430e62009-10-19 07:02:08 +00002147 Args.MakeArgString(getToolChain().GetProgramPath(C, "gas"));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002148 Dest.addCommand(new Command(JA, Exec, CmdArgs));
2149}
2150
2151void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
2152 Job &Dest, const InputInfo &Output,
2153 const InputInfoList &Inputs,
2154 const ArgList &Args,
2155 const char *LinkingOutput) const {
2156 const Driver &D = getToolChain().getHost().getDriver();
2157 ArgStringList CmdArgs;
2158
2159 if ((!Args.hasArg(options::OPT_nostdlib)) &&
2160 (!Args.hasArg(options::OPT_shared))) {
2161 CmdArgs.push_back("-e");
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002162 CmdArgs.push_back("_start");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002163 }
2164
2165 if (Args.hasArg(options::OPT_static)) {
2166 CmdArgs.push_back("-Bstatic");
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002167 CmdArgs.push_back("-dn");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002168 } else {
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002169// CmdArgs.push_back("--eh-frame-hdr");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002170 CmdArgs.push_back("-Bdynamic");
2171 if (Args.hasArg(options::OPT_shared)) {
2172 CmdArgs.push_back("-shared");
2173 } else {
Edward O'Callaghan3cecc192009-10-16 19:44:18 +00002174 CmdArgs.push_back("--dynamic-linker");
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002175 CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
2176 }
2177 }
2178
2179 if (Output.isPipe()) {
2180 CmdArgs.push_back("-o");
2181 CmdArgs.push_back("-");
2182 } else if (Output.isFilename()) {
2183 CmdArgs.push_back("-o");
2184 CmdArgs.push_back(Output.getFilename());
2185 } else {
2186 assert(Output.isNothing() && "Invalid output.");
2187 }
2188
2189 if (!Args.hasArg(options::OPT_nostdlib) &&
2190 !Args.hasArg(options::OPT_nostartfiles)) {
2191 if (!Args.hasArg(options::OPT_shared)) {
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002192 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
2193 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002194 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002195 } else {
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002196 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002197 }
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002198 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002199 }
2200
Daniel Dunbarf7fb31f2009-10-29 02:24:37 +00002201 CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
2202 + getToolChain().getTripleString()
2203 + "/4.2.4"));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002204
2205 Args.AddAllArgs(CmdArgs, options::OPT_L);
2206 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2207 Args.AddAllArgs(CmdArgs, options::OPT_e);
2208
2209 for (InputInfoList::const_iterator
2210 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2211 const InputInfo &II = *it;
2212
2213 // Don't try to pass LLVM inputs to a generic gcc.
2214 if (II.getType() == types::TY_LLVMBC)
2215 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00002216 << getToolChain().getTripleString();
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002217
2218 if (II.isPipe())
2219 CmdArgs.push_back("-");
2220 else if (II.isFilename())
2221 CmdArgs.push_back(II.getFilename());
2222 else
2223 II.getInputArg().renderAsInput(Args, CmdArgs);
2224 }
2225
2226 if (!Args.hasArg(options::OPT_nostdlib) &&
2227 !Args.hasArg(options::OPT_nodefaultlibs)) {
2228 // FIXME: For some reason GCC passes -lgcc before adding
2229 // the default system libraries. Just mimic this for now.
2230 CmdArgs.push_back("-lgcc");
2231
2232 if (Args.hasArg(options::OPT_pthread))
2233 CmdArgs.push_back("-pthread");
2234 if (!Args.hasArg(options::OPT_shared))
2235 CmdArgs.push_back("-lc");
2236 CmdArgs.push_back("-lgcc");
2237 }
2238
2239 if (!Args.hasArg(options::OPT_nostdlib) &&
2240 !Args.hasArg(options::OPT_nostartfiles)) {
2241 if (!Args.hasArg(options::OPT_shared))
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002242 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
Edward O'Callaghan7adf9492009-10-15 07:44:07 +00002243// else
2244// CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002245 }
2246
2247 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002248 Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
Edward O'Callaghane7925a02009-08-22 01:06:46 +00002249 Dest.addCommand(new Command(JA, Exec, CmdArgs));
2250}
2251
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002252void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2253 Job &Dest, const InputInfo &Output,
2254 const InputInfoList &Inputs,
2255 const ArgList &Args,
Mike Stump1eb44332009-09-09 15:08:12 +00002256 const char *LinkingOutput) const {
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002257 ArgStringList CmdArgs;
2258
2259 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2260 options::OPT_Xassembler);
2261
2262 CmdArgs.push_back("-o");
2263 if (Output.isPipe())
2264 CmdArgs.push_back("-");
2265 else
2266 CmdArgs.push_back(Output.getFilename());
2267
2268 for (InputInfoList::const_iterator
2269 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2270 const InputInfo &II = *it;
2271 if (II.isPipe())
2272 CmdArgs.push_back("-");
2273 else
2274 CmdArgs.push_back(II.getFilename());
2275 }
2276
2277 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002278 Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002279 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002280}
2281
2282void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
2283 Job &Dest, const InputInfo &Output,
2284 const InputInfoList &Inputs,
2285 const ArgList &Args,
2286 const char *LinkingOutput) const {
2287 const Driver &D = getToolChain().getHost().getDriver();
2288 ArgStringList CmdArgs;
2289
Daniel Dunbar2bbcf662009-08-03 01:28:59 +00002290 if ((!Args.hasArg(options::OPT_nostdlib)) &&
2291 (!Args.hasArg(options::OPT_shared))) {
2292 CmdArgs.push_back("-e");
2293 CmdArgs.push_back("__start");
2294 }
2295
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002296 if (Args.hasArg(options::OPT_static)) {
2297 CmdArgs.push_back("-Bstatic");
2298 } else {
2299 CmdArgs.push_back("--eh-frame-hdr");
Daniel Dunbar2bbcf662009-08-03 01:28:59 +00002300 CmdArgs.push_back("-Bdynamic");
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002301 if (Args.hasArg(options::OPT_shared)) {
Daniel Dunbar2bbcf662009-08-03 01:28:59 +00002302 CmdArgs.push_back("-shared");
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002303 } else {
2304 CmdArgs.push_back("-dynamic-linker");
2305 CmdArgs.push_back("/usr/libexec/ld.so");
2306 }
2307 }
2308
2309 if (Output.isPipe()) {
2310 CmdArgs.push_back("-o");
2311 CmdArgs.push_back("-");
2312 } else if (Output.isFilename()) {
2313 CmdArgs.push_back("-o");
2314 CmdArgs.push_back(Output.getFilename());
2315 } else {
2316 assert(Output.isNothing() && "Invalid output.");
2317 }
2318
2319 if (!Args.hasArg(options::OPT_nostdlib) &&
2320 !Args.hasArg(options::OPT_nostartfiles)) {
2321 if (!Args.hasArg(options::OPT_shared)) {
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002322 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o")));
2323 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002324 } else {
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002325 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002326 }
2327 }
2328
Edward O'Callaghane7e18202009-10-28 15:13:08 +00002329 std::string Triple = getToolChain().getTripleString();
2330 if (Triple.substr(0, 6) == "x86_64")
2331 Triple.replace(0, 6, "amd64");
Daniel Dunbarf7fb31f2009-10-29 02:24:37 +00002332 CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
2333 "/3.3.5"));
Daniel Dunbar2bbcf662009-08-03 01:28:59 +00002334
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002335 Args.AddAllArgs(CmdArgs, options::OPT_L);
2336 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2337 Args.AddAllArgs(CmdArgs, options::OPT_e);
2338
2339 for (InputInfoList::const_iterator
2340 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2341 const InputInfo &II = *it;
2342
2343 // Don't try to pass LLVM inputs to a generic gcc.
2344 if (II.getType() == types::TY_LLVMBC)
2345 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00002346 << getToolChain().getTripleString();
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002347
2348 if (II.isPipe())
2349 CmdArgs.push_back("-");
2350 else if (II.isFilename())
2351 CmdArgs.push_back(II.getFilename());
2352 else
2353 II.getInputArg().renderAsInput(Args, CmdArgs);
2354 }
2355
2356 if (!Args.hasArg(options::OPT_nostdlib) &&
2357 !Args.hasArg(options::OPT_nodefaultlibs)) {
Daniel Dunbar2bbcf662009-08-03 01:28:59 +00002358 // FIXME: For some reason GCC passes -lgcc before adding
2359 // the default system libraries. Just mimic this for now.
2360 CmdArgs.push_back("-lgcc");
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002361
2362 if (Args.hasArg(options::OPT_pthread))
2363 CmdArgs.push_back("-pthread");
Daniel Dunbar2bbcf662009-08-03 01:28:59 +00002364 if (!Args.hasArg(options::OPT_shared))
2365 CmdArgs.push_back("-lc");
2366 CmdArgs.push_back("-lgcc");
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002367 }
2368
2369 if (!Args.hasArg(options::OPT_nostdlib) &&
2370 !Args.hasArg(options::OPT_nostartfiles)) {
2371 if (!Args.hasArg(options::OPT_shared))
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002372 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002373 else
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002374 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002375 }
2376
2377 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002378 Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002379 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbarf7b8eec2009-06-29 20:52:51 +00002380}
Ed Schoutenc66a5a32009-04-02 19:13:12 +00002381
Daniel Dunbar68a31d42009-03-31 17:45:15 +00002382void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002383 Job &Dest, const InputInfo &Output,
2384 const InputInfoList &Inputs,
2385 const ArgList &Args,
Mike Stump1eb44332009-09-09 15:08:12 +00002386 const char *LinkingOutput) const {
Daniel Dunbar68a31d42009-03-31 17:45:15 +00002387 ArgStringList CmdArgs;
2388
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002389 // When building 32-bit code on FreeBSD/amd64, we have to explicitly
2390 // instruct as in the base system to assemble 32-bit code.
2391 if (getToolChain().getArchName() == "i386")
Daniel Dunbar68a31d42009-03-31 17:45:15 +00002392 CmdArgs.push_back("--32");
2393
2394 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2395 options::OPT_Xassembler);
2396
2397 CmdArgs.push_back("-o");
2398 if (Output.isPipe())
2399 CmdArgs.push_back("-");
2400 else
2401 CmdArgs.push_back(Output.getFilename());
2402
2403 for (InputInfoList::const_iterator
2404 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2405 const InputInfo &II = *it;
2406 if (II.isPipe())
2407 CmdArgs.push_back("-");
2408 else
2409 CmdArgs.push_back(II.getFilename());
2410 }
2411
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002412 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002413 Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002414 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar68a31d42009-03-31 17:45:15 +00002415}
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002416
2417void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002418 Job &Dest, const InputInfo &Output,
2419 const InputInfoList &Inputs,
2420 const ArgList &Args,
Daniel Dunbara8304f62009-05-02 20:14:53 +00002421 const char *LinkingOutput) const {
2422 const Driver &D = getToolChain().getHost().getDriver();
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002423 ArgStringList CmdArgs;
2424
2425 if (Args.hasArg(options::OPT_static)) {
2426 CmdArgs.push_back("-Bstatic");
2427 } else {
2428 CmdArgs.push_back("--eh-frame-hdr");
2429 if (Args.hasArg(options::OPT_shared)) {
2430 CmdArgs.push_back("-Bshareable");
2431 } else {
2432 CmdArgs.push_back("-dynamic-linker");
2433 CmdArgs.push_back("/libexec/ld-elf.so.1");
2434 }
2435 }
2436
2437 // When building 32-bit code on FreeBSD/amd64, we have to explicitly
2438 // instruct ld in the base system to link 32-bit code.
2439 if (getToolChain().getArchName() == "i386") {
2440 CmdArgs.push_back("-m");
2441 CmdArgs.push_back("elf_i386_fbsd");
2442 }
2443
2444 if (Output.isPipe()) {
2445 CmdArgs.push_back("-o");
2446 CmdArgs.push_back("-");
2447 } else if (Output.isFilename()) {
2448 CmdArgs.push_back("-o");
2449 CmdArgs.push_back(Output.getFilename());
2450 } else {
2451 assert(Output.isNothing() && "Invalid output.");
2452 }
2453
2454 if (!Args.hasArg(options::OPT_nostdlib) &&
2455 !Args.hasArg(options::OPT_nostartfiles)) {
2456 if (!Args.hasArg(options::OPT_shared)) {
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002457 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
2458 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2459 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002460 } else {
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002461 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2462 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002463 }
2464 }
2465
2466 Args.AddAllArgs(CmdArgs, options::OPT_L);
2467 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2468 Args.AddAllArgs(CmdArgs, options::OPT_e);
2469
2470 for (InputInfoList::const_iterator
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002471 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002472 const InputInfo &II = *it;
Daniel Dunbara8304f62009-05-02 20:14:53 +00002473
2474 // Don't try to pass LLVM inputs to a generic gcc.
2475 if (II.getType() == types::TY_LLVMBC)
2476 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00002477 << getToolChain().getTripleString();
Daniel Dunbara8304f62009-05-02 20:14:53 +00002478
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002479 if (II.isPipe())
2480 CmdArgs.push_back("-");
2481 else if (II.isFilename())
2482 CmdArgs.push_back(II.getFilename());
2483 else
2484 II.getInputArg().renderAsInput(Args, CmdArgs);
2485 }
2486
2487 if (!Args.hasArg(options::OPT_nostdlib) &&
2488 !Args.hasArg(options::OPT_nodefaultlibs)) {
2489 // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
2490 // the default system libraries. Just mimic this for now.
2491 CmdArgs.push_back("-lgcc");
2492 if (Args.hasArg(options::OPT_static)) {
2493 CmdArgs.push_back("-lgcc_eh");
2494 } else {
2495 CmdArgs.push_back("--as-needed");
2496 CmdArgs.push_back("-lgcc_s");
2497 CmdArgs.push_back("--no-as-needed");
2498 }
2499
2500 if (Args.hasArg(options::OPT_pthread))
2501 CmdArgs.push_back("-lpthread");
2502 CmdArgs.push_back("-lc");
2503
2504 CmdArgs.push_back("-lgcc");
2505 if (Args.hasArg(options::OPT_static)) {
2506 CmdArgs.push_back("-lgcc_eh");
2507 } else {
2508 CmdArgs.push_back("--as-needed");
2509 CmdArgs.push_back("-lgcc_s");
2510 CmdArgs.push_back("--no-as-needed");
2511 }
2512 }
2513
2514 if (!Args.hasArg(options::OPT_nostdlib) &&
2515 !Args.hasArg(options::OPT_nostartfiles)) {
2516 if (!Args.hasArg(options::OPT_shared))
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002517 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002518 else
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002519 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
2520 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002521 }
2522
Daniel Dunbarc21c4852009-04-08 23:54:23 +00002523 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002524 Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002525 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar008f54a2009-04-01 19:36:32 +00002526}
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002527
2528/// DragonFly Tools
2529
2530// For now, DragonFly Assemble does just about the same as for
2531// FreeBSD, but this may change soon.
2532void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2533 Job &Dest, const InputInfo &Output,
2534 const InputInfoList &Inputs,
2535 const ArgList &Args,
2536 const char *LinkingOutput) const {
2537 ArgStringList CmdArgs;
2538
2539 // When building 32-bit code on DragonFly/pc64, we have to explicitly
2540 // instruct as in the base system to assemble 32-bit code.
2541 if (getToolChain().getArchName() == "i386")
2542 CmdArgs.push_back("--32");
2543
2544 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2545 options::OPT_Xassembler);
2546
2547 CmdArgs.push_back("-o");
2548 if (Output.isPipe())
2549 CmdArgs.push_back("-");
2550 else
2551 CmdArgs.push_back(Output.getFilename());
2552
2553 for (InputInfoList::const_iterator
2554 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2555 const InputInfo &II = *it;
2556 if (II.isPipe())
2557 CmdArgs.push_back("-");
2558 else
2559 CmdArgs.push_back(II.getFilename());
2560 }
2561
2562 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002563 Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002564 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002565}
2566
2567void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
2568 Job &Dest, const InputInfo &Output,
2569 const InputInfoList &Inputs,
2570 const ArgList &Args,
2571 const char *LinkingOutput) const {
Daniel Dunbara8304f62009-05-02 20:14:53 +00002572 const Driver &D = getToolChain().getHost().getDriver();
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002573 ArgStringList CmdArgs;
2574
2575 if (Args.hasArg(options::OPT_static)) {
2576 CmdArgs.push_back("-Bstatic");
2577 } else {
2578 if (Args.hasArg(options::OPT_shared))
2579 CmdArgs.push_back("-Bshareable");
2580 else {
2581 CmdArgs.push_back("-dynamic-linker");
2582 CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
2583 }
2584 }
2585
2586 // When building 32-bit code on DragonFly/pc64, we have to explicitly
2587 // instruct ld in the base system to link 32-bit code.
2588 if (getToolChain().getArchName() == "i386") {
2589 CmdArgs.push_back("-m");
2590 CmdArgs.push_back("elf_i386");
2591 }
2592
2593 if (Output.isPipe()) {
2594 CmdArgs.push_back("-o");
2595 CmdArgs.push_back("-");
2596 } else if (Output.isFilename()) {
2597 CmdArgs.push_back("-o");
2598 CmdArgs.push_back(Output.getFilename());
2599 } else {
2600 assert(Output.isNothing() && "Invalid output.");
2601 }
2602
2603 if (!Args.hasArg(options::OPT_nostdlib) &&
2604 !Args.hasArg(options::OPT_nostartfiles)) {
2605 if (!Args.hasArg(options::OPT_shared)) {
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002606 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
2607 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2608 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002609 } else {
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002610 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2611 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002612 }
2613 }
2614
2615 Args.AddAllArgs(CmdArgs, options::OPT_L);
2616 Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2617 Args.AddAllArgs(CmdArgs, options::OPT_e);
2618
2619 for (InputInfoList::const_iterator
2620 it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2621 const InputInfo &II = *it;
Daniel Dunbara8304f62009-05-02 20:14:53 +00002622
2623 // Don't try to pass LLVM inputs to a generic gcc.
2624 if (II.getType() == types::TY_LLVMBC)
2625 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
Daniel Dunbar88137642009-09-09 22:32:48 +00002626 << getToolChain().getTripleString();
Daniel Dunbara8304f62009-05-02 20:14:53 +00002627
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002628 if (II.isPipe())
2629 CmdArgs.push_back("-");
2630 else if (II.isFilename())
2631 CmdArgs.push_back(II.getFilename());
2632 else
2633 II.getInputArg().renderAsInput(Args, CmdArgs);
2634 }
2635
2636 if (!Args.hasArg(options::OPT_nostdlib) &&
2637 !Args.hasArg(options::OPT_nodefaultlibs)) {
2638 // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
2639 // rpaths
2640 CmdArgs.push_back("-L/usr/lib/gcc41");
2641
2642 if (!Args.hasArg(options::OPT_static)) {
2643 CmdArgs.push_back("-rpath");
2644 CmdArgs.push_back("/usr/lib/gcc41");
2645
2646 CmdArgs.push_back("-rpath-link");
2647 CmdArgs.push_back("/usr/lib/gcc41");
2648
2649 CmdArgs.push_back("-rpath");
2650 CmdArgs.push_back("/usr/lib");
2651
2652 CmdArgs.push_back("-rpath-link");
2653 CmdArgs.push_back("/usr/lib");
2654 }
2655
2656 if (Args.hasArg(options::OPT_shared)) {
2657 CmdArgs.push_back("-lgcc_pic");
2658 } else {
2659 CmdArgs.push_back("-lgcc");
2660 }
2661
2662
2663 if (Args.hasArg(options::OPT_pthread))
2664 CmdArgs.push_back("-lthread_xu");
2665
2666 if (!Args.hasArg(options::OPT_nolibc)) {
2667 CmdArgs.push_back("-lc");
2668 }
2669
2670 if (Args.hasArg(options::OPT_shared)) {
2671 CmdArgs.push_back("-lgcc_pic");
2672 } else {
2673 CmdArgs.push_back("-lgcc");
2674 }
2675 }
2676
2677 if (!Args.hasArg(options::OPT_nostdlib) &&
2678 !Args.hasArg(options::OPT_nostartfiles)) {
2679 if (!Args.hasArg(options::OPT_shared))
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002680 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002681 else
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002682 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
2683 CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002684 }
2685
2686 const char *Exec =
Daniel Dunbar5ed34f42009-09-09 22:33:00 +00002687 Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
Daniel Dunbarcae087e2009-07-01 19:02:28 +00002688 Dest.addCommand(new Command(JA, Exec, CmdArgs));
Daniel Dunbar11e1b402009-05-02 18:28:39 +00002689}