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