Tools.cpp revision a91320b8af7143f7af4c0665ffa62a3b244c0bd9
1//===--- 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
12#include "clang/Basic/Version.h"
13#include "clang/Driver/Action.h"
14#include "clang/Driver/Arg.h"
15#include "clang/Driver/ArgList.h"
16#include "clang/Driver/Driver.h"
17#include "clang/Driver/DriverDiagnostic.h"
18#include "clang/Driver/Compilation.h"
19#include "clang/Driver/Job.h"
20#include "clang/Driver/HostInfo.h"
21#include "clang/Driver/Option.h"
22#include "clang/Driver/Options.h"
23#include "clang/Driver/ToolChain.h"
24#include "clang/Driver/Util.h"
25
26#include "llvm/ADT/SmallString.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/ADT/Twine.h"
29#include "llvm/Support/Format.h"
30#include "llvm/Support/raw_ostream.h"
31#include "llvm/System/Host.h"
32#include "llvm/System/Process.h"
33
34#include "InputInfo.h"
35#include "ToolChains.h"
36
37using namespace clang::driver;
38using namespace clang::driver::tools;
39
40/// CheckPreprocessingOptions - Perform some validation of preprocessing
41/// arguments that is shared with gcc.
42static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
43  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
44    if (!Args.hasArg(options::OPT_E))
45      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
46        << A->getAsString(Args) << "-E";
47}
48
49/// CheckCodeGenerationOptions - Perform some validation of code generation
50/// arguments that is shared with gcc.
51static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
52  // In gcc, only ARM checks this, but it seems reasonable to check universally.
53  if (Args.hasArg(options::OPT_static))
54    if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
55                                       options::OPT_mdynamic_no_pic))
56      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
57        << A->getAsString(Args) << "-static";
58}
59
60void Clang::AddPreprocessingOptions(const Driver &D,
61                                    const ArgList &Args,
62                                    ArgStringList &CmdArgs,
63                                    const InputInfo &Output,
64                                    const InputInfoList &Inputs) const {
65  Arg *A;
66
67  CheckPreprocessingOptions(D, Args);
68
69  Args.AddLastArg(CmdArgs, options::OPT_C);
70  Args.AddLastArg(CmdArgs, options::OPT_CC);
71
72  // Handle dependency file generation.
73  if ((A = Args.getLastArg(options::OPT_M)) ||
74      (A = Args.getLastArg(options::OPT_MM)) ||
75      (A = Args.getLastArg(options::OPT_MD)) ||
76      (A = Args.getLastArg(options::OPT_MMD))) {
77    // Determine the output location.
78    const char *DepFile;
79    if (Output.getType() == types::TY_Dependencies) {
80      if (Output.isPipe())
81        DepFile = "-";
82      else
83        DepFile = Output.getFilename();
84    } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
85      DepFile = MF->getValue(Args);
86    } else if (A->getOption().matches(options::OPT_M) ||
87               A->getOption().matches(options::OPT_MM)) {
88      DepFile = "-";
89    } else {
90      DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
91    }
92    CmdArgs.push_back("-dependency-file");
93    CmdArgs.push_back(DepFile);
94
95    // Add an -MT option if the user didn't specify their own.
96    //
97    // FIXME: This should use -MQ, when we support it.
98    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
99      const char *DepTarget;
100
101      // If user provided -o, that is the dependency target, except
102      // when we are only generating a dependency file.
103      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
104      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
105        DepTarget = OutputOpt->getValue(Args);
106      } else {
107        // Otherwise derive from the base input.
108        //
109        // FIXME: This should use the computed output file location.
110        llvm::sys::Path P(Inputs[0].getBaseInput());
111
112        P.eraseSuffix();
113        P.appendSuffix("o");
114        DepTarget = Args.MakeArgString(P.getLast());
115      }
116
117      CmdArgs.push_back("-MT");
118      CmdArgs.push_back(DepTarget);
119    }
120
121    if (A->getOption().matches(options::OPT_M) ||
122        A->getOption().matches(options::OPT_MD))
123      CmdArgs.push_back("-sys-header-deps");
124  }
125
126  Args.AddLastArg(CmdArgs, options::OPT_MP);
127  Args.AddAllArgs(CmdArgs, options::OPT_MT);
128
129  // Add -i* options, and automatically translate to
130  // -include-pch/-include-pth for transparent PCH support. It's
131  // wonky, but we include looking for .gch so we can support seamless
132  // replacement into a build system already set up to be generating
133  // .gch files.
134  for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
135         ie = Args.filtered_end(); it != ie; ++it) {
136    const Arg *A = it;
137
138    if (A->getOption().matches(options::OPT_include)) {
139      // 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
144      bool FoundPTH = false;
145      bool FoundPCH = false;
146      llvm::sys::Path P(A->getValue(Args));
147      if (UsePCH) {
148        P.appendSuffix("pch");
149        if (P.exists())
150          FoundPCH = true;
151        else
152          P.eraseSuffix();
153      }
154
155      if (!FoundPCH) {
156        P.appendSuffix("pth");
157        if (P.exists())
158          FoundPTH = true;
159        else
160          P.eraseSuffix();
161      }
162
163      if (!FoundPCH && !FoundPTH) {
164        P.appendSuffix("gch");
165        if (P.exists()) {
166          FoundPCH = UsePCH;
167          FoundPTH = !UsePCH;
168        }
169        else
170          P.eraseSuffix();
171      }
172
173      if (FoundPCH || FoundPTH) {
174        A->claim();
175        if (UsePCH)
176          CmdArgs.push_back("-include-pch");
177        else
178          CmdArgs.push_back("-include-pth");
179        CmdArgs.push_back(Args.MakeArgString(P.str()));
180        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);
200
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);
204}
205
206/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
207//
208// FIXME: tblgen this.
209static const char *getARMTargetCPU(const ArgList &Args) {
210  // FIXME: Warn on inconsistent use of -mcpu and -march.
211
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 "arm926ej-s";
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
260/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
261/// CPU.
262//
263// FIXME: This is redundant with -mcpu, why does LLVM use this.
264// FIXME: tblgen this, or kill it!
265static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
266  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")
270    return "v4t";
271
272  if (CPU == "arm10tdmi" || CPU == "arm1020t")
273    return "v5";
274
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")
279    return "v5e";
280
281  if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" ||
282      CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore")
283    return "v6";
284
285  if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s")
286    return "v6t2";
287
288  if (CPU == "cortex-a8" || CPU == "cortex-a9")
289    return "v7";
290
291  return "";
292}
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: {
303    // FIXME: Factor into subclasses.
304    llvm::Triple Triple = TC.getTriple();
305
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);
312    std::string ArchName = "arm";
313    if (Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
314      ArchName = "thumb";
315    Triple.setArchName(ArchName + Suffix.str());
316
317    return Triple.getTriple();
318  }
319  }
320}
321
322// FIXME: Move to target hook.
323static bool isSignedCharDefault(const llvm::Triple &Triple) {
324  switch (Triple.getArch()) {
325  default:
326    return true;
327
328  case llvm::Triple::ppc:
329  case llvm::Triple::ppc64:
330    if (Triple.getOS() == llvm::Triple::Darwin)
331      return true;
332    return false;
333
334  case llvm::Triple::systemz:
335    return false;
336  }
337}
338
339void Clang::AddARMTargetArgs(const ArgList &Args,
340                             ArgStringList &CmdArgs) const {
341  const Driver &D = getToolChain().getDriver();
342
343  // Select the ABI to use.
344  //
345  // FIXME: Support -meabi.
346  const char *ABIName = 0;
347  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
348    ABIName = A->getValue(Args);
349  } else {
350    // Select the default based on the platform.
351    switch (getToolChain().getTriple().getOS()) {
352      // FIXME: Is this right for non-Darwin and non-Linux?
353    default:
354      ABIName = "aapcs";
355      break;
356
357    case llvm::Triple::Darwin:
358      ABIName = "apcs-gnu";
359      break;
360
361    case llvm::Triple::Linux:
362      ABIName = "aapcs-linux";
363      break;
364    }
365  }
366  CmdArgs.push_back("-target-abi");
367  CmdArgs.push_back(ABIName);
368
369  // Set the CPU based on -march= and -mcpu=.
370  CmdArgs.push_back("-target-cpu");
371  CmdArgs.push_back(getARMTargetCPU(Args));
372
373  // Select the float ABI as determined by -msoft-float, -mhard-float, and
374  // -mfloat-abi=.
375  llvm::StringRef FloatABI;
376  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
377                               options::OPT_mhard_float,
378                               options::OPT_mfloat_abi_EQ)) {
379    if (A->getOption().matches(options::OPT_msoft_float))
380      FloatABI = "soft";
381    else if (A->getOption().matches(options::OPT_mhard_float))
382      FloatABI = "hard";
383    else {
384      FloatABI = A->getValue(Args);
385      if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
386        D.Diag(clang::diag::err_drv_invalid_mfloat_abi)
387          << A->getAsString(Args);
388        FloatABI = "soft";
389      }
390    }
391  }
392
393  // If unspecified, choose the default based on the platform.
394  if (FloatABI.empty()) {
395    // FIXME: This is wrong for non-Darwin, we don't have a mechanism yet for
396    // distinguishing things like linux-eabi vs linux-elf.
397    switch (getToolChain().getTriple().getOS()) {
398    case llvm::Triple::Darwin: {
399      // Darwin defaults to "softfp" for v6 and v7.
400      //
401      // FIXME: Factor out an ARM class so we can cache the arch somewhere.
402      llvm::StringRef ArchName = getLLVMArchSuffixForARM(getARMTargetCPU(Args));
403      if (ArchName.startswith("v6") || ArchName.startswith("v7"))
404        FloatABI = "softfp";
405      else
406        FloatABI = "soft";
407      break;
408    }
409
410    default:
411      // Assume "soft", but warn the user we are guessing.
412      FloatABI = "soft";
413      D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
414      break;
415    }
416  }
417
418  if (FloatABI == "soft") {
419    // Floating point operations and argument passing are soft.
420    //
421    // FIXME: This changes CPP defines, we need -target-soft-float.
422    CmdArgs.push_back("-msoft-float");
423    CmdArgs.push_back("-mfloat-abi");
424    CmdArgs.push_back("soft");
425  } else if (FloatABI == "softfp") {
426    // Floating point operations are hard, but argument passing is soft.
427    CmdArgs.push_back("-mfloat-abi");
428    CmdArgs.push_back("soft");
429  } else {
430    // Floating point operations and argument passing are hard.
431    assert(FloatABI == "hard" && "Invalid float abi!");
432    CmdArgs.push_back("-mfloat-abi");
433    CmdArgs.push_back("hard");
434  }
435
436  // Set appropriate target features for floating point mode.
437  //
438  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
439  // yet (it uses the -mfloat-abi and -msoft-float options above), and it is
440  // stripped out by the ARM target.
441
442  // Use software floating point operations?
443  if (FloatABI == "soft") {
444    CmdArgs.push_back("-target-feature");
445    CmdArgs.push_back("+soft-float");
446  }
447
448  // Use software floating point argument passing?
449  if (FloatABI != "hard") {
450    CmdArgs.push_back("-target-feature");
451    CmdArgs.push_back("+soft-float-abi");
452  }
453
454  // Honor -mfpu=.
455  //
456  // FIXME: Centralize feature selection, defaulting shouldn't be also in the
457  // frontend target.
458  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
459    llvm::StringRef FPU = A->getValue(Args);
460
461    // Set the target features based on the FPU.
462    if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
463      // Disable any default FPU support.
464      CmdArgs.push_back("-target-feature");
465      CmdArgs.push_back("-vfp2");
466      CmdArgs.push_back("-target-feature");
467      CmdArgs.push_back("-vfp3");
468      CmdArgs.push_back("-target-feature");
469      CmdArgs.push_back("-neon");
470    } else if (FPU == "vfp") {
471      CmdArgs.push_back("-target-feature");
472      CmdArgs.push_back("+vfp2");
473    } else if (FPU == "vfp3") {
474      CmdArgs.push_back("-target-feature");
475      CmdArgs.push_back("+vfp3");
476    } else if (FPU == "neon") {
477      CmdArgs.push_back("-target-feature");
478      CmdArgs.push_back("+neon");
479    } else
480      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
481  }
482}
483
484void Clang::AddX86TargetArgs(const ArgList &Args,
485                             ArgStringList &CmdArgs) const {
486  if (!Args.hasFlag(options::OPT_mred_zone,
487                    options::OPT_mno_red_zone,
488                    true) ||
489      Args.hasArg(options::OPT_mkernel) ||
490      Args.hasArg(options::OPT_fapple_kext))
491    CmdArgs.push_back("-disable-red-zone");
492
493  if (Args.hasFlag(options::OPT_msoft_float,
494                   options::OPT_mno_soft_float,
495                   false))
496    CmdArgs.push_back("-no-implicit-float");
497
498  const char *CPUName = 0;
499  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
500    if (llvm::StringRef(A->getValue(Args)) == "native") {
501      // FIXME: Reject attempts to use -march=native unless the target matches
502      // the host.
503      //
504      // FIXME: We should also incorporate the detected target features for use
505      // with -native.
506      std::string CPU = llvm::sys::getHostCPUName();
507      if (!CPU.empty())
508        CPUName = Args.MakeArgString(CPU);
509    } else
510      CPUName = A->getValue(Args);
511  }
512
513  // Select the default CPU if none was given (or detection failed).
514  if (!CPUName) {
515    // FIXME: Need target hooks.
516    if (memcmp(getToolChain().getOS().c_str(), "darwin", 6) == 0) {
517      if (getToolChain().getArchName() == "x86_64")
518        CPUName = "core2";
519      else if (getToolChain().getArchName() == "i386")
520        CPUName = "yonah";
521    } else {
522      if (getToolChain().getArchName() == "x86_64")
523        CPUName = "x86-64";
524      else if (getToolChain().getArchName() == "i386")
525        CPUName = "pentium4";
526    }
527  }
528
529  if (CPUName) {
530    CmdArgs.push_back("-target-cpu");
531    CmdArgs.push_back(CPUName);
532  }
533
534  for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
535         ie = Args.filtered_end(); it != ie; ++it) {
536    llvm::StringRef Name = it->getOption().getName();
537    it->claim();
538
539    // Skip over "-m".
540    assert(Name.startswith("-m") && "Invalid feature name.");
541    Name = Name.substr(2);
542
543    bool IsNegative = Name.startswith("no-");
544    if (IsNegative)
545      Name = Name.substr(3);
546
547    CmdArgs.push_back("-target-feature");
548    CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
549  }
550}
551
552static bool needsExceptions(const ArgList &Args,  types::ID InputType,
553                            const llvm::Triple &Triple) {
554  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
555                               options::OPT_fno_exceptions)) {
556    if (A->getOption().matches(options::OPT_fexceptions))
557      return true;
558    else
559      return false;
560  }
561  switch (InputType) {
562  case types::TY_CXX: case types::TY_CXXHeader:
563  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
564  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
565  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
566    return true;
567
568  case types::TY_ObjC: case types::TY_ObjCHeader:
569  case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
570    if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
571      return true;
572    if (Triple.getOS() != llvm::Triple::Darwin)
573      return false;
574    return (Triple.getDarwinMajorNumber() >= 9 &&
575            Triple.getArch() == llvm::Triple::x86_64);
576
577  default:
578    return false;
579  }
580}
581
582/// getEffectiveClangTriple - Get the "effective" target triple, which is the
583/// triple for the target but with the OS version potentially modified for
584/// Darwin's -mmacosx-version-min.
585static std::string getEffectiveClangTriple(const Driver &D,
586                                           const ToolChain &TC,
587                                           const ArgList &Args) {
588  llvm::Triple Triple(getLLVMTriple(TC, Args));
589
590  if (Triple.getOS() != llvm::Triple::Darwin) {
591    // Diagnose use of -mmacosx-version-min and -miphoneos-version-min on
592    // non-Darwin.
593    if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
594                                 options::OPT_miphoneos_version_min_EQ))
595      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
596    return Triple.getTriple();
597  }
598
599  // If -mmacosx-version-min=10.3.9 is specified, change the effective triple
600  // from being something like powerpc-apple-darwin9 to powerpc-apple-darwin7.
601  if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) {
602    unsigned Major, Minor, Micro;
603    bool HadExtra;
604    if (!Driver::GetReleaseVersion(A->getValue(Args), Major, Minor, Micro,
605                                   HadExtra) || HadExtra ||
606        Major != 10)
607      D.Diag(clang::diag::err_drv_invalid_version_number)
608        << A->getAsString(Args);
609
610    // Mangle the MacOS version min number into the Darwin number: e.g. 10.3.9
611    // is darwin7.9.
612    llvm::SmallString<16> Str;
613    llvm::raw_svector_ostream(Str) << "darwin" << Minor + 4 << "." << Micro;
614    Triple.setOSName(Str.str());
615  } else if (Arg *A = Args.getLastArg(options::OPT_miphoneos_version_min_EQ)) {
616    unsigned Major, Minor, Micro;
617    bool HadExtra;
618    if (!Driver::GetReleaseVersion(A->getValue(Args), Major, Minor, Micro,
619                                   HadExtra) || HadExtra)
620      D.Diag(clang::diag::err_drv_invalid_version_number)
621        << A->getAsString(Args);
622
623    // Mangle the iPhoneOS version number into the Darwin number: e.g. 2.0 is 2
624    // -> 9.2.0.
625    llvm::SmallString<16> Str;
626    llvm::raw_svector_ostream(Str) << "darwin9." << Major << "." << Minor;
627    Triple.setOSName(Str.str());
628  }
629
630  return Triple.getTriple();
631}
632
633void Clang::ConstructJob(Compilation &C, const JobAction &JA,
634                         Job &Dest,
635                         const InputInfo &Output,
636                         const InputInfoList &Inputs,
637                         const ArgList &Args,
638                         const char *LinkingOutput) const {
639  const Driver &D = getToolChain().getDriver();
640  ArgStringList CmdArgs;
641
642  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
643
644  // Invoke ourselves in -cc1 mode.
645  //
646  // FIXME: Implement custom jobs for internal actions.
647  CmdArgs.push_back("-cc1");
648
649  // Add the "effective" target triple.
650  CmdArgs.push_back("-triple");
651  std::string TripleStr = getEffectiveClangTriple(D, getToolChain(), Args);
652  CmdArgs.push_back(Args.MakeArgString(TripleStr));
653
654  // Select the appropriate action.
655  if (isa<AnalyzeJobAction>(JA)) {
656    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
657    CmdArgs.push_back("-analyze");
658  } else if (isa<PreprocessJobAction>(JA)) {
659    if (Output.getType() == types::TY_Dependencies)
660      CmdArgs.push_back("-Eonly");
661    else
662      CmdArgs.push_back("-E");
663  } else if (isa<PrecompileJobAction>(JA)) {
664    // Use PCH if the user requested it, except for C++ (for now).
665    bool UsePCH = D.CCCUsePCH;
666    if (types::isCXX(Inputs[0].getType()))
667      UsePCH = false;
668
669    if (UsePCH)
670      CmdArgs.push_back("-emit-pch");
671    else
672      CmdArgs.push_back("-emit-pth");
673  } else {
674    assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
675
676    if (JA.getType() == types::TY_Nothing) {
677      CmdArgs.push_back("-fsyntax-only");
678    } else if (JA.getType() == types::TY_LLVMAsm) {
679      CmdArgs.push_back("-emit-llvm");
680    } else if (JA.getType() == types::TY_LLVMBC) {
681      CmdArgs.push_back("-emit-llvm-bc");
682    } else if (JA.getType() == types::TY_PP_Asm) {
683      CmdArgs.push_back("-S");
684    } else if (JA.getType() == types::TY_AST) {
685      CmdArgs.push_back("-emit-pch");
686    }
687  }
688
689  // The make clang go fast button.
690  CmdArgs.push_back("-disable-free");
691
692  // Set the main file name, so that debug info works even with
693  // -save-temps.
694  CmdArgs.push_back("-main-file-name");
695  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
696
697  // Some flags which affect the language (via preprocessor
698  // defines). See darwin::CC1::AddCPPArgs.
699  if (Args.hasArg(options::OPT_static))
700    CmdArgs.push_back("-static-define");
701
702  if (isa<AnalyzeJobAction>(JA)) {
703    // Enable region store model by default.
704    CmdArgs.push_back("-analyzer-store=region");
705
706    // Treat blocks as analysis entry points.
707    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
708
709    // Add default argument set.
710    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
711      CmdArgs.push_back("-warn-dead-stores");
712      CmdArgs.push_back("-warn-security-syntactic");
713      CmdArgs.push_back("-checker-cfref");
714      CmdArgs.push_back("-analyzer-eagerly-assume");
715      CmdArgs.push_back("-warn-objc-methodsigs");
716      // Do not enable the missing -dealloc check.
717      // '-warn-objc-missing-dealloc',
718      CmdArgs.push_back("-warn-objc-unused-ivars");
719    }
720
721    // Set the output format. The default is plist, for (lame) historical
722    // reasons.
723    CmdArgs.push_back("-analyzer-output");
724    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
725      CmdArgs.push_back(A->getValue(Args));
726    else
727      CmdArgs.push_back("plist");
728
729    // Add -Xanalyzer arguments when running as analyzer.
730    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
731  }
732
733  CheckCodeGenerationOptions(D, Args);
734
735  // Perform argument translation for LLVM backend. This
736  // takes some care in reconciling with llvm-gcc. The
737  // issue is that llvm-gcc translates these options based on
738  // the values in cc1, whereas we are processing based on
739  // the driver arguments.
740
741  // This comes from the default translation the driver + cc1
742  // would do to enable flag_pic.
743  //
744  // FIXME: Centralize this code.
745  bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
746                     Args.hasArg(options::OPT_fpic) ||
747                     Args.hasArg(options::OPT_fPIE) ||
748                     Args.hasArg(options::OPT_fpie));
749  bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
750                      Args.hasArg(options::OPT_static));
751  const char *Model = getToolChain().GetForcedPicModel();
752  if (!Model) {
753    if (Args.hasArg(options::OPT_mdynamic_no_pic))
754      Model = "dynamic-no-pic";
755    else if (PICDisabled)
756      Model = "static";
757    else if (PICEnabled)
758      Model = "pic";
759    else
760      Model = getToolChain().GetDefaultRelocationModel();
761  }
762  if (llvm::StringRef(Model) != "pic") {
763    CmdArgs.push_back("-mrelocation-model");
764    CmdArgs.push_back(Model);
765  }
766
767  // Infer the __PIC__ value.
768  //
769  // FIXME:  This isn't quite right on Darwin, which always sets
770  // __PIC__=2.
771  if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
772    CmdArgs.push_back("-pic-level");
773    CmdArgs.push_back(Args.hasArg(options::OPT_fPIC) ? "2" : "1");
774  }
775  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
776                    options::OPT_fno_merge_all_constants))
777    CmdArgs.push_back("-no-merge-all-constants");
778
779  // LLVM Code Generator Options.
780
781  // FIXME: Set --enable-unsafe-fp-math.
782  if (Args.hasFlag(options::OPT_fno_omit_frame_pointer,
783                   options::OPT_fomit_frame_pointer))
784    CmdArgs.push_back("-mdisable-fp-elim");
785  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
786                    options::OPT_fno_zero_initialized_in_bss))
787    CmdArgs.push_back("-mno-zero-initialized-in-bss");
788  if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm))
789    CmdArgs.push_back("-masm-verbose");
790  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
791    CmdArgs.push_back("-mdebug-pass");
792    CmdArgs.push_back("Structure");
793  }
794  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
795    CmdArgs.push_back("-mdebug-pass");
796    CmdArgs.push_back("Arguments");
797  }
798
799  // This is a coarse approximation of what llvm-gcc actually does, both
800  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
801  // complicated ways.
802  bool AsynchronousUnwindTables =
803    Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
804                 options::OPT_fno_asynchronous_unwind_tables,
805                 getToolChain().IsUnwindTablesDefault() &&
806                 !Args.hasArg(options::OPT_mkernel));
807  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
808                   AsynchronousUnwindTables))
809    CmdArgs.push_back("-munwind-tables");
810
811  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
812    CmdArgs.push_back("-mlimit-float-precision");
813    CmdArgs.push_back(A->getValue(Args));
814  }
815
816  // FIXME: Handle -mtune=.
817  (void) Args.hasArg(options::OPT_mtune_EQ);
818
819  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
820    CmdArgs.push_back("-mcode-model");
821    CmdArgs.push_back(A->getValue(Args));
822  }
823
824  // Add target specific cpu and features flags.
825  switch(getToolChain().getTriple().getArch()) {
826  default:
827    break;
828
829  case llvm::Triple::arm:
830  case llvm::Triple::thumb:
831    AddARMTargetArgs(Args, CmdArgs);
832    break;
833
834  case llvm::Triple::x86:
835  case llvm::Triple::x86_64:
836    AddX86TargetArgs(Args, CmdArgs);
837    break;
838  }
839
840  // -fmath-errno is default.
841  if (!Args.hasFlag(options::OPT_fmath_errno,
842                   options::OPT_fno_math_errno,
843                   getToolChain().IsMathErrnoDefault()))
844    CmdArgs.push_back("-fno-math-errno");
845
846  Arg *Unsupported;
847  if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
848      (Unsupported = Args.getLastArg(options::OPT_MQ)) ||
849      (Unsupported = Args.getLastArg(options::OPT_iframework)) ||
850      (Unsupported = Args.getLastArg(options::OPT_fshort_enums)))
851    D.Diag(clang::diag::err_drv_clang_unsupported)
852      << Unsupported->getOption().getName();
853
854  Args.AddAllArgs(CmdArgs, options::OPT_v);
855  Args.AddLastArg(CmdArgs, options::OPT_P);
856  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
857
858  // Special case debug options to only pass -g to clang. This is
859  // wrong.
860  if (Args.hasArg(options::OPT_g_Group))
861    CmdArgs.push_back("-g");
862
863  Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
864  Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
865
866  // Pass the path to compiler resource files.
867  //
868  // FIXME: Get this from a configuration object.
869  llvm::sys::Path P(D.Dir);
870  P.eraseComponent(); // Remove /bin from foo/bin
871  P.appendComponent("lib");
872  P.appendComponent("clang");
873  P.appendComponent(CLANG_VERSION_STRING);
874  CmdArgs.push_back("-resource-dir");
875  CmdArgs.push_back(Args.MakeArgString(P.str()));
876
877  // Add preprocessing options like -I, -D, etc. if we are using the
878  // preprocessor.
879  //
880  // FIXME: Support -fpreprocessed
881  types::ID InputType = Inputs[0].getType();
882  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
883    AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
884
885  // Manually translate -O to -O2 and -O4 to -O3; let clang reject
886  // others.
887  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
888    if (A->getOption().matches(options::OPT_O4))
889      CmdArgs.push_back("-O3");
890    else if (A->getValue(Args)[0] == '\0')
891      CmdArgs.push_back("-O2");
892    else
893      A->render(Args, CmdArgs);
894  }
895
896  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
897  Args.AddLastArg(CmdArgs, options::OPT_pedantic);
898  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
899  Args.AddLastArg(CmdArgs, options::OPT_w);
900
901  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
902  // (-ansi is equivalent to -std=c89).
903  //
904  // If a std is supplied, only add -trigraphs if it follows the
905  // option.
906  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
907    if (Std->getOption().matches(options::OPT_ansi))
908      if (types::isCXX(InputType))
909        CmdArgs.push_back("-std=c++98");
910      else
911        CmdArgs.push_back("-std=c89");
912    else
913      Std->render(Args, CmdArgs);
914
915    if (Arg *A = Args.getLastArg(options::OPT_trigraphs))
916      if (A->getIndex() > Std->getIndex())
917        A->render(Args, CmdArgs);
918  } else {
919    // Honor -std-default.
920    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
921                              "-std=", /*Joined=*/true);
922    Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
923  }
924
925  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
926    CmdArgs.push_back("-ftemplate-depth");
927    CmdArgs.push_back(A->getValue(Args));
928  }
929
930  if (Args.hasArg(options::OPT__relocatable_pch))
931    CmdArgs.push_back("-relocatable-pch");
932
933  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
934    CmdArgs.push_back("-fconstant-string-class");
935    CmdArgs.push_back(A->getValue(Args));
936  }
937
938  // Pass -fmessage-length=.
939  CmdArgs.push_back("-fmessage-length");
940  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
941    CmdArgs.push_back(A->getValue(Args));
942  } else {
943    // If -fmessage-length=N was not specified, determine whether this is a
944    // terminal and, if so, implicitly define -fmessage-length appropriately.
945    unsigned N = llvm::sys::Process::StandardErrColumns();
946    CmdArgs.push_back(Args.MakeArgString(llvm::Twine(N)));
947  }
948
949  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
950    CmdArgs.push_back("-fvisibility");
951    CmdArgs.push_back(A->getValue(Args));
952  }
953
954  // Forward -f (flag) options which we can pass directly.
955  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
956  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
957  Args.AddLastArg(CmdArgs, options::OPT_ffreestanding);
958  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
959  Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions);
960  Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics);
961  Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
962  Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only);
963  Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
964  Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
965  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
966  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
967  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
968  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
969
970  Args.AddLastArg(CmdArgs, options::OPT_pthread);
971
972  // -stack-protector=0 is default.
973  unsigned StackProtectorLevel = 0;
974  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
975                               options::OPT_fstack_protector_all,
976                               options::OPT_fstack_protector)) {
977    if (A->getOption().matches(options::OPT_fstack_protector))
978      StackProtectorLevel = 1;
979    else if (A->getOption().matches(options::OPT_fstack_protector_all))
980      StackProtectorLevel = 2;
981  } else
982    StackProtectorLevel = getToolChain().GetDefaultStackProtectorLevel();
983  if (StackProtectorLevel) {
984    CmdArgs.push_back("-stack-protector");
985    CmdArgs.push_back(Args.MakeArgString(llvm::Twine(StackProtectorLevel)));
986  }
987
988  // Forward -f options with positive and negative forms; we translate
989  // these by hand.
990
991  // -fbuiltin is default.
992  if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
993    CmdArgs.push_back("-fno-builtin");
994
995  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
996                    options::OPT_fno_assume_sane_operator_new))
997    CmdArgs.push_back("-fno-assume-sane-operator-new");
998
999  // -fblocks=0 is default.
1000  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
1001                   getToolChain().IsBlocksDefault())) {
1002    Args.AddLastArg(CmdArgs, options::OPT_fblock_introspection);
1003    CmdArgs.push_back("-fblocks");
1004  }
1005
1006  // -fexceptions=0 is default.
1007  if (needsExceptions(Args, InputType, getToolChain().getTriple()))
1008    CmdArgs.push_back("-fexceptions");
1009
1010  // -frtti is default.
1011  if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
1012    CmdArgs.push_back("-fno-rtti");
1013
1014  // -fsigned-char is default.
1015  if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
1016                    isSignedCharDefault(getToolChain().getTriple())))
1017    CmdArgs.push_back("-fno-signed-char");
1018
1019  // -fms-extensions=0 is default.
1020  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1021                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
1022    CmdArgs.push_back("-fms-extensions");
1023
1024  // -fnext-runtime is default.
1025  if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
1026                    getToolChain().getTriple().getOS() == llvm::Triple::Darwin))
1027    CmdArgs.push_back("-fgnu-runtime");
1028
1029  // -fobjc-nonfragile-abi=0 is default.
1030  if (types::isObjC(InputType)) {
1031    if (Args.hasArg(options::OPT_fobjc_nonfragile_abi) ||
1032        getToolChain().IsObjCNonFragileABIDefault())
1033      CmdArgs.push_back("-fobjc-nonfragile-abi");
1034  }
1035
1036  // -fshort-wchar default varies depending on platform; only
1037  // pass if specified.
1038  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar)) {
1039    if (A->getOption().matches(options::OPT_fshort_wchar))
1040      CmdArgs.push_back("-fshort-wchar");
1041  }
1042
1043  // -fno-pascal-strings is default, only pass non-default. If the tool chain
1044  // happened to translate to -mpascal-strings, we want to back translate here.
1045  //
1046  // FIXME: This is gross; that translation should be pulled from the
1047  // tool chain.
1048  if (Args.hasFlag(options::OPT_fpascal_strings,
1049                   options::OPT_fno_pascal_strings,
1050                   false) ||
1051      Args.hasFlag(options::OPT_mpascal_strings,
1052                   options::OPT_mno_pascal_strings,
1053                   false))
1054    CmdArgs.push_back("-fpascal-strings");
1055
1056  // -fcommon is default, only pass non-default.
1057  if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
1058    CmdArgs.push_back("-fno-common");
1059
1060  // -fsigned-bitfields is default, and clang doesn't yet support
1061  // --funsigned-bitfields.
1062  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
1063                    options::OPT_funsigned_bitfields))
1064    D.Diag(clang::diag::warn_drv_clang_unsupported)
1065      << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
1066
1067  // -fdiagnostics-fixit-info is default, only pass non-default.
1068  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
1069                    options::OPT_fno_diagnostics_fixit_info))
1070    CmdArgs.push_back("-fno-diagnostics-fixit-info");
1071
1072  // Enable -fdiagnostics-show-option by default.
1073  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
1074                   options::OPT_fno_diagnostics_show_option))
1075    CmdArgs.push_back("-fdiagnostics-show-option");
1076
1077  // Color diagnostics are the default, unless the terminal doesn't support
1078  // them.
1079  if (Args.hasFlag(options::OPT_fcolor_diagnostics,
1080                   options::OPT_fno_color_diagnostics) &&
1081      llvm::sys::Process::StandardErrHasColors())
1082    CmdArgs.push_back("-fcolor-diagnostics");
1083
1084  if (!Args.hasFlag(options::OPT_fshow_source_location,
1085                    options::OPT_fno_show_source_location))
1086    CmdArgs.push_back("-fno-show-source-location");
1087
1088  // -fdollars-in-identifiers default varies depending on platform and
1089  // language; only pass if specified.
1090  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
1091                               options::OPT_fno_dollars_in_identifiers)) {
1092    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
1093      CmdArgs.push_back("-fdollars-in-identifiers");
1094    else
1095      CmdArgs.push_back("-fno-dollars-in-identifiers");
1096  }
1097
1098  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
1099  // practical purposes.
1100  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
1101                               options::OPT_fno_unit_at_a_time)) {
1102    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
1103      D.Diag(clang::diag::warn_drv_clang_unsupported) << A->getAsString(Args);
1104  }
1105
1106  // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
1107  //
1108  // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
1109#if 0
1110  if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
1111      (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1112       getToolChain().getTriple().getArch() == llvm::Triple::thumb)) {
1113    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
1114      CmdArgs.push_back("-fno-builtin-strcat");
1115    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
1116      CmdArgs.push_back("-fno-builtin-strcpy");
1117  }
1118#endif
1119
1120  if (Arg *A = Args.getLastArg(options::OPT_traditional,
1121                               options::OPT_traditional_cpp))
1122    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
1123
1124  Args.AddLastArg(CmdArgs, options::OPT_dM);
1125  Args.AddLastArg(CmdArgs, options::OPT_dD);
1126
1127  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
1128  Args.AddAllArgValues(CmdArgs, options::OPT_mllvm);
1129
1130  if (Output.getType() == types::TY_Dependencies) {
1131    // Handled with other dependency code.
1132  } else if (Output.isPipe()) {
1133    CmdArgs.push_back("-o");
1134    CmdArgs.push_back("-");
1135  } else if (Output.isFilename()) {
1136    CmdArgs.push_back("-o");
1137    CmdArgs.push_back(Output.getFilename());
1138  } else {
1139    assert(Output.isNothing() && "Invalid output.");
1140  }
1141
1142  for (InputInfoList::const_iterator
1143         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1144    const InputInfo &II = *it;
1145    CmdArgs.push_back("-x");
1146    CmdArgs.push_back(types::getTypeName(II.getType()));
1147    if (II.isPipe())
1148      CmdArgs.push_back("-");
1149    else if (II.isFilename())
1150      CmdArgs.push_back(II.getFilename());
1151    else
1152      II.getInputArg().renderAsInput(Args, CmdArgs);
1153  }
1154
1155  Args.AddAllArgs(CmdArgs, options::OPT_undef);
1156
1157  const char *Exec =
1158    Args.MakeArgString(getToolChain().GetProgramPath(C, "clang"));
1159
1160  // Optionally embed the -cc1 level arguments into the debug info, for build
1161  // analysis.
1162  if (getToolChain().UseDwarfDebugFlags()) {
1163    llvm::SmallString<256> Flags;
1164    Flags += Exec;
1165    for (unsigned i = 0, e = CmdArgs.size(); i != e; ++i) {
1166      Flags += " ";
1167      Flags += CmdArgs[i];
1168    }
1169    CmdArgs.push_back("-dwarf-debug-flags");
1170    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
1171  }
1172
1173  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
1174
1175  // Explicitly warn that these options are unsupported, even though
1176  // we are allowing compilation to continue.
1177  for (arg_iterator it = Args.filtered_begin(options::OPT_pg),
1178         ie = Args.filtered_end(); it != ie; ++it) {
1179    it->claim();
1180    D.Diag(clang::diag::warn_drv_clang_unsupported) << it->getAsString(Args);
1181  }
1182
1183  // Claim some arguments which clang supports automatically.
1184
1185  // -fpch-preprocess is used with gcc to add a special marker in the
1186  // -output to include the PCH file. Clang's PTH solution is
1187  // -completely transparent, so we do not need to deal with it at
1188  // -all.
1189  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
1190
1191  // Claim some arguments which clang doesn't support, but we don't
1192  // care to warn the user about.
1193  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
1194  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
1195}
1196
1197void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
1198                               Job &Dest,
1199                               const InputInfo &Output,
1200                               const InputInfoList &Inputs,
1201                               const ArgList &Args,
1202                               const char *LinkingOutput) const {
1203  const Driver &D = getToolChain().getDriver();
1204  ArgStringList CmdArgs;
1205
1206  for (ArgList::const_iterator
1207         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
1208    Arg *A = *it;
1209    if (A->getOption().hasForwardToGCC()) {
1210      // It is unfortunate that we have to claim here, as this means
1211      // we will basically never report anything interesting for
1212      // platforms using a generic gcc, even if we are just using gcc
1213      // to get to the assembler.
1214      A->claim();
1215      A->render(Args, CmdArgs);
1216    }
1217  }
1218
1219  RenderExtraToolArgs(CmdArgs);
1220
1221  // If using a driver driver, force the arch.
1222  const std::string &Arch = getToolChain().getArchName();
1223  if (getToolChain().getHost().useDriverDriver()) {
1224    CmdArgs.push_back("-arch");
1225
1226    // FIXME: Remove these special cases.
1227    if (Arch == "powerpc")
1228      CmdArgs.push_back("ppc");
1229    else if (Arch == "powerpc64")
1230      CmdArgs.push_back("ppc64");
1231    else
1232      CmdArgs.push_back(Args.MakeArgString(Arch));
1233  }
1234
1235  // Try to force gcc to match the tool chain we want, if we recognize
1236  // the arch.
1237  //
1238  // FIXME: The triple class should directly provide the information we want
1239  // here.
1240  if (Arch == "i386" || Arch == "powerpc")
1241    CmdArgs.push_back("-m32");
1242  else if (Arch == "x86_64" || Arch == "powerpc64")
1243    CmdArgs.push_back("-m64");
1244
1245  if (Output.isPipe()) {
1246    CmdArgs.push_back("-o");
1247    CmdArgs.push_back("-");
1248  } else if (Output.isFilename()) {
1249    CmdArgs.push_back("-o");
1250    CmdArgs.push_back(Output.getFilename());
1251  } else {
1252    assert(Output.isNothing() && "Unexpected output");
1253    CmdArgs.push_back("-fsyntax-only");
1254  }
1255
1256
1257  // Only pass -x if gcc will understand it; otherwise hope gcc
1258  // understands the suffix correctly. The main use case this would go
1259  // wrong in is for linker inputs if they happened to have an odd
1260  // suffix; really the only way to get this to happen is a command
1261  // like '-x foobar a.c' which will treat a.c like a linker input.
1262  //
1263  // FIXME: For the linker case specifically, can we safely convert
1264  // inputs into '-Wl,' options?
1265  for (InputInfoList::const_iterator
1266         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1267    const InputInfo &II = *it;
1268
1269    // Don't try to pass LLVM or AST inputs to a generic gcc.
1270    if (II.getType() == types::TY_LLVMBC)
1271      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
1272        << getToolChain().getTripleString();
1273    else if (II.getType() == types::TY_AST)
1274      D.Diag(clang::diag::err_drv_no_ast_support)
1275        << getToolChain().getTripleString();
1276
1277    if (types::canTypeBeUserSpecified(II.getType())) {
1278      CmdArgs.push_back("-x");
1279      CmdArgs.push_back(types::getTypeName(II.getType()));
1280    }
1281
1282    if (II.isPipe())
1283      CmdArgs.push_back("-");
1284    else if (II.isFilename())
1285      CmdArgs.push_back(II.getFilename());
1286    else
1287      // Don't render as input, we need gcc to do the translations.
1288      II.getInputArg().render(Args, CmdArgs);
1289  }
1290
1291  const char *GCCName = getToolChain().getDriver().CCCGenericGCCName.c_str();
1292  const char *Exec =
1293    Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName));
1294  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
1295}
1296
1297void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1298  CmdArgs.push_back("-E");
1299}
1300
1301void gcc::Precompile::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1302  // The type is good enough.
1303}
1304
1305void gcc::Compile::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1306  CmdArgs.push_back("-S");
1307}
1308
1309void gcc::Assemble::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1310  CmdArgs.push_back("-c");
1311}
1312
1313void gcc::Link::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
1314  // The types are (hopefully) good enough.
1315}
1316
1317const char *darwin::CC1::getCC1Name(types::ID Type) const {
1318  switch (Type) {
1319  default:
1320    assert(0 && "Unexpected type for Darwin CC1 tool.");
1321  case types::TY_Asm:
1322  case types::TY_C: case types::TY_CHeader:
1323  case types::TY_PP_C: case types::TY_PP_CHeader:
1324    return "cc1";
1325  case types::TY_ObjC: case types::TY_ObjCHeader:
1326  case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
1327    return "cc1obj";
1328  case types::TY_CXX: case types::TY_CXXHeader:
1329  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
1330    return "cc1plus";
1331  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
1332  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
1333    return "cc1objplus";
1334  }
1335}
1336
1337const char *darwin::CC1::getBaseInputName(const ArgList &Args,
1338                                          const InputInfoList &Inputs) {
1339  llvm::sys::Path P(Inputs[0].getBaseInput());
1340  return Args.MakeArgString(P.getLast());
1341}
1342
1343const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
1344                                          const InputInfoList &Inputs) {
1345  const char *Str = getBaseInputName(Args, Inputs);
1346
1347  if (const char *End = strchr(Str, '.'))
1348    return Args.MakeArgString(std::string(Str, End));
1349
1350  return Str;
1351}
1352
1353const char *
1354darwin::CC1::getDependencyFileName(const ArgList &Args,
1355                                   const InputInfoList &Inputs) {
1356  // FIXME: Think about this more.
1357  std::string Res;
1358
1359  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
1360    std::string Str(OutputOpt->getValue(Args));
1361
1362    Res = Str.substr(0, Str.rfind('.'));
1363  } else
1364    Res = darwin::CC1::getBaseInputStem(Args, Inputs);
1365
1366  return Args.MakeArgString(Res + ".d");
1367}
1368
1369void darwin::CC1::AddCC1Args(const ArgList &Args,
1370                             ArgStringList &CmdArgs) const {
1371  const Driver &D = getToolChain().getDriver();
1372
1373  CheckCodeGenerationOptions(D, Args);
1374
1375  // Derived from cc1 spec.
1376  if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
1377      !Args.hasArg(options::OPT_mdynamic_no_pic))
1378    CmdArgs.push_back("-fPIC");
1379
1380  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1381      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
1382    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
1383      CmdArgs.push_back("-fno-builtin-strcat");
1384    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
1385      CmdArgs.push_back("-fno-builtin-strcpy");
1386  }
1387
1388  // gcc has some code here to deal with when no -mmacosx-version-min
1389  // and no -miphoneos-version-min is present, but this never happens
1390  // due to tool chain specific argument translation.
1391
1392  if (Args.hasArg(options::OPT_g_Flag) &&
1393      !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
1394    CmdArgs.push_back("-feliminate-unused-debug-symbols");
1395}
1396
1397void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
1398                                    const InputInfoList &Inputs,
1399                                    const ArgStringList &OutputArgs) const {
1400  const Driver &D = getToolChain().getDriver();
1401
1402  // Derived from cc1_options spec.
1403  if (Args.hasArg(options::OPT_fast) ||
1404      Args.hasArg(options::OPT_fastf) ||
1405      Args.hasArg(options::OPT_fastcp))
1406    CmdArgs.push_back("-O3");
1407
1408  if (Arg *A = Args.getLastArg(options::OPT_pg))
1409    if (Args.hasArg(options::OPT_fomit_frame_pointer))
1410      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1411        << A->getAsString(Args) << "-fomit-frame-pointer";
1412
1413  AddCC1Args(Args, CmdArgs);
1414
1415  if (!Args.hasArg(options::OPT_Q))
1416    CmdArgs.push_back("-quiet");
1417
1418  CmdArgs.push_back("-dumpbase");
1419  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
1420
1421  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
1422
1423  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
1424  Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
1425
1426  // FIXME: The goal is to use the user provided -o if that is our
1427  // final output, otherwise to drive from the original input
1428  // name. Find a clean way to go about this.
1429  if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
1430      Args.hasArg(options::OPT_o)) {
1431    Arg *OutputOpt = Args.getLastArg(options::OPT_o);
1432    CmdArgs.push_back("-auxbase-strip");
1433    CmdArgs.push_back(OutputOpt->getValue(Args));
1434  } else {
1435    CmdArgs.push_back("-auxbase");
1436    CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
1437  }
1438
1439  Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
1440
1441  Args.AddAllArgs(CmdArgs, options::OPT_O);
1442  // FIXME: -Wall is getting some special treatment. Investigate.
1443  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
1444  Args.AddLastArg(CmdArgs, options::OPT_w);
1445  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
1446                  options::OPT_trigraphs);
1447  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1448    // Honor -std-default.
1449    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1450                              "-std=", /*Joined=*/true);
1451  }
1452
1453  if (Args.hasArg(options::OPT_v))
1454    CmdArgs.push_back("-version");
1455  if (Args.hasArg(options::OPT_pg))
1456    CmdArgs.push_back("-p");
1457  Args.AddLastArg(CmdArgs, options::OPT_p);
1458
1459  // The driver treats -fsyntax-only specially.
1460  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1461      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
1462    // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
1463    // used to inhibit the default -fno-builtin-str{cat,cpy}.
1464    //
1465    // FIXME: Should we grow a better way to deal with "removing" args?
1466    for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,
1467                                               options::OPT_fsyntax_only),
1468           ie = Args.filtered_end(); it != ie; ++it) {
1469      if (!it->getOption().matches(options::OPT_fbuiltin_strcat) &&
1470          !it->getOption().matches(options::OPT_fbuiltin_strcpy)) {
1471        it->claim();
1472        it->render(Args, CmdArgs);
1473      }
1474    }
1475  } else
1476    Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
1477
1478  Args.AddAllArgs(CmdArgs, options::OPT_undef);
1479  if (Args.hasArg(options::OPT_Qn))
1480    CmdArgs.push_back("-fno-ident");
1481
1482  // FIXME: This isn't correct.
1483  //Args.AddLastArg(CmdArgs, options::OPT__help)
1484  //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
1485
1486  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1487
1488  // FIXME: Still don't get what is happening here. Investigate.
1489  Args.AddAllArgs(CmdArgs, options::OPT__param);
1490
1491  if (Args.hasArg(options::OPT_fmudflap) ||
1492      Args.hasArg(options::OPT_fmudflapth)) {
1493    CmdArgs.push_back("-fno-builtin");
1494    CmdArgs.push_back("-fno-merge-constants");
1495  }
1496
1497  if (Args.hasArg(options::OPT_coverage)) {
1498    CmdArgs.push_back("-fprofile-arcs");
1499    CmdArgs.push_back("-ftest-coverage");
1500  }
1501
1502  if (types::isCXX(Inputs[0].getType()))
1503    CmdArgs.push_back("-D__private_extern__=extern");
1504}
1505
1506void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
1507                                    const InputInfoList &Inputs,
1508                                    const ArgStringList &OutputArgs) const {
1509  // Derived from cpp_options
1510  AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
1511
1512  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1513
1514  AddCC1Args(Args, CmdArgs);
1515
1516  // NOTE: The code below has some commonality with cpp_options, but
1517  // in classic gcc style ends up sending things in different
1518  // orders. This may be a good merge candidate once we drop pedantic
1519  // compatibility.
1520
1521  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
1522  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
1523                  options::OPT_trigraphs);
1524  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1525    // Honor -std-default.
1526    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1527                              "-std=", /*Joined=*/true);
1528  }
1529  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
1530  Args.AddLastArg(CmdArgs, options::OPT_w);
1531
1532  // The driver treats -fsyntax-only specially.
1533  Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
1534
1535  if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
1536      !Args.hasArg(options::OPT_fno_working_directory))
1537    CmdArgs.push_back("-fworking-directory");
1538
1539  Args.AddAllArgs(CmdArgs, options::OPT_O);
1540  Args.AddAllArgs(CmdArgs, options::OPT_undef);
1541  if (Args.hasArg(options::OPT_save_temps))
1542    CmdArgs.push_back("-fpch-preprocess");
1543}
1544
1545void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
1546                                          ArgStringList &CmdArgs,
1547                                          const InputInfoList &Inputs) const {
1548  const Driver &D = getToolChain().getDriver();
1549
1550  CheckPreprocessingOptions(D, Args);
1551
1552  // Derived from cpp_unique_options.
1553  // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
1554  Args.AddLastArg(CmdArgs, options::OPT_C);
1555  Args.AddLastArg(CmdArgs, options::OPT_CC);
1556  if (!Args.hasArg(options::OPT_Q))
1557    CmdArgs.push_back("-quiet");
1558  Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
1559  Args.AddLastArg(CmdArgs, options::OPT_v);
1560  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
1561  Args.AddLastArg(CmdArgs, options::OPT_P);
1562
1563  // FIXME: Handle %I properly.
1564  if (getToolChain().getArchName() == "x86_64") {
1565    CmdArgs.push_back("-imultilib");
1566    CmdArgs.push_back("x86_64");
1567  }
1568
1569  if (Args.hasArg(options::OPT_MD)) {
1570    CmdArgs.push_back("-MD");
1571    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
1572  }
1573
1574  if (Args.hasArg(options::OPT_MMD)) {
1575    CmdArgs.push_back("-MMD");
1576    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
1577  }
1578
1579  Args.AddLastArg(CmdArgs, options::OPT_M);
1580  Args.AddLastArg(CmdArgs, options::OPT_MM);
1581  Args.AddAllArgs(CmdArgs, options::OPT_MF);
1582  Args.AddLastArg(CmdArgs, options::OPT_MG);
1583  Args.AddLastArg(CmdArgs, options::OPT_MP);
1584  Args.AddAllArgs(CmdArgs, options::OPT_MQ);
1585  Args.AddAllArgs(CmdArgs, options::OPT_MT);
1586  if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
1587      (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
1588    if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
1589      CmdArgs.push_back("-MQ");
1590      CmdArgs.push_back(OutputOpt->getValue(Args));
1591    }
1592  }
1593
1594  Args.AddLastArg(CmdArgs, options::OPT_remap);
1595  if (Args.hasArg(options::OPT_g3))
1596    CmdArgs.push_back("-dD");
1597  Args.AddLastArg(CmdArgs, options::OPT_H);
1598
1599  AddCPPArgs(Args, CmdArgs);
1600
1601  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
1602  Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
1603
1604  for (InputInfoList::const_iterator
1605         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1606    const InputInfo &II = *it;
1607
1608    if (II.isPipe())
1609      CmdArgs.push_back("-");
1610    else
1611      CmdArgs.push_back(II.getFilename());
1612  }
1613
1614  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
1615                       options::OPT_Xpreprocessor);
1616
1617  if (Args.hasArg(options::OPT_fmudflap)) {
1618    CmdArgs.push_back("-D_MUDFLAP");
1619    CmdArgs.push_back("-include");
1620    CmdArgs.push_back("mf-runtime.h");
1621  }
1622
1623  if (Args.hasArg(options::OPT_fmudflapth)) {
1624    CmdArgs.push_back("-D_MUDFLAP");
1625    CmdArgs.push_back("-D_MUDFLAPTH");
1626    CmdArgs.push_back("-include");
1627    CmdArgs.push_back("mf-runtime.h");
1628  }
1629}
1630
1631void darwin::CC1::AddCPPArgs(const ArgList &Args,
1632                             ArgStringList &CmdArgs) const {
1633  // Derived from cpp spec.
1634
1635  if (Args.hasArg(options::OPT_static)) {
1636    // The gcc spec is broken here, it refers to dynamic but
1637    // that has been translated. Start by being bug compatible.
1638
1639    // if (!Args.hasArg(arglist.parser.dynamicOption))
1640    CmdArgs.push_back("-D__STATIC__");
1641  } else
1642    CmdArgs.push_back("-D__DYNAMIC__");
1643
1644  if (Args.hasArg(options::OPT_pthread))
1645    CmdArgs.push_back("-D_REENTRANT");
1646}
1647
1648void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
1649                                      Job &Dest, const InputInfo &Output,
1650                                      const InputInfoList &Inputs,
1651                                      const ArgList &Args,
1652                                      const char *LinkingOutput) const {
1653  ArgStringList CmdArgs;
1654
1655  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
1656
1657  CmdArgs.push_back("-E");
1658
1659  if (Args.hasArg(options::OPT_traditional) ||
1660      Args.hasArg(options::OPT_traditional_cpp))
1661    CmdArgs.push_back("-traditional-cpp");
1662
1663  ArgStringList OutputArgs;
1664  if (Output.isFilename()) {
1665    OutputArgs.push_back("-o");
1666    OutputArgs.push_back(Output.getFilename());
1667  } else {
1668    assert(Output.isPipe() && "Unexpected CC1 output.");
1669  }
1670
1671  if (Args.hasArg(options::OPT_E)) {
1672    AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1673  } else {
1674    AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1675    CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1676  }
1677
1678  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
1679
1680  const char *CC1Name = getCC1Name(Inputs[0].getType());
1681  const char *Exec =
1682    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
1683  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
1684}
1685
1686void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
1687                                   Job &Dest, const InputInfo &Output,
1688                                   const InputInfoList &Inputs,
1689                                   const ArgList &Args,
1690                                   const char *LinkingOutput) const {
1691  const Driver &D = getToolChain().getDriver();
1692  ArgStringList CmdArgs;
1693
1694  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
1695
1696  types::ID InputType = Inputs[0].getType();
1697  const Arg *A;
1698  if ((A = Args.getLastArg(options::OPT_traditional)))
1699    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
1700      << A->getAsString(Args) << "-E";
1701
1702  if (Output.getType() == types::TY_LLVMAsm)
1703    CmdArgs.push_back("-emit-llvm");
1704  else if (Output.getType() == types::TY_LLVMBC)
1705    CmdArgs.push_back("-emit-llvm-bc");
1706  else if (Output.getType() == types::TY_AST)
1707    D.Diag(clang::diag::err_drv_no_ast_support)
1708      << getToolChain().getTripleString();
1709
1710  ArgStringList OutputArgs;
1711  if (Output.getType() != types::TY_PCH) {
1712    OutputArgs.push_back("-o");
1713    if (Output.isPipe())
1714      OutputArgs.push_back("-");
1715    else if (Output.isNothing())
1716      OutputArgs.push_back("/dev/null");
1717    else
1718      OutputArgs.push_back(Output.getFilename());
1719  }
1720
1721  // There is no need for this level of compatibility, but it makes
1722  // diffing easier.
1723  bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
1724                          Args.hasArg(options::OPT_S));
1725
1726  if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
1727    AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
1728    if (OutputArgsEarly) {
1729      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1730    } else {
1731      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1732      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1733    }
1734  } else {
1735    CmdArgs.push_back("-fpreprocessed");
1736
1737    for (InputInfoList::const_iterator
1738           it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1739      const InputInfo &II = *it;
1740
1741      // Reject AST inputs.
1742      if (II.getType() == types::TY_AST) {
1743        D.Diag(clang::diag::err_drv_no_ast_support)
1744          << getToolChain().getTripleString();
1745        return;
1746      }
1747
1748      if (II.isPipe())
1749        CmdArgs.push_back("-");
1750      else
1751        CmdArgs.push_back(II.getFilename());
1752    }
1753
1754    if (OutputArgsEarly) {
1755      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1756    } else {
1757      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1758      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1759    }
1760  }
1761
1762  if (Output.getType() == types::TY_PCH) {
1763    assert(Output.isFilename() && "Invalid PCH output.");
1764
1765    CmdArgs.push_back("-o");
1766    // NOTE: gcc uses a temp .s file for this, but there doesn't seem
1767    // to be a good reason.
1768    CmdArgs.push_back("/dev/null");
1769
1770    CmdArgs.push_back("--output-pch=");
1771    CmdArgs.push_back(Output.getFilename());
1772  }
1773
1774  const char *CC1Name = getCC1Name(Inputs[0].getType());
1775  const char *Exec =
1776    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name));
1777  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
1778}
1779
1780void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
1781                                    Job &Dest, const InputInfo &Output,
1782                                    const InputInfoList &Inputs,
1783                                    const ArgList &Args,
1784                                    const char *LinkingOutput) const {
1785  ArgStringList CmdArgs;
1786
1787  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
1788  const InputInfo &Input = Inputs[0];
1789
1790  // Bit of a hack, this is only used for original inputs.
1791  //
1792  // FIXME: This is broken for preprocessed .s inputs.
1793  if (Input.isFilename() &&
1794      strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
1795    if (Args.hasArg(options::OPT_gstabs))
1796      CmdArgs.push_back("--gstabs");
1797    else if (Args.hasArg(options::OPT_g_Group))
1798      CmdArgs.push_back("--gdwarf2");
1799  }
1800
1801  // Derived from asm spec.
1802  AddDarwinArch(Args, CmdArgs);
1803
1804  if (!getDarwinToolChain().isIPhoneOS() ||
1805      Args.hasArg(options::OPT_force__cpusubtype__ALL))
1806    CmdArgs.push_back("-force_cpusubtype_ALL");
1807
1808  if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
1809      (Args.hasArg(options::OPT_mkernel) ||
1810       Args.hasArg(options::OPT_static) ||
1811       Args.hasArg(options::OPT_fapple_kext)))
1812    CmdArgs.push_back("-static");
1813
1814  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
1815                       options::OPT_Xassembler);
1816
1817  assert(Output.isFilename() && "Unexpected lipo output.");
1818  CmdArgs.push_back("-o");
1819  CmdArgs.push_back(Output.getFilename());
1820
1821  if (Input.isPipe()) {
1822    CmdArgs.push_back("-");
1823  } else {
1824    assert(Input.isFilename() && "Invalid input.");
1825    CmdArgs.push_back(Input.getFilename());
1826  }
1827
1828  // asm_final spec is empty.
1829
1830  const char *Exec =
1831    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
1832  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
1833}
1834
1835/// Helper routine for seeing if we should use dsymutil; this is a
1836/// gcc compatible hack, we should remove it and use the input
1837/// type information.
1838static bool isSourceSuffix(const char *Str) {
1839  // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm',
1840  // 'mm'.
1841  return llvm::StringSwitch<bool>(Str)
1842           .Case("C", true)
1843           .Case("c", true)
1844           .Case("m", true)
1845           .Case("cc", true)
1846           .Case("cp", true)
1847           .Case("mm", true)
1848           .Case("CPP", true)
1849           .Case("c++", true)
1850           .Case("cpp", true)
1851           .Case("cxx", true)
1852           .Default(false);
1853}
1854
1855// FIXME: Can we tablegen this?
1856static const char *GetArmArchForMArch(llvm::StringRef Value) {
1857  if (Value == "armv6k")
1858    return "armv6";
1859
1860  if (Value == "armv5tej")
1861    return "armv5";
1862
1863  if (Value == "xscale")
1864    return "xscale";
1865
1866  if (Value == "armv4t")
1867    return "armv4t";
1868
1869  if (Value == "armv7" || Value == "armv7-a" || Value == "armv7-r" ||
1870      Value == "armv7-m" || Value == "armv7a" || Value == "armv7r" ||
1871      Value == "armv7m")
1872    return "armv7";
1873
1874  return 0;
1875}
1876
1877// FIXME: Can we tablegen this?
1878static const char *GetArmArchForMCpu(llvm::StringRef Value) {
1879  if (Value == "arm10tdmi" || Value == "arm1020t" || Value == "arm9e" ||
1880      Value == "arm946e-s" || Value == "arm966e-s" ||
1881      Value == "arm968e-s" || Value == "arm10e" ||
1882      Value == "arm1020e" || Value == "arm1022e" || Value == "arm926ej-s" ||
1883      Value == "arm1026ej-s")
1884    return "armv5";
1885
1886  if (Value == "xscale")
1887    return "xscale";
1888
1889  if (Value == "arm1136j-s" || Value == "arm1136jf-s" ||
1890      Value == "arm1176jz-s" || Value == "arm1176jzf-s")
1891    return "armv6";
1892
1893  if (Value == "cortex-a8" || Value == "cortex-r4" || Value == "cortex-m3")
1894    return "armv7";
1895
1896  return 0;
1897}
1898
1899void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
1900                                       ArgStringList &CmdArgs) const {
1901  // Derived from darwin_arch spec.
1902  CmdArgs.push_back("-arch");
1903
1904  switch (getToolChain().getTriple().getArch()) {
1905  default:
1906    CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
1907    break;
1908
1909  case llvm::Triple::arm: {
1910    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1911      if (const char *Arch = GetArmArchForMArch(A->getValue(Args))) {
1912        CmdArgs.push_back(Arch);
1913        return;
1914      }
1915    }
1916
1917    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1918      if (const char *Arch = GetArmArchForMCpu(A->getValue(Args))) {
1919        CmdArgs.push_back(Arch);
1920        return;
1921      }
1922    }
1923
1924    CmdArgs.push_back("arm");
1925    CmdArgs.push_back("-force_cpusubtype_ALL");
1926    return;
1927  }
1928  }
1929}
1930
1931void darwin::DarwinTool::AddDarwinSubArch(const ArgList &Args,
1932                                          ArgStringList &CmdArgs) const {
1933  // Derived from darwin_subarch spec, not sure what the distinction
1934  // exists for but at least for this chain it is the same.
1935  AddDarwinArch(Args, CmdArgs);
1936}
1937
1938void darwin::Link::AddLinkArgs(const ArgList &Args,
1939                               ArgStringList &CmdArgs) const {
1940  const Driver &D = getToolChain().getDriver();
1941
1942  // Derived from the "link" spec.
1943  Args.AddAllArgs(CmdArgs, options::OPT_static);
1944  if (!Args.hasArg(options::OPT_static))
1945    CmdArgs.push_back("-dynamic");
1946  if (Args.hasArg(options::OPT_fgnu_runtime)) {
1947    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
1948    // here. How do we wish to handle such things?
1949  }
1950
1951  if (!Args.hasArg(options::OPT_dynamiclib)) {
1952    if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
1953      AddDarwinArch(Args, CmdArgs);
1954      CmdArgs.push_back("-force_cpusubtype_ALL");
1955    } else
1956      AddDarwinSubArch(Args, CmdArgs);
1957
1958    Args.AddLastArg(CmdArgs, options::OPT_bundle);
1959    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
1960    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
1961
1962    Arg *A;
1963    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
1964        (A = Args.getLastArg(options::OPT_current__version)) ||
1965        (A = Args.getLastArg(options::OPT_install__name)))
1966      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
1967        << A->getAsString(Args) << "-dynamiclib";
1968
1969    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
1970    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
1971    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
1972  } else {
1973    CmdArgs.push_back("-dylib");
1974
1975    Arg *A;
1976    if ((A = Args.getLastArg(options::OPT_bundle)) ||
1977        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
1978        (A = Args.getLastArg(options::OPT_client__name)) ||
1979        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
1980        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
1981        (A = Args.getLastArg(options::OPT_private__bundle)))
1982      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1983        << A->getAsString(Args) << "-dynamiclib";
1984
1985    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
1986                              "-dylib_compatibility_version");
1987    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
1988                              "-dylib_current_version");
1989
1990    if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
1991      AddDarwinArch(Args, CmdArgs);
1992      // NOTE: We don't add -force_cpusubtype_ALL on this path. Ok.
1993    } else
1994      AddDarwinSubArch(Args, CmdArgs);
1995
1996    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
1997                              "-dylib_install_name");
1998  }
1999
2000  Args.AddLastArg(CmdArgs, options::OPT_all__load);
2001  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
2002  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
2003  if (getDarwinToolChain().isIPhoneOS())
2004    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
2005  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
2006  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
2007  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
2008  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
2009  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
2010  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
2011  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
2012  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
2013  Args.AddAllArgs(CmdArgs, options::OPT_init);
2014
2015  if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ) &&
2016      !Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
2017    // Add default version min.
2018    if (!getDarwinToolChain().isIPhoneOS()) {
2019      CmdArgs.push_back("-macosx_version_min");
2020      CmdArgs.push_back(getDarwinToolChain().getMacosxVersionStr());
2021    } else {
2022      CmdArgs.push_back("-iphoneos_version_min");
2023      CmdArgs.push_back(getDarwinToolChain().getIPhoneOSVersionStr());
2024    }
2025  }
2026
2027  // Adding all arguments doesn't make sense here but this is what
2028  // gcc does.
2029  Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
2030                            "-macosx_version_min");
2031  Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
2032                            "-iphoneos_version_min");
2033  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
2034  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
2035  Args.AddLastArg(CmdArgs, options::OPT_single__module);
2036  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
2037  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
2038
2039  if (Args.hasArg(options::OPT_fpie))
2040    CmdArgs.push_back("-pie");
2041
2042  Args.AddLastArg(CmdArgs, options::OPT_prebind);
2043  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
2044  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
2045  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
2046  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
2047  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
2048  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
2049  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
2050  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
2051  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
2052  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
2053  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
2054  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
2055  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
2056  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
2057  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
2058
2059  Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
2060  if (getDarwinToolChain().isIPhoneOS()) {
2061    if (!Args.hasArg(options::OPT_isysroot)) {
2062      CmdArgs.push_back("-syslibroot");
2063      CmdArgs.push_back("/Developer/SDKs/Extra");
2064    }
2065  }
2066
2067  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
2068  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
2069  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
2070  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
2071  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
2072
2073  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
2074  if (!Args.hasArg(options::OPT_weak__reference__mismatches)) {
2075    CmdArgs.push_back("-weak_reference_mismatches");
2076    CmdArgs.push_back("non-weak");
2077  }
2078
2079  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
2080  Args.AddAllArgs(CmdArgs, options::OPT_y);
2081  Args.AddLastArg(CmdArgs, options::OPT_w);
2082  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
2083  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
2084  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
2085  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
2086  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
2087  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
2088  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
2089  Args.AddLastArg(CmdArgs, options::OPT_whyload);
2090  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
2091  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
2092  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
2093  Args.AddLastArg(CmdArgs, options::OPT_Mach);
2094}
2095
2096void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
2097                                Job &Dest, const InputInfo &Output,
2098                                const InputInfoList &Inputs,
2099                                const ArgList &Args,
2100                                const char *LinkingOutput) const {
2101  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
2102
2103  // The logic here is derived from gcc's behavior; most of which
2104  // comes from specs (starting with link_command). Consult gcc for
2105  // more information.
2106  ArgStringList CmdArgs;
2107
2108  // I'm not sure why this particular decomposition exists in gcc, but
2109  // we follow suite for ease of comparison.
2110  AddLinkArgs(Args, CmdArgs);
2111
2112  Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
2113  Args.AddAllArgs(CmdArgs, options::OPT_s);
2114  Args.AddAllArgs(CmdArgs, options::OPT_t);
2115  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
2116  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
2117  Args.AddAllArgs(CmdArgs, options::OPT_A);
2118  Args.AddLastArg(CmdArgs, options::OPT_e);
2119  Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
2120  Args.AddAllArgs(CmdArgs, options::OPT_r);
2121
2122  CmdArgs.push_back("-o");
2123  CmdArgs.push_back(Output.getFilename());
2124
2125
2126  unsigned MacosxVersionMin[3];
2127  getDarwinToolChain().getMacosxVersionMin(Args, MacosxVersionMin);
2128
2129  if (!Args.hasArg(options::OPT_A) &&
2130      !Args.hasArg(options::OPT_nostdlib) &&
2131      !Args.hasArg(options::OPT_nostartfiles)) {
2132    // Derived from startfile spec.
2133    if (Args.hasArg(options::OPT_dynamiclib)) {
2134      // Derived from darwin_dylib1 spec.
2135      if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 5))
2136        CmdArgs.push_back("-ldylib1.o");
2137      else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 6))
2138        CmdArgs.push_back("-ldylib1.10.5.o");
2139    } else {
2140      if (Args.hasArg(options::OPT_bundle)) {
2141        if (!Args.hasArg(options::OPT_static)) {
2142          // Derived from darwin_bundle1 spec.
2143          if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 6))
2144            CmdArgs.push_back("-lbundle1.o");
2145        }
2146      } else {
2147        if (Args.hasArg(options::OPT_pg)) {
2148          if (Args.hasArg(options::OPT_static) ||
2149              Args.hasArg(options::OPT_object) ||
2150              Args.hasArg(options::OPT_preload)) {
2151            CmdArgs.push_back("-lgcrt0.o");
2152          } else {
2153            CmdArgs.push_back("-lgcrt1.o");
2154
2155            // darwin_crt2 spec is empty.
2156          }
2157        } else {
2158          if (Args.hasArg(options::OPT_static) ||
2159              Args.hasArg(options::OPT_object) ||
2160              Args.hasArg(options::OPT_preload)) {
2161            CmdArgs.push_back("-lcrt0.o");
2162          } else {
2163            // Derived from darwin_crt1 spec.
2164            if (getDarwinToolChain().isIPhoneOS()) {
2165              CmdArgs.push_back("-lcrt1.o");
2166            } else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin,
2167                                                              10, 5))
2168              CmdArgs.push_back("-lcrt1.o");
2169            else if (getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin,
2170                                                            10, 6))
2171              CmdArgs.push_back("-lcrt1.10.5.o");
2172            else
2173              CmdArgs.push_back("-lcrt1.10.6.o");
2174
2175            // darwin_crt2 spec is empty.
2176          }
2177        }
2178      }
2179    }
2180
2181    if (Args.hasArg(options::OPT_shared_libgcc) &&
2182        !Args.hasArg(options::OPT_miphoneos_version_min_EQ) &&
2183        getDarwinToolChain().isMacosxVersionLT(MacosxVersionMin, 10, 5)) {
2184      const char *Str =
2185        Args.MakeArgString(getToolChain().GetFilePath(C, "crt3.o"));
2186      CmdArgs.push_back(Str);
2187    }
2188  }
2189
2190  Args.AddAllArgs(CmdArgs, options::OPT_L);
2191
2192  if (Args.hasArg(options::OPT_fopenmp))
2193    // This is more complicated in gcc...
2194    CmdArgs.push_back("-lgomp");
2195
2196  getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
2197
2198  for (InputInfoList::const_iterator
2199         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2200    const InputInfo &II = *it;
2201    if (II.isFilename())
2202      CmdArgs.push_back(II.getFilename());
2203    else
2204      II.getInputArg().renderAsInput(Args, CmdArgs);
2205  }
2206
2207  if (LinkingOutput) {
2208    CmdArgs.push_back("-arch_multiple");
2209    CmdArgs.push_back("-final_output");
2210    CmdArgs.push_back(LinkingOutput);
2211  }
2212
2213  if (Args.hasArg(options::OPT_fprofile_arcs) ||
2214      Args.hasArg(options::OPT_fprofile_generate) ||
2215      Args.hasArg(options::OPT_fcreate_profile) ||
2216      Args.hasArg(options::OPT_coverage))
2217    CmdArgs.push_back("-lgcov");
2218
2219  if (Args.hasArg(options::OPT_fnested_functions))
2220    CmdArgs.push_back("-allow_stack_execute");
2221
2222  if (!Args.hasArg(options::OPT_nostdlib) &&
2223      !Args.hasArg(options::OPT_nodefaultlibs)) {
2224    // FIXME: g++ is more complicated here, it tries to put -lstdc++
2225    // before -lm, for example.
2226    if (getToolChain().getDriver().CCCIsCXX)
2227      CmdArgs.push_back("-lstdc++");
2228
2229    // link_ssp spec is empty.
2230
2231    // Let the tool chain choose which runtime library to link.
2232    getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
2233  }
2234
2235  if (!Args.hasArg(options::OPT_A) &&
2236      !Args.hasArg(options::OPT_nostdlib) &&
2237      !Args.hasArg(options::OPT_nostartfiles)) {
2238    // endfile_spec is empty.
2239  }
2240
2241  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2242  Args.AddAllArgs(CmdArgs, options::OPT_F);
2243
2244  const char *Exec =
2245    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
2246  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2247
2248  // Find the first non-empty base input (we want to ignore linker
2249  // inputs).
2250  const char *BaseInput = "";
2251  for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
2252    if (Inputs[i].getBaseInput()[0] != '\0') {
2253      BaseInput = Inputs[i].getBaseInput();
2254      break;
2255    }
2256  }
2257
2258  // Run dsymutil if we are making an executable in a single step.
2259  //
2260  // FIXME: Currently we don't want to do this when we are part of a
2261  // universal build step, as this would end up creating stray temp
2262  // files.
2263  if (!LinkingOutput &&
2264      Args.getLastArg(options::OPT_g_Group) &&
2265      !Args.getLastArg(options::OPT_gstabs) &&
2266      !Args.getLastArg(options::OPT_g0)) {
2267    // FIXME: This is gross, but matches gcc. The test only considers
2268    // the suffix (not the -x type), and then only of the first
2269    // source input. Awesome.
2270    const char *Suffix = strrchr(BaseInput, '.');
2271    if (Suffix && isSourceSuffix(Suffix + 1)) {
2272      const char *Exec =
2273        Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil"));
2274      ArgStringList CmdArgs;
2275      CmdArgs.push_back(Output.getFilename());
2276      C.getJobs().addCommand(new Command(JA, *this, Exec, CmdArgs));
2277    }
2278  }
2279}
2280
2281void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
2282                                Job &Dest, const InputInfo &Output,
2283                                const InputInfoList &Inputs,
2284                                const ArgList &Args,
2285                                const char *LinkingOutput) const {
2286  ArgStringList CmdArgs;
2287
2288  CmdArgs.push_back("-create");
2289  assert(Output.isFilename() && "Unexpected lipo output.");
2290
2291  CmdArgs.push_back("-output");
2292  CmdArgs.push_back(Output.getFilename());
2293
2294  for (InputInfoList::const_iterator
2295         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2296    const InputInfo &II = *it;
2297    assert(II.isFilename() && "Unexpected lipo input.");
2298    CmdArgs.push_back(II.getFilename());
2299  }
2300  const char *Exec =
2301    Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo"));
2302  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2303}
2304
2305void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2306                                      Job &Dest, const InputInfo &Output,
2307                                      const InputInfoList &Inputs,
2308                                      const ArgList &Args,
2309                                      const char *LinkingOutput) const {
2310  ArgStringList CmdArgs;
2311
2312  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2313                       options::OPT_Xassembler);
2314
2315  CmdArgs.push_back("-o");
2316  if (Output.isPipe())
2317    CmdArgs.push_back("-");
2318  else
2319    CmdArgs.push_back(Output.getFilename());
2320
2321  for (InputInfoList::const_iterator
2322         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2323    const InputInfo &II = *it;
2324    if (II.isPipe())
2325      CmdArgs.push_back("-");
2326    else
2327      CmdArgs.push_back(II.getFilename());
2328  }
2329
2330  const char *Exec =
2331    Args.MakeArgString(getToolChain().GetProgramPath(C, "gas"));
2332  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2333}
2334
2335void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
2336                                  Job &Dest, const InputInfo &Output,
2337                                  const InputInfoList &Inputs,
2338                                  const ArgList &Args,
2339                                  const char *LinkingOutput) const {
2340  const Driver &D = getToolChain().getDriver();
2341  ArgStringList CmdArgs;
2342
2343  if ((!Args.hasArg(options::OPT_nostdlib)) &&
2344      (!Args.hasArg(options::OPT_shared))) {
2345    CmdArgs.push_back("-e");
2346    CmdArgs.push_back("_start");
2347  }
2348
2349  if (Args.hasArg(options::OPT_static)) {
2350    CmdArgs.push_back("-Bstatic");
2351    CmdArgs.push_back("-dn");
2352  } else {
2353//    CmdArgs.push_back("--eh-frame-hdr");
2354    CmdArgs.push_back("-Bdynamic");
2355    if (Args.hasArg(options::OPT_shared)) {
2356      CmdArgs.push_back("-shared");
2357    } else {
2358      CmdArgs.push_back("--dynamic-linker");
2359      CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
2360    }
2361  }
2362
2363  if (Output.isPipe()) {
2364    CmdArgs.push_back("-o");
2365    CmdArgs.push_back("-");
2366  } else if (Output.isFilename()) {
2367    CmdArgs.push_back("-o");
2368    CmdArgs.push_back(Output.getFilename());
2369  } else {
2370    assert(Output.isNothing() && "Invalid output.");
2371  }
2372
2373  if (!Args.hasArg(options::OPT_nostdlib) &&
2374      !Args.hasArg(options::OPT_nostartfiles)) {
2375    if (!Args.hasArg(options::OPT_shared)) {
2376      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
2377      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2378      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
2379    } else {
2380      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2381    }
2382    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
2383  }
2384
2385  CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
2386                                       + getToolChain().getTripleString()
2387                                       + "/4.2.4"));
2388
2389  Args.AddAllArgs(CmdArgs, options::OPT_L);
2390  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2391  Args.AddAllArgs(CmdArgs, options::OPT_e);
2392
2393  for (InputInfoList::const_iterator
2394         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2395    const InputInfo &II = *it;
2396
2397    // Don't try to pass LLVM inputs to a generic gcc.
2398    if (II.getType() == types::TY_LLVMBC)
2399      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
2400        << getToolChain().getTripleString();
2401
2402    if (II.isPipe())
2403      CmdArgs.push_back("-");
2404    else if (II.isFilename())
2405      CmdArgs.push_back(II.getFilename());
2406    else
2407      II.getInputArg().renderAsInput(Args, CmdArgs);
2408  }
2409
2410  if (!Args.hasArg(options::OPT_nostdlib) &&
2411      !Args.hasArg(options::OPT_nodefaultlibs)) {
2412    // FIXME: For some reason GCC passes -lgcc before adding
2413    // the default system libraries. Just mimic this for now.
2414    CmdArgs.push_back("-lgcc");
2415
2416    if (Args.hasArg(options::OPT_pthread))
2417      CmdArgs.push_back("-pthread");
2418    if (!Args.hasArg(options::OPT_shared))
2419      CmdArgs.push_back("-lc");
2420    CmdArgs.push_back("-lgcc");
2421  }
2422
2423  if (!Args.hasArg(options::OPT_nostdlib) &&
2424      !Args.hasArg(options::OPT_nostartfiles)) {
2425    if (!Args.hasArg(options::OPT_shared))
2426      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
2427//    else
2428//      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
2429  }
2430
2431  const char *Exec =
2432    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
2433  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2434}
2435
2436void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2437                                     Job &Dest, const InputInfo &Output,
2438                                     const InputInfoList &Inputs,
2439                                     const ArgList &Args,
2440                                     const char *LinkingOutput) const {
2441  ArgStringList CmdArgs;
2442
2443  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2444                       options::OPT_Xassembler);
2445
2446  CmdArgs.push_back("-o");
2447  if (Output.isPipe())
2448    CmdArgs.push_back("-");
2449  else
2450    CmdArgs.push_back(Output.getFilename());
2451
2452  for (InputInfoList::const_iterator
2453         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2454    const InputInfo &II = *it;
2455    if (II.isPipe())
2456      CmdArgs.push_back("-");
2457    else
2458      CmdArgs.push_back(II.getFilename());
2459  }
2460
2461  const char *Exec =
2462    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
2463  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2464}
2465
2466void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
2467                                 Job &Dest, const InputInfo &Output,
2468                                 const InputInfoList &Inputs,
2469                                 const ArgList &Args,
2470                                 const char *LinkingOutput) const {
2471  const Driver &D = getToolChain().getDriver();
2472  ArgStringList CmdArgs;
2473
2474  if ((!Args.hasArg(options::OPT_nostdlib)) &&
2475      (!Args.hasArg(options::OPT_shared))) {
2476    CmdArgs.push_back("-e");
2477    CmdArgs.push_back("__start");
2478  }
2479
2480  if (Args.hasArg(options::OPT_static)) {
2481    CmdArgs.push_back("-Bstatic");
2482  } else {
2483    CmdArgs.push_back("--eh-frame-hdr");
2484    CmdArgs.push_back("-Bdynamic");
2485    if (Args.hasArg(options::OPT_shared)) {
2486      CmdArgs.push_back("-shared");
2487    } else {
2488      CmdArgs.push_back("-dynamic-linker");
2489      CmdArgs.push_back("/usr/libexec/ld.so");
2490    }
2491  }
2492
2493  if (Output.isPipe()) {
2494    CmdArgs.push_back("-o");
2495    CmdArgs.push_back("-");
2496  } else if (Output.isFilename()) {
2497    CmdArgs.push_back("-o");
2498    CmdArgs.push_back(Output.getFilename());
2499  } else {
2500    assert(Output.isNothing() && "Invalid output.");
2501  }
2502
2503  if (!Args.hasArg(options::OPT_nostdlib) &&
2504      !Args.hasArg(options::OPT_nostartfiles)) {
2505    if (!Args.hasArg(options::OPT_shared)) {
2506      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o")));
2507      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
2508    } else {
2509      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
2510    }
2511  }
2512
2513  std::string Triple = getToolChain().getTripleString();
2514  if (Triple.substr(0, 6) == "x86_64")
2515    Triple.replace(0, 6, "amd64");
2516  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
2517                                       "/3.3.5"));
2518
2519  Args.AddAllArgs(CmdArgs, options::OPT_L);
2520  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2521  Args.AddAllArgs(CmdArgs, options::OPT_e);
2522
2523  for (InputInfoList::const_iterator
2524         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2525    const InputInfo &II = *it;
2526
2527    // Don't try to pass LLVM inputs to a generic gcc.
2528    if (II.getType() == types::TY_LLVMBC)
2529      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
2530        << getToolChain().getTripleString();
2531
2532    if (II.isPipe())
2533      CmdArgs.push_back("-");
2534    else if (II.isFilename())
2535      CmdArgs.push_back(II.getFilename());
2536    else
2537      II.getInputArg().renderAsInput(Args, CmdArgs);
2538  }
2539
2540  if (!Args.hasArg(options::OPT_nostdlib) &&
2541      !Args.hasArg(options::OPT_nodefaultlibs)) {
2542    // FIXME: For some reason GCC passes -lgcc before adding
2543    // the default system libraries. Just mimic this for now.
2544    CmdArgs.push_back("-lgcc");
2545
2546    if (Args.hasArg(options::OPT_pthread))
2547      CmdArgs.push_back("-pthread");
2548    if (!Args.hasArg(options::OPT_shared))
2549      CmdArgs.push_back("-lc");
2550    CmdArgs.push_back("-lgcc");
2551  }
2552
2553  if (!Args.hasArg(options::OPT_nostdlib) &&
2554      !Args.hasArg(options::OPT_nostartfiles)) {
2555    if (!Args.hasArg(options::OPT_shared))
2556      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
2557    else
2558      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
2559  }
2560
2561  const char *Exec =
2562    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
2563  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2564}
2565
2566void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2567                                     Job &Dest, const InputInfo &Output,
2568                                     const InputInfoList &Inputs,
2569                                     const ArgList &Args,
2570                                     const char *LinkingOutput) const {
2571  ArgStringList CmdArgs;
2572
2573  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
2574  // instruct as in the base system to assemble 32-bit code.
2575  if (getToolChain().getArchName() == "i386")
2576    CmdArgs.push_back("--32");
2577
2578  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2579                       options::OPT_Xassembler);
2580
2581  CmdArgs.push_back("-o");
2582  if (Output.isPipe())
2583    CmdArgs.push_back("-");
2584  else
2585    CmdArgs.push_back(Output.getFilename());
2586
2587  for (InputInfoList::const_iterator
2588         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2589    const InputInfo &II = *it;
2590    if (II.isPipe())
2591      CmdArgs.push_back("-");
2592    else
2593      CmdArgs.push_back(II.getFilename());
2594  }
2595
2596  const char *Exec =
2597    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
2598  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2599}
2600
2601void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
2602                                 Job &Dest, const InputInfo &Output,
2603                                 const InputInfoList &Inputs,
2604                                 const ArgList &Args,
2605                                 const char *LinkingOutput) const {
2606  const Driver &D = getToolChain().getDriver();
2607  ArgStringList CmdArgs;
2608
2609  if (Args.hasArg(options::OPT_static)) {
2610    CmdArgs.push_back("-Bstatic");
2611  } else {
2612    CmdArgs.push_back("--eh-frame-hdr");
2613    if (Args.hasArg(options::OPT_shared)) {
2614      CmdArgs.push_back("-Bshareable");
2615    } else {
2616      CmdArgs.push_back("-dynamic-linker");
2617      CmdArgs.push_back("/libexec/ld-elf.so.1");
2618    }
2619  }
2620
2621  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
2622  // instruct ld in the base system to link 32-bit code.
2623  if (getToolChain().getArchName() == "i386") {
2624    CmdArgs.push_back("-m");
2625    CmdArgs.push_back("elf_i386_fbsd");
2626  }
2627
2628  if (Output.isPipe()) {
2629    CmdArgs.push_back("-o");
2630    CmdArgs.push_back("-");
2631  } else if (Output.isFilename()) {
2632    CmdArgs.push_back("-o");
2633    CmdArgs.push_back(Output.getFilename());
2634  } else {
2635    assert(Output.isNothing() && "Invalid output.");
2636  }
2637
2638  if (!Args.hasArg(options::OPT_nostdlib) &&
2639      !Args.hasArg(options::OPT_nostartfiles)) {
2640    if (!Args.hasArg(options::OPT_shared)) {
2641      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
2642      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2643      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
2644    } else {
2645      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2646      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
2647    }
2648  }
2649
2650  Args.AddAllArgs(CmdArgs, options::OPT_L);
2651  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2652  Args.AddAllArgs(CmdArgs, options::OPT_e);
2653
2654  for (InputInfoList::const_iterator
2655         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2656    const InputInfo &II = *it;
2657
2658    // Don't try to pass LLVM inputs to a generic gcc.
2659    if (II.getType() == types::TY_LLVMBC)
2660      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
2661        << getToolChain().getTripleString();
2662
2663    if (II.isPipe())
2664      CmdArgs.push_back("-");
2665    else if (II.isFilename())
2666      CmdArgs.push_back(II.getFilename());
2667    else
2668      II.getInputArg().renderAsInput(Args, CmdArgs);
2669  }
2670
2671  if (!Args.hasArg(options::OPT_nostdlib) &&
2672      !Args.hasArg(options::OPT_nodefaultlibs)) {
2673    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
2674    // the default system libraries. Just mimic this for now.
2675    CmdArgs.push_back("-lgcc");
2676    if (D.CCCIsCXX)
2677      CmdArgs.push_back("-lstdc++");
2678    if (Args.hasArg(options::OPT_static)) {
2679      CmdArgs.push_back("-lgcc_eh");
2680    } else {
2681      CmdArgs.push_back("--as-needed");
2682      CmdArgs.push_back("-lgcc_s");
2683      CmdArgs.push_back("--no-as-needed");
2684    }
2685
2686    if (Args.hasArg(options::OPT_pthread))
2687      CmdArgs.push_back("-lpthread");
2688    CmdArgs.push_back("-lc");
2689
2690    CmdArgs.push_back("-lgcc");
2691    if (Args.hasArg(options::OPT_static)) {
2692      CmdArgs.push_back("-lgcc_eh");
2693    } else {
2694      CmdArgs.push_back("--as-needed");
2695      CmdArgs.push_back("-lgcc_s");
2696      CmdArgs.push_back("--no-as-needed");
2697    }
2698  }
2699
2700  if (!Args.hasArg(options::OPT_nostdlib) &&
2701      !Args.hasArg(options::OPT_nostartfiles)) {
2702    if (!Args.hasArg(options::OPT_shared))
2703      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
2704    else
2705      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
2706    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
2707  }
2708
2709  const char *Exec =
2710    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
2711  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2712}
2713
2714/// DragonFly Tools
2715
2716// For now, DragonFly Assemble does just about the same as for
2717// FreeBSD, but this may change soon.
2718void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2719                                       Job &Dest, const InputInfo &Output,
2720                                       const InputInfoList &Inputs,
2721                                       const ArgList &Args,
2722                                       const char *LinkingOutput) const {
2723  ArgStringList CmdArgs;
2724
2725  // When building 32-bit code on DragonFly/pc64, we have to explicitly
2726  // instruct as in the base system to assemble 32-bit code.
2727  if (getToolChain().getArchName() == "i386")
2728    CmdArgs.push_back("--32");
2729
2730  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2731                       options::OPT_Xassembler);
2732
2733  CmdArgs.push_back("-o");
2734  if (Output.isPipe())
2735    CmdArgs.push_back("-");
2736  else
2737    CmdArgs.push_back(Output.getFilename());
2738
2739  for (InputInfoList::const_iterator
2740         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2741    const InputInfo &II = *it;
2742    if (II.isPipe())
2743      CmdArgs.push_back("-");
2744    else
2745      CmdArgs.push_back(II.getFilename());
2746  }
2747
2748  const char *Exec =
2749    Args.MakeArgString(getToolChain().GetProgramPath(C, "as"));
2750  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2751}
2752
2753void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
2754                                 Job &Dest, const InputInfo &Output,
2755                                 const InputInfoList &Inputs,
2756                                 const ArgList &Args,
2757                                 const char *LinkingOutput) const {
2758  const Driver &D = getToolChain().getDriver();
2759  ArgStringList CmdArgs;
2760
2761  if (Args.hasArg(options::OPT_static)) {
2762    CmdArgs.push_back("-Bstatic");
2763  } else {
2764    if (Args.hasArg(options::OPT_shared))
2765      CmdArgs.push_back("-Bshareable");
2766    else {
2767      CmdArgs.push_back("-dynamic-linker");
2768      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
2769    }
2770  }
2771
2772  // When building 32-bit code on DragonFly/pc64, we have to explicitly
2773  // instruct ld in the base system to link 32-bit code.
2774  if (getToolChain().getArchName() == "i386") {
2775    CmdArgs.push_back("-m");
2776    CmdArgs.push_back("elf_i386");
2777  }
2778
2779  if (Output.isPipe()) {
2780    CmdArgs.push_back("-o");
2781    CmdArgs.push_back("-");
2782  } else if (Output.isFilename()) {
2783    CmdArgs.push_back("-o");
2784    CmdArgs.push_back(Output.getFilename());
2785  } else {
2786    assert(Output.isNothing() && "Invalid output.");
2787  }
2788
2789  if (!Args.hasArg(options::OPT_nostdlib) &&
2790      !Args.hasArg(options::OPT_nostartfiles)) {
2791    if (!Args.hasArg(options::OPT_shared)) {
2792      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o")));
2793      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2794      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o")));
2795    } else {
2796      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o")));
2797      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o")));
2798    }
2799  }
2800
2801  Args.AddAllArgs(CmdArgs, options::OPT_L);
2802  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2803  Args.AddAllArgs(CmdArgs, options::OPT_e);
2804
2805  for (InputInfoList::const_iterator
2806         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2807    const InputInfo &II = *it;
2808
2809    // Don't try to pass LLVM inputs to a generic gcc.
2810    if (II.getType() == types::TY_LLVMBC)
2811      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
2812        << getToolChain().getTripleString();
2813
2814    if (II.isPipe())
2815      CmdArgs.push_back("-");
2816    else if (II.isFilename())
2817      CmdArgs.push_back(II.getFilename());
2818    else
2819      II.getInputArg().renderAsInput(Args, CmdArgs);
2820  }
2821
2822  if (!Args.hasArg(options::OPT_nostdlib) &&
2823      !Args.hasArg(options::OPT_nodefaultlibs)) {
2824    // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
2825    //         rpaths
2826    CmdArgs.push_back("-L/usr/lib/gcc41");
2827
2828    if (!Args.hasArg(options::OPT_static)) {
2829      CmdArgs.push_back("-rpath");
2830      CmdArgs.push_back("/usr/lib/gcc41");
2831
2832      CmdArgs.push_back("-rpath-link");
2833      CmdArgs.push_back("/usr/lib/gcc41");
2834
2835      CmdArgs.push_back("-rpath");
2836      CmdArgs.push_back("/usr/lib");
2837
2838      CmdArgs.push_back("-rpath-link");
2839      CmdArgs.push_back("/usr/lib");
2840    }
2841
2842    if (Args.hasArg(options::OPT_shared)) {
2843      CmdArgs.push_back("-lgcc_pic");
2844    } else {
2845      CmdArgs.push_back("-lgcc");
2846    }
2847
2848
2849    if (Args.hasArg(options::OPT_pthread))
2850      CmdArgs.push_back("-lpthread");
2851
2852    if (!Args.hasArg(options::OPT_nolibc)) {
2853      CmdArgs.push_back("-lc");
2854    }
2855
2856    if (Args.hasArg(options::OPT_shared)) {
2857      CmdArgs.push_back("-lgcc_pic");
2858    } else {
2859      CmdArgs.push_back("-lgcc");
2860    }
2861  }
2862
2863  if (!Args.hasArg(options::OPT_nostdlib) &&
2864      !Args.hasArg(options::OPT_nostartfiles)) {
2865    if (!Args.hasArg(options::OPT_shared))
2866      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o")));
2867    else
2868      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
2869    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
2870  }
2871
2872  const char *Exec =
2873    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld"));
2874  Dest.addCommand(new Command(JA, *this, Exec, CmdArgs));
2875}
2876