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