Tools.cpp revision d82df3ad430397d7f9ef511e7c5157f997c41f53
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/Driver/Action.h"
13#include "clang/Driver/Arg.h"
14#include "clang/Driver/ArgList.h"
15#include "clang/Driver/Driver.h" // FIXME: Remove?
16#include "clang/Driver/DriverDiagnostic.h" // FIXME: Remove?
17#include "clang/Driver/Compilation.h"
18#include "clang/Driver/Job.h"
19#include "clang/Driver/HostInfo.h"
20#include "clang/Driver/Option.h"
21#include "clang/Driver/ToolChain.h"
22#include "clang/Driver/Util.h"
23
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/Support/Format.h"
26#include "llvm/Support/raw_ostream.h"
27
28#include "InputInfo.h"
29#include "ToolChains.h"
30
31using namespace clang::driver;
32using namespace clang::driver::tools;
33
34void Clang::AddPreprocessingOptions(const ArgList &Args,
35                                    ArgStringList &CmdArgs,
36                                    const InputInfo &Output,
37                                    const InputInfoList &Inputs) const {
38  // Handle dependency file generation.
39  Arg *A;
40  if ((A = Args.getLastArg(options::OPT_M)) ||
41      (A = Args.getLastArg(options::OPT_MM)) ||
42      (A = Args.getLastArg(options::OPT_MD)) ||
43      (A = Args.getLastArg(options::OPT_MMD))) {
44    // Determine the output location.
45    const char *DepFile;
46    if (Output.getType() == types::TY_Dependencies) {
47      if (Output.isPipe())
48        DepFile = "-";
49      else
50        DepFile = Output.getFilename();
51    } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
52      DepFile = MF->getValue(Args);
53    } else if (A->getOption().getId() == options::OPT_M ||
54               A->getOption().getId() == options::OPT_MM) {
55      DepFile = "-";
56    } else {
57      DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
58    }
59    CmdArgs.push_back("-dependency-file");
60    CmdArgs.push_back(DepFile);
61
62    // Add an -MT option if the user didn't specify their own.
63    // FIXME: This should use -MQ, when we support it.
64    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
65      const char *DepTarget;
66
67      // If user provided -o, that is the dependency target, except
68      // when we are only generating a dependency file.
69      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
70      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
71        DepTarget = OutputOpt->getValue(Args);
72      } else {
73        // Otherwise derive from the base input.
74        //
75        // FIXME: This should use the computed output file location.
76        llvm::sys::Path P(Inputs[0].getBaseInput());
77
78        P.eraseSuffix();
79        P.appendSuffix("o");
80        DepTarget = Args.MakeArgString(P.getLast().c_str());
81      }
82
83      CmdArgs.push_back("-MT");
84      CmdArgs.push_back(DepTarget);
85    }
86
87    if (A->getOption().getId() == options::OPT_M ||
88        A->getOption().getId() == options::OPT_MD)
89      CmdArgs.push_back("-sys-header-deps");
90  }
91
92  Args.AddLastArg(CmdArgs, options::OPT_MP);
93  Args.AddAllArgs(CmdArgs, options::OPT_MT);
94
95  // FIXME: Use iterator.
96
97  // Add -i* options, and automatically translate to -include-pth for
98  // transparent PCH support. It's wonky, but we include looking for
99  // .gch so we can support seamless replacement into a build system
100  // already set up to be generating .gch files.
101  for (ArgList::const_iterator
102         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
103    const Arg *A = *it;
104    if (!A->getOption().matches(options::OPT_clang_i_Group))
105      continue;
106
107    if (A->getOption().matches(options::OPT_include)) {
108      bool FoundPTH = false;
109      llvm::sys::Path P(A->getValue(Args));
110      P.appendSuffix("pth");
111      if (P.exists()) {
112        FoundPTH = true;
113      } else {
114        P.eraseSuffix();
115        P.appendSuffix("gch");
116        if (P.exists())
117          FoundPTH = true;
118      }
119
120      if (FoundPTH) {
121        A->claim();
122        CmdArgs.push_back("-include-pth");
123        CmdArgs.push_back(Args.MakeArgString(P.c_str()));
124        continue;
125      }
126    }
127
128    // Not translated, render as usual.
129    A->claim();
130    A->render(Args, CmdArgs);
131  }
132
133  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
134  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
135
136  // Add -Wp, and -Xassembler if using the preprocessor.
137
138  // FIXME: There is a very unfortunate problem here, some troubled
139  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
140  // really support that we would have to parse and then translate
141  // those options. :(
142  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
143                       options::OPT_Xpreprocessor);
144}
145
146void Clang::ConstructJob(Compilation &C, const JobAction &JA,
147                         Job &Dest,
148                         const InputInfo &Output,
149                         const InputInfoList &Inputs,
150                         const ArgList &Args,
151                         const char *LinkingOutput) const {
152  const Driver &D = getToolChain().getHost().getDriver();
153  ArgStringList CmdArgs;
154
155  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
156
157  CmdArgs.push_back("-triple");
158  const char *TripleStr =
159    Args.MakeArgString(getToolChain().getTripleString().c_str());
160  CmdArgs.push_back(TripleStr);
161
162  if (isa<AnalyzeJobAction>(JA)) {
163    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
164    CmdArgs.push_back("-analyze");
165  } else if (isa<PreprocessJobAction>(JA)) {
166    if (Output.getType() == types::TY_Dependencies)
167      CmdArgs.push_back("-Eonly");
168    else
169      CmdArgs.push_back("-E");
170  } else if (isa<PrecompileJobAction>(JA)) {
171    CmdArgs.push_back("-emit-pth");
172  } else {
173    assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
174
175    if (JA.getType() == types::TY_Nothing) {
176      CmdArgs.push_back("-fsyntax-only");
177    } else if (JA.getType() == types::TY_LLVMAsm) {
178      CmdArgs.push_back("-emit-llvm");
179    } else if (JA.getType() == types::TY_LLVMBC) {
180      CmdArgs.push_back("-emit-llvm-bc");
181    } else if (JA.getType() == types::TY_PP_Asm) {
182      CmdArgs.push_back("-S");
183    }
184  }
185
186  // The make clang go fast button.
187  CmdArgs.push_back("-disable-free");
188
189  // Set the main file name, so that debug info works even with
190  // -save-temps.
191  CmdArgs.push_back("-main-file-name");
192  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
193
194  // Some flags which affect the language (via preprocessor
195  // defines). See darwin::CC1::AddCPPArgs.
196  if (Args.hasArg(options::OPT_static))
197    CmdArgs.push_back("-static-define");
198
199  if (isa<AnalyzeJobAction>(JA)) {
200    // Add default argument set.
201    //
202    // FIXME: Move into clang?
203    CmdArgs.push_back("-warn-dead-stores");
204    CmdArgs.push_back("-checker-cfref");
205    CmdArgs.push_back("-analyzer-eagerly-assume");
206    CmdArgs.push_back("-warn-objc-methodsigs");
207    // Do not enable the missing -dealloc check.
208    // '-warn-objc-missing-dealloc',
209    CmdArgs.push_back("-warn-objc-unused-ivars");
210
211    CmdArgs.push_back("-analyzer-output=plist");
212
213    // Add -Xanalyzer arguments when running as analyzer.
214    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
215  } else {
216    // Perform argument translation for LLVM backend. This
217    // takes some care in reconciling with llvm-gcc. The
218    // issue is that llvm-gcc translates these options based on
219    // the values in cc1, whereas we are processing based on
220    // the driver arguments.
221    //
222    // FIXME: This is currently broken for -f flags when -fno
223    // variants are present.
224
225    // This comes from the default translation the driver + cc1
226    // would do to enable flag_pic.
227    //
228    // FIXME: Centralize this code.
229    bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
230                       Args.hasArg(options::OPT_fpic) ||
231                       Args.hasArg(options::OPT_fPIE) ||
232                       Args.hasArg(options::OPT_fpie));
233    bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
234                        Args.hasArg(options::OPT_static));
235    const char *Model = getToolChain().GetForcedPicModel();
236    if (!Model) {
237      if (Args.hasArg(options::OPT_mdynamic_no_pic))
238        Model = "dynamic-no-pic";
239      else if (PICDisabled)
240        Model = "static";
241      else if (PICEnabled)
242        Model = "pic";
243      else
244        Model = getToolChain().GetDefaultRelocationModel();
245    }
246    CmdArgs.push_back("--relocation-model");
247    CmdArgs.push_back(Model);
248
249    // Infer the __PIC__ value.
250    //
251    // FIXME:  This isn't quite right on Darwin, which always sets
252    // __PIC__=2.
253    if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
254      if (Args.hasArg(options::OPT_fPIC))
255        CmdArgs.push_back("-pic-level=2");
256      else
257        CmdArgs.push_back("-pic-level=1");
258    }
259
260    if (Args.hasArg(options::OPT_ftime_report))
261      CmdArgs.push_back("--time-passes");
262    // FIXME: Set --enable-unsafe-fp-math.
263    if (!Args.hasArg(options::OPT_fomit_frame_pointer))
264      CmdArgs.push_back("--disable-fp-elim");
265    if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
266                      options::OPT_fno_zero_initialized_in_bss,
267                      true))
268      CmdArgs.push_back("--nozero-initialized-in-bss");
269    if (Args.hasArg(options::OPT_dA) || Args.hasArg(options::OPT_fverbose_asm))
270      CmdArgs.push_back("--asm-verbose");
271    if (Args.hasArg(options::OPT_fdebug_pass_structure))
272      CmdArgs.push_back("--debug-pass=Structure");
273    if (Args.hasArg(options::OPT_fdebug_pass_arguments))
274      CmdArgs.push_back("--debug-pass=Arguments");
275    // FIXME: set --inline-threshhold=50 if (optimize_size || optimize
276    // < 3)
277    if (Args.hasFlag(options::OPT_funwind_tables,
278                     options::OPT_fno_unwind_tables,
279                     getToolChain().IsUnwindTablesDefault()))
280      CmdArgs.push_back("--unwind-tables=1");
281    else
282      CmdArgs.push_back("--unwind-tables=0");
283    if (!Args.hasFlag(options::OPT_mred_zone,
284                      options::OPT_mno_red_zone,
285                      true))
286      CmdArgs.push_back("--disable-red-zone");
287    if (Args.hasFlag(options::OPT_msoft_float,
288                     options::OPT_mno_soft_float,
289                     false))
290      CmdArgs.push_back("--soft-float");
291
292    // FIXME: Need target hooks.
293    if (memcmp(getToolChain().getPlatform().c_str(), "darwin", 6) == 0) {
294      if (getToolChain().getArchName() == "x86_64")
295        CmdArgs.push_back("--mcpu=core2");
296      else if (getToolChain().getArchName() == "i386")
297        CmdArgs.push_back("--mcpu=yonah");
298    }
299
300    // FIXME: Ignores ordering. Also, we need to find a realistic
301    // solution for this.
302    static const struct {
303      options::ID Pos, Neg;
304      const char *Name;
305    } FeatureOptions[] = {
306      { options::OPT_mmmx, options::OPT_mno_mmx, "mmx" },
307      { options::OPT_msse, options::OPT_mno_sse, "sse" },
308      { options::OPT_msse2, options::OPT_mno_sse2, "sse2" },
309      { options::OPT_msse3, options::OPT_mno_sse3, "sse3" },
310      { options::OPT_mssse3, options::OPT_mno_ssse3, "ssse3" },
311      { options::OPT_msse41, options::OPT_mno_sse41, "sse41" },
312      { options::OPT_msse42, options::OPT_mno_sse42, "sse42" },
313      { options::OPT_msse4a, options::OPT_mno_sse4a, "sse4a" },
314      { options::OPT_m3dnow, options::OPT_mno_3dnow, "3dnow" },
315      { options::OPT_m3dnowa, options::OPT_mno_3dnowa, "3dnowa" }
316    };
317    const unsigned NumFeatureOptions =
318      sizeof(FeatureOptions)/sizeof(FeatureOptions[0]);
319
320    // FIXME: Avoid std::string
321    std::string Attrs;
322    for (unsigned i=0; i < NumFeatureOptions; ++i) {
323      if (Args.hasArg(FeatureOptions[i].Pos)) {
324        if (!Attrs.empty())
325          Attrs += ',';
326        Attrs += '+';
327        Attrs += FeatureOptions[i].Name;
328      } else if (Args.hasArg(FeatureOptions[i].Neg)) {
329        if (!Attrs.empty())
330          Attrs += ',';
331        Attrs += '-';
332        Attrs += FeatureOptions[i].Name;
333      }
334    }
335    if (!Attrs.empty()) {
336      CmdArgs.push_back("--mattr");
337      CmdArgs.push_back(Args.MakeArgString(Attrs.c_str()));
338    }
339
340    if (Args.hasFlag(options::OPT_fmath_errno,
341                     options::OPT_fno_math_errno,
342                     getToolChain().IsMathErrnoDefault()))
343      CmdArgs.push_back("--fmath-errno=1");
344    else
345      CmdArgs.push_back("--fmath-errno=0");
346
347    if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
348      CmdArgs.push_back("--limit-float-precision");
349      CmdArgs.push_back(A->getValue(Args));
350    }
351
352    // FIXME: Add --stack-protector-buffer-size=<xxx> on
353    // -fstack-protect.
354
355    Arg *Unsupported;
356    if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
357        (Unsupported = Args.getLastArg(options::OPT_MQ)))
358      D.Diag(clang::diag::err_drv_unsupported_opt)
359        << Unsupported->getOption().getName();
360  }
361
362  Args.AddAllArgs(CmdArgs, options::OPT_v);
363  Args.AddLastArg(CmdArgs, options::OPT_P);
364  Args.AddLastArg(CmdArgs, options::OPT_mmacosx_version_min_EQ);
365  Args.AddLastArg(CmdArgs, options::OPT_miphoneos_version_min_EQ);
366
367  // Special case debug options to only pass -g to clang. This is
368  // wrong.
369  if (Args.hasArg(options::OPT_g_Group))
370    CmdArgs.push_back("-g");
371
372  Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
373
374  Args.AddLastArg(CmdArgs, options::OPT_isysroot);
375
376  // Add preprocessing options like -I, -D, etc. if we are using the
377  // preprocessor.
378  //
379  // FIXME: Support -fpreprocessed
380  types::ID InputType = Inputs[0].getType();
381  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
382    AddPreprocessingOptions(Args, CmdArgs, Output, Inputs);
383
384  // Manually translate -O to -O1 and -O4 to -O3; let clang reject
385  // others.
386  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
387    if (A->getOption().getId() == options::OPT_O4)
388      CmdArgs.push_back("-O3");
389    else if (A->getValue(Args)[0] == '\0')
390      CmdArgs.push_back("-O1");
391    else
392      A->render(Args, CmdArgs);
393  }
394
395  Args.AddAllArgs(CmdArgs, options::OPT_clang_W_Group,
396                  options::OPT_pedantic_Group);
397  Args.AddLastArg(CmdArgs, options::OPT_w);
398
399  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
400  // (-ansi is equivalent to -std=c89).
401  //
402  // If a std is supplied, only add -trigraphs if it follows the
403  // option.
404  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
405    if (Std->getOption().matches(options::OPT_ansi))
406      CmdArgs.push_back("-std=c89");
407    else
408      Std->render(Args, CmdArgs);
409
410    if (Arg *A = Args.getLastArg(options::OPT_trigraphs))
411      if (A->getIndex() > Std->getIndex())
412        A->render(Args, CmdArgs);
413  } else
414    Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
415
416  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
417    CmdArgs.push_back("-ftemplate-depth");
418    CmdArgs.push_back(A->getValue(Args));
419  }
420
421  // Forward -f options which we can pass directly.
422  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
423  Args.AddLastArg(CmdArgs, options::OPT_fexceptions);
424  Args.AddLastArg(CmdArgs, options::OPT_ffreestanding);
425  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
426  Args.AddLastArg(CmdArgs, options::OPT_fgnu_runtime);
427  Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions);
428  Args.AddLastArg(CmdArgs, options::OPT_fms_extensions);
429  Args.AddLastArg(CmdArgs, options::OPT_fnext_runtime);
430  Args.AddLastArg(CmdArgs, options::OPT_fno_caret_diagnostics);
431  Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
432  Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc_only);
433  Args.AddLastArg(CmdArgs, options::OPT_fobjc_gc);
434  // FIXME: Should we remove this?
435  Args.AddLastArg(CmdArgs, options::OPT_fobjc_nonfragile_abi);
436  Args.AddLastArg(CmdArgs, options::OPT_fprint_source_range_info);
437  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
438  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
439  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
440  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
441
442  // Forward -f options with positive and negative forms; we translate
443  // these by hand.
444
445  // -fbuiltin is default, only pass non-default.
446  if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
447    CmdArgs.push_back("-fbuiltin=0");
448
449  // -fblocks default varies depending on platform and language;
450  // -always pass if specified.
451  if (Arg *A = Args.getLastArg(options::OPT_fblocks, options::OPT_fno_blocks)) {
452    if (A->getOption().matches(options::OPT_fblocks))
453      CmdArgs.push_back("-fblocks");
454    else
455      CmdArgs.push_back("-fblocks=0");
456  }
457
458  // -fno-pascal-strings is default, only pass non-default. If the
459  // -tool chain happened to translate to -mpascal-strings, we want to
460  // -back translate here.
461  //
462  // FIXME: This is gross; that translation should be pulled from the
463  // tool chain.
464  if (Args.hasFlag(options::OPT_fpascal_strings,
465                   options::OPT_fno_pascal_strings,
466                   false) ||
467      Args.hasFlag(options::OPT_mpascal_strings,
468                   options::OPT_mno_pascal_strings,
469                   false))
470    CmdArgs.push_back("-fpascal-strings");
471
472  // -fcommon is default, only pass non-default.
473  if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
474    CmdArgs.push_back("-fno-common");
475
476  Args.AddLastArg(CmdArgs, options::OPT_dM);
477  Args.AddLastArg(CmdArgs, options::OPT_dD);
478
479  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
480
481  if (Output.getType() == types::TY_Dependencies) {
482    // Handled with other dependency code.
483  } else if (Output.isPipe()) {
484    CmdArgs.push_back("-o");
485    CmdArgs.push_back("-");
486  } else if (Output.isFilename()) {
487    CmdArgs.push_back("-o");
488    CmdArgs.push_back(Output.getFilename());
489  } else {
490    assert(Output.isNothing() && "Invalid output.");
491  }
492
493  for (InputInfoList::const_iterator
494         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
495    const InputInfo &II = *it;
496    CmdArgs.push_back("-x");
497    CmdArgs.push_back(types::getTypeName(II.getType()));
498    if (II.isPipe())
499      CmdArgs.push_back("-");
500    else if (II.isFilename())
501      CmdArgs.push_back(II.getFilename());
502    else
503      II.getInputArg().renderAsInput(Args, CmdArgs);
504  }
505
506  const char *Exec =
507    Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc").c_str());
508  Dest.addCommand(new Command(Exec, CmdArgs));
509
510  // Explicitly warn that these options are unsupported, even though
511  // we are allowing compilation to continue.
512  // FIXME: Use iterator.
513  for (ArgList::const_iterator
514         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
515    const Arg *A = *it;
516    if (A->getOption().matches(options::OPT_pg)) {
517      A->claim();
518      D.Diag(clang::diag::warn_drv_clang_unsupported)
519        << A->getAsString(Args);
520    }
521  }
522
523  // Claim some arguments which clang supports automatically.
524
525  // -fpch-preprocess is used with gcc to add a special marker in the
526  // -output to include the PCH file. Clang's PTH solution is
527  // -completely transparent, so we do not need to deal with it at
528  // -all.
529  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
530
531  // Claim some arguments which clang doesn't support, but we don't
532  // care to warn the user about.
533
534  // FIXME: Use iterator.
535  for (ArgList::const_iterator
536         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
537    const Arg *A = *it;
538    if (A->getOption().matches(options::OPT_clang_ignored_W_Group) ||
539        A->getOption().matches(options::OPT_clang_ignored_f_Group) ||
540        A->getOption().matches(options::OPT_clang_ignored_m_Group))
541      A->claim();
542  }
543}
544
545void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
546                               Job &Dest,
547                               const InputInfo &Output,
548                               const InputInfoList &Inputs,
549                               const ArgList &Args,
550                               const char *LinkingOutput) const {
551  ArgStringList CmdArgs;
552
553  for (ArgList::const_iterator
554         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
555    Arg *A = *it;
556    if (A->getOption().hasForwardToGCC()) {
557      // It is unfortunate that we have to claim here, as this means
558      // we will basically never report anything interesting for
559      // platforms using a generic gcc.
560      A->claim();
561      A->render(Args, CmdArgs);
562    }
563  }
564
565  RenderExtraToolArgs(CmdArgs);
566
567  // If using a driver driver, force the arch.
568  if (getToolChain().getHost().useDriverDriver()) {
569    CmdArgs.push_back("-arch");
570
571    // FIXME: Remove these special cases.
572    const char *Str = getToolChain().getArchName().c_str();
573    if (strcmp(Str, "powerpc") == 0)
574      Str = "ppc";
575    else if (strcmp(Str, "powerpc64") == 0)
576      Str = "ppc64";
577    CmdArgs.push_back(Str);
578  }
579
580  if (Output.isPipe()) {
581    CmdArgs.push_back("-o");
582    CmdArgs.push_back("-");
583  } else if (Output.isFilename()) {
584    CmdArgs.push_back("-o");
585    CmdArgs.push_back(Output.getFilename());
586  } else {
587    assert(Output.isNothing() && "Unexpected output");
588    CmdArgs.push_back("-fsyntax-only");
589  }
590
591
592  // Only pass -x if gcc will understand it; otherwise hope gcc
593  // understands the suffix correctly. The main use case this would go
594  // wrong in is for linker inputs if they happened to have an odd
595  // suffix; really the only way to get this to happen is a command
596  // like '-x foobar a.c' which will treat a.c like a linker input.
597  //
598  // FIXME: For the linker case specifically, can we safely convert
599  // inputs into '-Wl,' options?
600  for (InputInfoList::const_iterator
601         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
602    const InputInfo &II = *it;
603    if (types::canTypeBeUserSpecified(II.getType())) {
604      CmdArgs.push_back("-x");
605      CmdArgs.push_back(types::getTypeName(II.getType()));
606    }
607
608    if (II.isPipe())
609      CmdArgs.push_back("-");
610    else if (II.isFilename())
611      CmdArgs.push_back(II.getFilename());
612    else
613      // Don't render as input, we need gcc to do the translations.
614      II.getInputArg().render(Args, CmdArgs);
615  }
616
617  const char *GCCName =
618    getToolChain().getHost().getDriver().CCCGenericGCCName.c_str();
619  const char *Exec =
620    Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName).c_str());
621  Dest.addCommand(new Command(Exec, CmdArgs));
622}
623
624void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
625  CmdArgs.push_back("-E");
626}
627
628void gcc::Precompile::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
629  // The type is good enough.
630}
631
632void gcc::Compile::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
633  CmdArgs.push_back("-S");
634}
635
636void gcc::Assemble::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
637  CmdArgs.push_back("-c");
638}
639
640void gcc::Link::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
641  // The types are (hopefully) good enough.
642}
643
644const char *darwin::CC1::getCC1Name(types::ID Type) const {
645  switch (Type) {
646  default:
647    assert(0 && "Unexpected type for Darwin CC1 tool.");
648  case types::TY_Asm:
649  case types::TY_C: case types::TY_CHeader:
650  case types::TY_PP_C: case types::TY_PP_CHeader:
651    return "cc1";
652  case types::TY_ObjC: case types::TY_ObjCHeader:
653  case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
654    return "cc1obj";
655  case types::TY_CXX: case types::TY_CXXHeader:
656  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
657    return "cc1plus";
658  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
659  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
660    return "cc1objplus";
661  }
662}
663
664const char *darwin::CC1::getBaseInputName(const ArgList &Args,
665                                          const InputInfoList &Inputs) {
666  llvm::sys::Path P(Inputs[0].getBaseInput());
667  return Args.MakeArgString(P.getLast().c_str());
668}
669
670const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
671                                          const InputInfoList &Inputs) {
672  const char *Str = getBaseInputName(Args, Inputs);
673
674  if (const char *End = strchr(Str, '.'))
675    return Args.MakeArgString(std::string(Str, End).c_str());
676
677  return Str;
678}
679
680const char *
681darwin::CC1::getDependencyFileName(const ArgList &Args,
682                                   const InputInfoList &Inputs) {
683  // FIXME: Think about this more.
684  std::string Res;
685
686  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
687    std::string Str(OutputOpt->getValue(Args));
688
689    Res = Str.substr(0, Str.rfind('.'));
690  } else
691    Res = darwin::CC1::getBaseInputStem(Args, Inputs);
692
693  return Args.MakeArgString((Res + ".d").c_str());
694}
695
696void darwin::CC1::AddCC1Args(const ArgList &Args,
697                             ArgStringList &CmdArgs) const {
698  // Derived from cc1 spec.
699
700  // FIXME: -fapple-kext seems to disable this too. Investigate.
701  if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
702      !Args.hasArg(options::OPT_mdynamic_no_pic))
703    CmdArgs.push_back("-fPIC");
704
705  // gcc has some code here to deal with when no -mmacosx-version-min
706  // and no -miphoneos-version-min is present, but this never happens
707  // due to tool chain specific argument translation.
708
709  // FIXME: Remove mthumb
710  // FIXME: Remove mno-thumb
711  // FIXME: Remove faltivec
712  // FIXME: Remove mno-fused-madd
713  // FIXME: Remove mlong-branch
714  // FIXME: Remove mlongcall
715  // FIXME: Remove mcpu=G4
716  // FIXME: Remove mcpu=G5
717
718  if (Args.hasArg(options::OPT_g_Flag) &&
719      !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
720    CmdArgs.push_back("-feliminate-unused-debug-symbols");
721}
722
723void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
724                                    const InputInfoList &Inputs,
725                                    const ArgStringList &OutputArgs) const {
726  const Driver &D = getToolChain().getHost().getDriver();
727
728  // Derived from cc1_options spec.
729  if (Args.hasArg(options::OPT_fast) ||
730      Args.hasArg(options::OPT_fastf) ||
731      Args.hasArg(options::OPT_fastcp))
732    CmdArgs.push_back("-O3");
733
734  if (Arg *A = Args.getLastArg(options::OPT_pg))
735    if (Args.hasArg(options::OPT_fomit_frame_pointer))
736      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
737        << A->getAsString(Args) << "-fomit-frame-pointer";
738
739  AddCC1Args(Args, CmdArgs);
740
741  if (!Args.hasArg(options::OPT_Q))
742    CmdArgs.push_back("-quiet");
743
744  CmdArgs.push_back("-dumpbase");
745  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
746
747  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
748
749  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
750  Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
751
752  // FIXME: The goal is to use the user provided -o if that is our
753  // final output, otherwise to drive from the original input
754  // name. Find a clean way to go about this.
755  if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
756      Args.hasArg(options::OPT_o)) {
757    Arg *OutputOpt = Args.getLastArg(options::OPT_o);
758    CmdArgs.push_back("-auxbase-strip");
759    CmdArgs.push_back(OutputOpt->getValue(Args));
760  } else {
761    CmdArgs.push_back("-auxbase");
762    CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
763  }
764
765  Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
766
767  Args.AddAllArgs(CmdArgs, options::OPT_O);
768  // FIXME: -Wall is getting some special treatment. Investigate.
769  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
770  Args.AddLastArg(CmdArgs, options::OPT_w);
771  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
772                  options::OPT_trigraphs);
773  if (Args.hasArg(options::OPT_v))
774    CmdArgs.push_back("-version");
775  if (Args.hasArg(options::OPT_pg))
776    CmdArgs.push_back("-p");
777  Args.AddLastArg(CmdArgs, options::OPT_p);
778
779  // The driver treats -fsyntax-only specially.
780  Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
781
782  Args.AddAllArgs(CmdArgs, options::OPT_undef);
783  if (Args.hasArg(options::OPT_Qn))
784    CmdArgs.push_back("-fno-ident");
785
786  // FIXME: This isn't correct.
787  //Args.AddLastArg(CmdArgs, options::OPT__help)
788  //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
789
790  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
791
792  // FIXME: Still don't get what is happening here. Investigate.
793  Args.AddAllArgs(CmdArgs, options::OPT__param);
794
795  if (Args.hasArg(options::OPT_fmudflap) ||
796      Args.hasArg(options::OPT_fmudflapth)) {
797    CmdArgs.push_back("-fno-builtin");
798    CmdArgs.push_back("-fno-merge-constants");
799  }
800
801  if (Args.hasArg(options::OPT_coverage)) {
802    CmdArgs.push_back("-fprofile-arcs");
803    CmdArgs.push_back("-ftest-coverage");
804  }
805
806  if (types::isCXX(Inputs[0].getType()))
807    CmdArgs.push_back("-D__private_extern__=extern");
808}
809
810void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
811                                    const InputInfoList &Inputs,
812                                    const ArgStringList &OutputArgs) const {
813  // Derived from cpp_options
814  AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
815
816  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
817
818  AddCC1Args(Args, CmdArgs);
819
820  // NOTE: The code below has some commonality with cpp_options, but
821  // in classic gcc style ends up sending things in different
822  // orders. This may be a good merge candidate once we drop pedantic
823  // compatibility.
824
825  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
826  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
827                  options::OPT_trigraphs);
828  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
829  Args.AddLastArg(CmdArgs, options::OPT_w);
830
831  // The driver treats -fsyntax-only specially.
832  Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
833
834  if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
835      !Args.hasArg(options::OPT_fno_working_directory))
836    CmdArgs.push_back("-fworking-directory");
837
838  Args.AddAllArgs(CmdArgs, options::OPT_O);
839  Args.AddAllArgs(CmdArgs, options::OPT_undef);
840  if (Args.hasArg(options::OPT_save_temps))
841    CmdArgs.push_back("-fpch-preprocess");
842}
843
844void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
845                                          ArgStringList &CmdArgs,
846                                          const InputInfoList &Inputs) const
847{
848  const Driver &D = getToolChain().getHost().getDriver();
849
850  // Derived from cpp_unique_options.
851  Arg *A;
852  if ((A = Args.getLastArg(options::OPT_C)) ||
853      (A = Args.getLastArg(options::OPT_CC))) {
854    if (!Args.hasArg(options::OPT_E))
855      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
856        << A->getAsString(Args) << "-E";
857  }
858  if (!Args.hasArg(options::OPT_Q))
859    CmdArgs.push_back("-quiet");
860  Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
861  Args.AddLastArg(CmdArgs, options::OPT_v);
862  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
863  Args.AddLastArg(CmdArgs, options::OPT_P);
864
865  // FIXME: Handle %I properly.
866  if (getToolChain().getArchName() == "x86_64") {
867    CmdArgs.push_back("-imultilib");
868    CmdArgs.push_back("x86_64");
869  }
870
871  if (Args.hasArg(options::OPT_MD)) {
872    CmdArgs.push_back("-MD");
873    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
874  }
875
876  if (Args.hasArg(options::OPT_MMD)) {
877    CmdArgs.push_back("-MMD");
878    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
879  }
880
881  Args.AddLastArg(CmdArgs, options::OPT_M);
882  Args.AddLastArg(CmdArgs, options::OPT_MM);
883  Args.AddAllArgs(CmdArgs, options::OPT_MF);
884  Args.AddLastArg(CmdArgs, options::OPT_MG);
885  Args.AddLastArg(CmdArgs, options::OPT_MP);
886  Args.AddAllArgs(CmdArgs, options::OPT_MQ);
887  Args.AddAllArgs(CmdArgs, options::OPT_MT);
888  if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
889      (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
890    if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
891      CmdArgs.push_back("-MQ");
892      CmdArgs.push_back(OutputOpt->getValue(Args));
893    }
894  }
895
896  Args.AddLastArg(CmdArgs, options::OPT_remap);
897  if (Args.hasArg(options::OPT_g3))
898    CmdArgs.push_back("-dD");
899  Args.AddLastArg(CmdArgs, options::OPT_H);
900
901  AddCPPArgs(Args, CmdArgs);
902
903  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
904  Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
905
906  for (InputInfoList::const_iterator
907         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
908    const InputInfo &II = *it;
909
910    if (II.isPipe())
911      CmdArgs.push_back("-");
912    else
913      CmdArgs.push_back(II.getFilename());
914  }
915
916  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
917                       options::OPT_Xpreprocessor);
918
919  if (Args.hasArg(options::OPT_fmudflap)) {
920    CmdArgs.push_back("-D_MUDFLAP");
921    CmdArgs.push_back("-include");
922    CmdArgs.push_back("mf-runtime.h");
923  }
924
925  if (Args.hasArg(options::OPT_fmudflapth)) {
926    CmdArgs.push_back("-D_MUDFLAP");
927    CmdArgs.push_back("-D_MUDFLAPTH");
928    CmdArgs.push_back("-include");
929    CmdArgs.push_back("mf-runtime.h");
930  }
931}
932
933void darwin::CC1::AddCPPArgs(const ArgList &Args,
934                             ArgStringList &CmdArgs) const {
935  // Derived from cpp spec.
936
937  if (Args.hasArg(options::OPT_static)) {
938    // The gcc spec is broken here, it refers to dynamic but
939    // that has been translated. Start by being bug compatible.
940
941    // if (!Args.hasArg(arglist.parser.dynamicOption))
942    CmdArgs.push_back("-D__STATIC__");
943  } else
944    CmdArgs.push_back("-D__DYNAMIC__");
945
946  if (Args.hasArg(options::OPT_pthread))
947    CmdArgs.push_back("-D_REENTRANT");
948}
949
950void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
951                                      Job &Dest, const InputInfo &Output,
952                                      const InputInfoList &Inputs,
953                                      const ArgList &Args,
954                                      const char *LinkingOutput) const {
955  ArgStringList CmdArgs;
956
957  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
958
959  CmdArgs.push_back("-E");
960
961  if (Args.hasArg(options::OPT_traditional) ||
962      Args.hasArg(options::OPT_ftraditional) ||
963      Args.hasArg(options::OPT_traditional_cpp))
964    CmdArgs.push_back("-traditional-cpp");
965
966  ArgStringList OutputArgs;
967  if (Output.isFilename()) {
968    OutputArgs.push_back("-o");
969    OutputArgs.push_back(Output.getFilename());
970  } else {
971    assert(Output.isPipe() && "Unexpected CC1 output.");
972  }
973
974  if (Args.hasArg(options::OPT_E)) {
975    AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
976  } else {
977    AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
978    CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
979  }
980
981  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
982
983  const char *CC1Name = getCC1Name(Inputs[0].getType());
984  const char *Exec =
985    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
986  Dest.addCommand(new Command(Exec, CmdArgs));
987}
988
989void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
990                                   Job &Dest, const InputInfo &Output,
991                                   const InputInfoList &Inputs,
992                                   const ArgList &Args,
993                                   const char *LinkingOutput) const {
994  const Driver &D = getToolChain().getHost().getDriver();
995  ArgStringList CmdArgs;
996
997  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
998
999  types::ID InputType = Inputs[0].getType();
1000  const Arg *A;
1001  if ((A = Args.getLastArg(options::OPT_traditional)) ||
1002      (A = Args.getLastArg(options::OPT_ftraditional)))
1003    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
1004      << A->getAsString(Args) << "-E";
1005
1006  if (Output.getType() == types::TY_LLVMAsm)
1007    CmdArgs.push_back("-emit-llvm");
1008  else if (Output.getType() == types::TY_LLVMBC)
1009    CmdArgs.push_back("-emit-llvm-bc");
1010
1011  ArgStringList OutputArgs;
1012  if (Output.getType() != types::TY_PCH) {
1013    OutputArgs.push_back("-o");
1014    if (Output.isPipe())
1015      OutputArgs.push_back("-");
1016    else if (Output.isNothing())
1017      OutputArgs.push_back("/dev/null");
1018    else
1019      OutputArgs.push_back(Output.getFilename());
1020  }
1021
1022  // There is no need for this level of compatibility, but it makes
1023  // diffing easier.
1024  bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
1025                          Args.hasArg(options::OPT_S));
1026
1027  if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
1028    AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
1029    if (OutputArgsEarly) {
1030      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1031    } else {
1032      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1033      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1034    }
1035  } else {
1036    CmdArgs.push_back("-fpreprocessed");
1037
1038    // FIXME: There is a spec command to remove
1039    // -fpredictive-compilation args here. Investigate.
1040
1041    for (InputInfoList::const_iterator
1042           it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1043      const InputInfo &II = *it;
1044
1045      if (II.isPipe())
1046        CmdArgs.push_back("-");
1047      else
1048        CmdArgs.push_back(II.getFilename());
1049    }
1050
1051    if (OutputArgsEarly) {
1052      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
1053    } else {
1054      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
1055      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1056    }
1057  }
1058
1059  if (Output.getType() == types::TY_PCH) {
1060    assert(Output.isFilename() && "Invalid PCH output.");
1061
1062    CmdArgs.push_back("-o");
1063    // NOTE: gcc uses a temp .s file for this, but there doesn't seem
1064    // to be a good reason.
1065    CmdArgs.push_back("/dev/null");
1066
1067    CmdArgs.push_back("--output-pch=");
1068    CmdArgs.push_back(Output.getFilename());
1069  }
1070
1071  const char *CC1Name = getCC1Name(Inputs[0].getType());
1072  const char *Exec =
1073    Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
1074  Dest.addCommand(new Command(Exec, CmdArgs));
1075}
1076
1077void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
1078                                    Job &Dest, const InputInfo &Output,
1079                                    const InputInfoList &Inputs,
1080                                    const ArgList &Args,
1081                                    const char *LinkingOutput) const {
1082  ArgStringList CmdArgs;
1083
1084  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
1085  const InputInfo &Input = Inputs[0];
1086
1087  // Bit of a hack, this is only used for original inputs.
1088  //
1089  // FIXME: This is broken for preprocessed .s inputs.
1090  if (Input.isFilename() &&
1091      strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
1092    if (Args.hasArg(options::OPT_gstabs))
1093      CmdArgs.push_back("--gstabs");
1094    else if (Args.hasArg(options::OPT_g_Group))
1095      CmdArgs.push_back("--gdwarf2");
1096  }
1097
1098  // Derived from asm spec.
1099  CmdArgs.push_back("-arch");
1100  CmdArgs.push_back(getToolChain().getArchName().c_str());
1101
1102  CmdArgs.push_back("-force_cpusubtype_ALL");
1103  if ((Args.hasArg(options::OPT_mkernel) ||
1104       Args.hasArg(options::OPT_static) ||
1105       Args.hasArg(options::OPT_fapple_kext)) &&
1106      !Args.hasArg(options::OPT_dynamic))
1107    CmdArgs.push_back("-static");
1108
1109  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
1110                       options::OPT_Xassembler);
1111
1112  assert(Output.isFilename() && "Unexpected lipo output.");
1113  CmdArgs.push_back("-o");
1114  CmdArgs.push_back(Output.getFilename());
1115
1116  if (Input.isPipe()) {
1117    CmdArgs.push_back("-");
1118  } else {
1119    assert(Input.isFilename() && "Invalid input.");
1120    CmdArgs.push_back(Input.getFilename());
1121  }
1122
1123  // asm_final spec is empty.
1124
1125  const char *Exec =
1126    Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
1127  Dest.addCommand(new Command(Exec, CmdArgs));
1128}
1129
1130static const char *MakeFormattedString(const ArgList &Args,
1131                                       const llvm::format_object_base &Fmt) {
1132  std::string Str;
1133  llvm::raw_string_ostream(Str) << Fmt;
1134  return Args.MakeArgString(Str.c_str());
1135}
1136
1137/// Helper routine for seeing if we should use dsymutil; this is a
1138/// gcc compatible hack, we should remove it and use the input
1139/// type information.
1140static bool isSourceSuffix(const char *Str) {
1141  // match: 'C', 'CPP', 'c', 'cc', 'cp', 'c++', 'cpp', 'cxx', 'm',
1142  // 'mm'.
1143  switch (strlen(Str)) {
1144  default:
1145    return false;
1146  case 1:
1147    return (memcmp(Str, "C", 1) == 0 ||
1148            memcmp(Str, "c", 1) == 0 ||
1149            memcmp(Str, "m", 1) == 0);
1150  case 2:
1151    return (memcmp(Str, "cc", 2) == 0 ||
1152            memcmp(Str, "cp", 2) == 0 ||
1153            memcmp(Str, "mm", 2) == 0);
1154  case 3:
1155    return (memcmp(Str, "CPP", 3) == 0 ||
1156            memcmp(Str, "c++", 3) == 0 ||
1157            memcmp(Str, "cpp", 3) == 0 ||
1158            memcmp(Str, "cxx", 3) == 0);
1159  }
1160}
1161
1162static bool isMacosxVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
1163  for (unsigned i=0; i < 3; ++i) {
1164    if (A[i] > B[i]) return false;
1165    if (A[i] < B[i]) return true;
1166  }
1167  return false;
1168}
1169
1170static bool isMacosxVersionLT(unsigned (&A)[3],
1171                              unsigned V0, unsigned V1=0, unsigned V2=0) {
1172  unsigned B[3] = { V0, V1, V2 };
1173  return isMacosxVersionLT(A, B);
1174}
1175
1176const toolchains::Darwin_X86 &darwin::Link::getDarwinToolChain() const {
1177  return reinterpret_cast<const toolchains::Darwin_X86&>(getToolChain());
1178}
1179
1180void darwin::Link::AddDarwinArch(const ArgList &Args,
1181                                 ArgStringList &CmdArgs) const {
1182  // Derived from darwin_arch spec.
1183  CmdArgs.push_back("-arch");
1184  CmdArgs.push_back(getToolChain().getArchName().c_str());
1185}
1186
1187void darwin::Link::AddDarwinSubArch(const ArgList &Args,
1188                                    ArgStringList &CmdArgs) const {
1189  // Derived from darwin_subarch spec, not sure what the distinction
1190  // exists for but at least for this chain it is the same.
1191  AddDarwinArch(Args, CmdArgs);
1192}
1193
1194void darwin::Link::AddLinkArgs(const ArgList &Args,
1195                               ArgStringList &CmdArgs) const {
1196  const Driver &D = getToolChain().getHost().getDriver();
1197
1198  // Derived from the "link" spec.
1199  Args.AddAllArgs(CmdArgs, options::OPT_static);
1200  if (!Args.hasArg(options::OPT_static))
1201    CmdArgs.push_back("-dynamic");
1202  if (Args.hasArg(options::OPT_fgnu_runtime)) {
1203    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
1204    // here. How do we wish to handle such things?
1205  }
1206
1207  if (!Args.hasArg(options::OPT_dynamiclib)) {
1208    if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
1209      AddDarwinArch(Args, CmdArgs);
1210      CmdArgs.push_back("-force_cpusubtype_ALL");
1211    } else
1212      AddDarwinSubArch(Args, CmdArgs);
1213
1214    Args.AddLastArg(CmdArgs, options::OPT_bundle);
1215    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
1216    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
1217
1218    Arg *A;
1219    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
1220        (A = Args.getLastArg(options::OPT_current__version)) ||
1221        (A = Args.getLastArg(options::OPT_install__name)))
1222      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
1223        << A->getAsString(Args) << "-dynamiclib";
1224
1225    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
1226    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
1227    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
1228  } else {
1229    CmdArgs.push_back("-dylib");
1230
1231    Arg *A;
1232    if ((A = Args.getLastArg(options::OPT_bundle)) ||
1233        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
1234        (A = Args.getLastArg(options::OPT_client__name)) ||
1235        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
1236        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
1237        (A = Args.getLastArg(options::OPT_private__bundle)))
1238      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1239        << A->getAsString(Args) << "-dynamiclib";
1240
1241    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
1242                              "-dylib_compatibility_version");
1243    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
1244                              "-dylib_current_version");
1245
1246    if (Args.hasArg(options::OPT_force__cpusubtype__ALL)) {
1247      AddDarwinArch(Args, CmdArgs);
1248      // NOTE: We don't add -force_cpusubtype_ALL on this path. Ok.
1249    } else
1250      AddDarwinSubArch(Args, CmdArgs);
1251
1252    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
1253                              "-dylib_install_name");
1254  }
1255
1256  Args.AddLastArg(CmdArgs, options::OPT_all__load);
1257  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
1258  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
1259  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
1260  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
1261  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
1262  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
1263  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
1264  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
1265  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
1266  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
1267  Args.AddAllArgs(CmdArgs, options::OPT_init);
1268
1269  if (!Args.hasArg(options::OPT_mmacosx_version_min_EQ)) {
1270    if (!Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
1271      // FIXME: I don't understand what is going on here. This is
1272      // supposed to come from darwin_ld_minversion, but gcc doesn't
1273      // seem to be following that; it must be getting overridden
1274      // somewhere.
1275      CmdArgs.push_back("-macosx_version_min");
1276      CmdArgs.push_back(getDarwinToolChain().getMacosxVersionStr());
1277    }
1278  } else {
1279    // Adding all arguments doesn't make sense here but this is what
1280    // gcc does.
1281    Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
1282                              "-macosx_version_min");
1283  }
1284
1285  Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
1286                            "-iphoneos_version_min");
1287  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
1288  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
1289  Args.AddLastArg(CmdArgs, options::OPT_single__module);
1290  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
1291  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
1292
1293  if (Args.hasArg(options::OPT_fpie))
1294    CmdArgs.push_back("-pie");
1295
1296  Args.AddLastArg(CmdArgs, options::OPT_prebind);
1297  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
1298  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
1299  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
1300  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
1301  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
1302  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
1303  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
1304  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
1305  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
1306  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
1307  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
1308  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
1309  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
1310  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
1311  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
1312  Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
1313  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
1314  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
1315  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
1316  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
1317  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
1318  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
1319
1320  if (!Args.hasArg(options::OPT_weak__reference__mismatches)) {
1321    CmdArgs.push_back("-weak_reference_mismatches");
1322    CmdArgs.push_back("non-weak");
1323  }
1324
1325  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
1326  Args.AddAllArgs(CmdArgs, options::OPT_y);
1327  Args.AddLastArg(CmdArgs, options::OPT_w);
1328  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
1329  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
1330  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
1331  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
1332  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
1333  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
1334  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
1335  Args.AddLastArg(CmdArgs, options::OPT_whyload);
1336  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
1337  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
1338  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
1339  Args.AddLastArg(CmdArgs, options::OPT_Mach);
1340}
1341
1342void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
1343                                Job &Dest, const InputInfo &Output,
1344                                const InputInfoList &Inputs,
1345                                const ArgList &Args,
1346                                const char *LinkingOutput) const {
1347  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
1348  // The logic here is derived from gcc's behavior; most of which
1349  // comes from specs (starting with link_command). Consult gcc for
1350  // more information.
1351
1352  // FIXME: The spec references -fdump= which seems to have
1353  // disappeared?
1354
1355  ArgStringList CmdArgs;
1356
1357  // I'm not sure why this particular decomposition exists in gcc, but
1358  // we follow suite for ease of comparison.
1359  AddLinkArgs(Args, CmdArgs);
1360
1361  // FIXME: gcc has %{x} in here. How could this ever happen?  Cruft?
1362  Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
1363  Args.AddAllArgs(CmdArgs, options::OPT_s);
1364  Args.AddAllArgs(CmdArgs, options::OPT_t);
1365  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
1366  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
1367  Args.AddAllArgs(CmdArgs, options::OPT_A);
1368  Args.AddLastArg(CmdArgs, options::OPT_e);
1369  Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
1370  Args.AddAllArgs(CmdArgs, options::OPT_r);
1371
1372  // FIXME: This is just being pedantically bug compatible, gcc
1373  // doesn't *mean* to forward this, it just does (yay for pattern
1374  // matching). It doesn't work, of course.
1375  Args.AddAllArgs(CmdArgs, options::OPT_object);
1376
1377  CmdArgs.push_back("-o");
1378  CmdArgs.push_back(Output.getFilename());
1379
1380  unsigned MacosxVersion[3];
1381  if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ)) {
1382    bool HadExtra;
1383    if (!Driver::GetReleaseVersion(A->getValue(Args), MacosxVersion[0],
1384                                   MacosxVersion[1], MacosxVersion[2],
1385                                   HadExtra) ||
1386        HadExtra) {
1387      const Driver &D = getToolChain().getHost().getDriver();
1388      D.Diag(clang::diag::err_drv_invalid_version_number)
1389        << A->getAsString(Args);
1390    }
1391  } else {
1392    getDarwinToolChain().getMacosxVersion(MacosxVersion);
1393  }
1394
1395  if (!Args.hasArg(options::OPT_A) &&
1396      !Args.hasArg(options::OPT_nostdlib) &&
1397      !Args.hasArg(options::OPT_nostartfiles)) {
1398    // Derived from startfile spec.
1399    if (Args.hasArg(options::OPT_dynamiclib)) {
1400      // Derived from darwin_dylib1 spec.
1401      if (isMacosxVersionLT(MacosxVersion, 10, 5))
1402        CmdArgs.push_back("-ldylib1.o");
1403      else if (isMacosxVersionLT(MacosxVersion, 10, 6))
1404        CmdArgs.push_back("-ldylib1.10.5.o");
1405    } else {
1406      if (Args.hasArg(options::OPT_bundle)) {
1407        if (!Args.hasArg(options::OPT_static)) {
1408          // Derived from darwin_bundle1 spec.
1409          if (isMacosxVersionLT(MacosxVersion, 10, 6))
1410            CmdArgs.push_back("-lbundle1.o");
1411        }
1412      } else {
1413        if (Args.hasArg(options::OPT_pg)) {
1414          if (Args.hasArg(options::OPT_static) ||
1415              Args.hasArg(options::OPT_object) ||
1416              Args.hasArg(options::OPT_preload)) {
1417            CmdArgs.push_back("-lgcrt0.o");
1418          } else {
1419            CmdArgs.push_back("-lgcrt1.o");
1420
1421            // darwin_crt2 spec is empty.
1422          }
1423        } else {
1424          if (Args.hasArg(options::OPT_static) ||
1425              Args.hasArg(options::OPT_object) ||
1426              Args.hasArg(options::OPT_preload)) {
1427            CmdArgs.push_back("-lcrt0.o");
1428          } else {
1429            // Derived from darwin_crt1 spec.
1430            if (isMacosxVersionLT(MacosxVersion, 10, 5))
1431              CmdArgs.push_back("-lcrt1.o");
1432            else if (isMacosxVersionLT(MacosxVersion, 10, 6))
1433              CmdArgs.push_back("-lcrt1.10.5.o");
1434            else
1435              CmdArgs.push_back("-lcrt1.10.6.o");
1436
1437            // darwin_crt2 spec is empty.
1438          }
1439        }
1440      }
1441    }
1442
1443    if (Args.hasArg(options::OPT_shared_libgcc) &&
1444        !Args.hasArg(options::OPT_miphoneos_version_min_EQ) &&
1445        isMacosxVersionLT(MacosxVersion, 10, 5)) {
1446      const char *Str = getToolChain().GetFilePath(C, "crt3.o").c_str();
1447      CmdArgs.push_back(Args.MakeArgString(Str));
1448    }
1449  }
1450
1451  Args.AddAllArgs(CmdArgs, options::OPT_L);
1452
1453  if (Args.hasArg(options::OPT_fopenmp))
1454    // This is more complicated in gcc...
1455    CmdArgs.push_back("-lgomp");
1456
1457  // FIXME: Derive these correctly.
1458  const char *TCDir = getDarwinToolChain().getToolChainDir().c_str();
1459  if (getToolChain().getArchName() == "x86_64") {
1460    CmdArgs.push_back(MakeFormattedString(Args,
1461                                          llvm::format("-L/usr/lib/gcc/%s/x86_64", TCDir)));
1462    // Intentionally duplicated for (temporary) gcc bug compatibility.
1463    CmdArgs.push_back(MakeFormattedString(Args,
1464                                          llvm::format("-L/usr/lib/gcc/%s/x86_64", TCDir)));
1465  }
1466  CmdArgs.push_back(MakeFormattedString(Args,
1467                                        llvm::format("-L/usr/lib/%s", TCDir)));
1468  CmdArgs.push_back(MakeFormattedString(Args,
1469                                        llvm::format("-L/usr/lib/gcc/%s", TCDir)));
1470  // Intentionally duplicated for (temporary) gcc bug compatibility.
1471  CmdArgs.push_back(MakeFormattedString(Args,
1472                                        llvm::format("-L/usr/lib/gcc/%s", TCDir)));
1473  CmdArgs.push_back(MakeFormattedString(Args,
1474                                        llvm::format("-L/usr/lib/gcc/%s/../../../%s", TCDir, TCDir)));
1475  CmdArgs.push_back(MakeFormattedString(Args,
1476                                        llvm::format("-L/usr/lib/gcc/%s/../../..", TCDir)));
1477
1478  for (InputInfoList::const_iterator
1479         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1480    const InputInfo &II = *it;
1481    if (II.isFilename())
1482      CmdArgs.push_back(II.getFilename());
1483    else
1484      II.getInputArg().renderAsInput(Args, CmdArgs);
1485  }
1486
1487  if (LinkingOutput) {
1488    CmdArgs.push_back("-arch_multiple");
1489    CmdArgs.push_back("-final_output");
1490    CmdArgs.push_back(LinkingOutput);
1491  }
1492
1493  if (Args.hasArg(options::OPT_fprofile_arcs) ||
1494      Args.hasArg(options::OPT_fprofile_generate) ||
1495      Args.hasArg(options::OPT_fcreate_profile) ||
1496      Args.hasArg(options::OPT_coverage))
1497    CmdArgs.push_back("-lgcov");
1498
1499  if (Args.hasArg(options::OPT_fnested_functions))
1500    CmdArgs.push_back("-allow_stack_execute");
1501
1502  if (!Args.hasArg(options::OPT_nostdlib) &&
1503      !Args.hasArg(options::OPT_nodefaultlibs)) {
1504    // FIXME: g++ is more complicated here, it tries to put -lstdc++
1505    // before -lm, for example.
1506    if (getToolChain().getHost().getDriver().CCCIsCXX)
1507      CmdArgs.push_back("-lstdc++");
1508
1509    // link_ssp spec is empty.
1510
1511    // Derived from libgcc and lib specs but refactored.
1512    if (Args.hasArg(options::OPT_static)) {
1513      CmdArgs.push_back("-lgcc_static");
1514    } else {
1515      if (Args.hasArg(options::OPT_static_libgcc)) {
1516        CmdArgs.push_back("-lgcc_eh");
1517      } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) {
1518        // Derived from darwin_iphoneos_libgcc spec.
1519        CmdArgs.push_back("-lgcc_s.10.5");
1520      } else if (Args.hasArg(options::OPT_shared_libgcc) ||
1521                 Args.hasArg(options::OPT_fexceptions) ||
1522                 Args.hasArg(options::OPT_fgnu_runtime)) {
1523        // FIXME: This is probably broken on 10.3?
1524        if (isMacosxVersionLT(MacosxVersion, 10, 5))
1525          CmdArgs.push_back("-lgcc_s.10.4");
1526        else if (isMacosxVersionLT(MacosxVersion, 10, 6))
1527          CmdArgs.push_back("-lgcc_s.10.5");
1528      } else {
1529        if (isMacosxVersionLT(MacosxVersion, 10, 3, 9))
1530          ; // Do nothing.
1531        else if (isMacosxVersionLT(MacosxVersion, 10, 5))
1532          CmdArgs.push_back("-lgcc_s.10.4");
1533        else if (isMacosxVersionLT(MacosxVersion, 10, 6))
1534          CmdArgs.push_back("-lgcc_s.10.5");
1535      }
1536
1537      if (isMacosxVersionLT(MacosxVersion, 10, 6)) {
1538        CmdArgs.push_back("-lgcc");
1539        CmdArgs.push_back("-lSystem");
1540      } else {
1541        CmdArgs.push_back("-lSystem");
1542        CmdArgs.push_back("-lgcc");
1543      }
1544    }
1545  }
1546
1547  if (!Args.hasArg(options::OPT_A) &&
1548      !Args.hasArg(options::OPT_nostdlib) &&
1549      !Args.hasArg(options::OPT_nostartfiles)) {
1550    // endfile_spec is empty.
1551  }
1552
1553  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
1554  Args.AddAllArgs(CmdArgs, options::OPT_F);
1555
1556  const char *Exec =
1557    Args.MakeArgString(getToolChain().GetProgramPath(C, "collect2").c_str());
1558  Dest.addCommand(new Command(Exec, CmdArgs));
1559
1560  // Find the first non-empty base input (we want to ignore linker
1561  // inputs).
1562  const char *BaseInput = "";
1563  for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
1564    if (Inputs[i].getBaseInput()[0] != '\0') {
1565      BaseInput = Inputs[i].getBaseInput();
1566      break;
1567    }
1568  }
1569
1570  if (Args.getLastArg(options::OPT_g_Group) &&
1571      !Args.getLastArg(options::OPT_gstabs) &&
1572      !Args.getLastArg(options::OPT_g0)) {
1573    // FIXME: This is gross, but matches gcc. The test only considers
1574    // the suffix (not the -x type), and then only of the first
1575    // source input. Awesome.
1576    const char *Suffix = strrchr(BaseInput, '.');
1577    if (Suffix && isSourceSuffix(Suffix + 1)) {
1578      const char *Exec =
1579        Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil").c_str());
1580      ArgStringList CmdArgs;
1581      CmdArgs.push_back(Output.getFilename());
1582      C.getJobs().addCommand(new Command(Exec, CmdArgs));
1583    }
1584  }
1585}
1586
1587void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
1588                                Job &Dest, const InputInfo &Output,
1589                                const InputInfoList &Inputs,
1590                                const ArgList &Args,
1591                                const char *LinkingOutput) const {
1592  ArgStringList CmdArgs;
1593
1594  CmdArgs.push_back("-create");
1595  assert(Output.isFilename() && "Unexpected lipo output.");
1596
1597  CmdArgs.push_back("-output");
1598  CmdArgs.push_back(Output.getFilename());
1599
1600  for (InputInfoList::const_iterator
1601         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1602    const InputInfo &II = *it;
1603    assert(II.isFilename() && "Unexpected lipo input.");
1604    CmdArgs.push_back(II.getFilename());
1605  }
1606  const char *Exec =
1607    Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo").c_str());
1608  Dest.addCommand(new Command(Exec, CmdArgs));
1609}
1610
1611
1612void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
1613                                     Job &Dest, const InputInfo &Output,
1614                                     const InputInfoList &Inputs,
1615                                     const ArgList &Args,
1616                                     const char *LinkingOutput) const
1617{
1618  ArgStringList CmdArgs;
1619
1620  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
1621  // instruct as in the base system to assemble 32-bit code.
1622  if (getToolChain().getArchName() == "i386")
1623    CmdArgs.push_back("--32");
1624
1625  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
1626                       options::OPT_Xassembler);
1627
1628  CmdArgs.push_back("-o");
1629  if (Output.isPipe())
1630    CmdArgs.push_back("-");
1631  else
1632    CmdArgs.push_back(Output.getFilename());
1633
1634  for (InputInfoList::const_iterator
1635         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1636    const InputInfo &II = *it;
1637    if (II.isPipe())
1638      CmdArgs.push_back("-");
1639    else
1640      CmdArgs.push_back(II.getFilename());
1641  }
1642
1643  const char *Exec =
1644    Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
1645  Dest.addCommand(new Command(Exec, CmdArgs));
1646}
1647
1648void freebsd::Link::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{
1654  ArgStringList CmdArgs;
1655
1656  if (Args.hasArg(options::OPT_static)) {
1657    CmdArgs.push_back("-Bstatic");
1658  } else {
1659    CmdArgs.push_back("--eh-frame-hdr");
1660    if (Args.hasArg(options::OPT_shared)) {
1661      CmdArgs.push_back("-Bshareable");
1662    } else {
1663      CmdArgs.push_back("-dynamic-linker");
1664      CmdArgs.push_back("/libexec/ld-elf.so.1");
1665    }
1666  }
1667
1668  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
1669  // instruct ld in the base system to link 32-bit code.
1670  if (getToolChain().getArchName() == "i386") {
1671    CmdArgs.push_back("-m");
1672    CmdArgs.push_back("elf_i386_fbsd");
1673  }
1674
1675  if (Output.isPipe()) {
1676    CmdArgs.push_back("-o");
1677    CmdArgs.push_back("-");
1678  } else if (Output.isFilename()) {
1679    CmdArgs.push_back("-o");
1680    CmdArgs.push_back(Output.getFilename());
1681  } else {
1682    assert(Output.isNothing() && "Invalid output.");
1683  }
1684
1685  if (!Args.hasArg(options::OPT_nostdlib) &&
1686      !Args.hasArg(options::OPT_nostartfiles)) {
1687    if (!Args.hasArg(options::OPT_shared)) {
1688      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt1.o").c_str()));
1689      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o").c_str()));
1690      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o").c_str()));
1691    } else {
1692      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crti.o").c_str()));
1693      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o").c_str()));
1694    }
1695  }
1696
1697  Args.AddAllArgs(CmdArgs, options::OPT_L);
1698  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
1699  Args.AddAllArgs(CmdArgs, options::OPT_e);
1700
1701  for (InputInfoList::const_iterator
1702         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1703    const InputInfo &II = *it;
1704    if (II.isPipe())
1705      CmdArgs.push_back("-");
1706    else if (II.isFilename())
1707      CmdArgs.push_back(II.getFilename());
1708    else
1709      II.getInputArg().renderAsInput(Args, CmdArgs);
1710  }
1711
1712  if (!Args.hasArg(options::OPT_nostdlib) &&
1713      !Args.hasArg(options::OPT_nodefaultlibs)) {
1714    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
1715    // the default system libraries. Just mimic this for now.
1716    CmdArgs.push_back("-lgcc");
1717    if (Args.hasArg(options::OPT_static)) {
1718      CmdArgs.push_back("-lgcc_eh");
1719    } else {
1720      CmdArgs.push_back("--as-needed");
1721      CmdArgs.push_back("-lgcc_s");
1722      CmdArgs.push_back("--no-as-needed");
1723    }
1724
1725    if (Args.hasArg(options::OPT_pthread))
1726      CmdArgs.push_back("-lpthread");
1727    CmdArgs.push_back("-lc");
1728
1729    CmdArgs.push_back("-lgcc");
1730    if (Args.hasArg(options::OPT_static)) {
1731      CmdArgs.push_back("-lgcc_eh");
1732    } else {
1733      CmdArgs.push_back("--as-needed");
1734      CmdArgs.push_back("-lgcc_s");
1735      CmdArgs.push_back("--no-as-needed");
1736    }
1737  }
1738
1739  if (!Args.hasArg(options::OPT_nostdlib) &&
1740      !Args.hasArg(options::OPT_nostartfiles)) {
1741    if (!Args.hasArg(options::OPT_shared))
1742      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o").c_str()));
1743    else
1744      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o").c_str()));
1745    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o").c_str()));
1746  }
1747
1748  const char *Exec =
1749    Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
1750  Dest.addCommand(new Command(Exec, CmdArgs));
1751}
1752