Tools.cpp revision 25147702ca1c50f7cb18ff466e8d79d436fcf44a
12f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com//===--- Tools.cpp - Tools Implementations --------------------------------===//
22f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com//
32f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com//                     The LLVM Compiler Infrastructure
42f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com//
52f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com// This file is distributed under the University of Illinois Open Source
62f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com// License. See LICENSE.TXT for details.
72f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com//
8907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org//===----------------------------------------------------------------------===//
968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
102eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "Tools.h"
11d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com
1292b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com#include "clang/Driver/Action.h"
132f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com#include "clang/Driver/Arg.h"
14907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/ArgList.h"
15907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/Driver.h"
16907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/DriverDiagnostic.h"
17907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/Compilation.h"
18907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/Job.h"
19907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/HostInfo.h"
20907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/Option.h"
21907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/Options.h"
22907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/ToolChain.h"
23907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "clang/Driver/Util.h"
24907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
25907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/ADT/SmallString.h"
26907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/ADT/StringSwitch.h"
27907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/ADT/Twine.h"
28907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/Support/Format.h"
29907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/Support/raw_ostream.h"
30907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/System/Host.h"
31907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "llvm/System/Process.h"
32907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
33907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "InputInfo.h"
34907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org#include "ToolChains.h"
35907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
36907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgusing namespace clang::driver;
37907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgusing namespace clang::driver::tools;
38907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
39907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/// CheckPreprocessingOptions - Perform some validation of preprocessing
40907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/// arguments that is shared with gcc.
41907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgstatic void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
42907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
43907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (!Args.hasArg(options::OPT_E))
44907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
45907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        << A->getAsString(Args) << "-E";
46907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
47907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
48d7b1af68deefe6e4ca5fa635625154c1e4f2eae6reed@google.com/// CheckCodeGenerationOptions - Perform some validation of code generation
49907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org/// arguments that is shared with gcc.
50907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgstatic void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
51907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  // In gcc, only ARM checks this, but it seems reasonable to check universally.
52907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  if (Args.hasArg(options::OPT_static))
53907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
54907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                       options::OPT_mdynamic_no_pic))
55907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
56907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        << A->getAsString(Args) << "-static";
57907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
58907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
59907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org// Quote target names for inclusion in GNU Make dependency files.
60907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org// Only the characters '$', '#', ' ', '\t' are quoted.
61907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgstatic void QuoteTarget(llvm::StringRef Target,
62907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                        llvm::SmallVectorImpl<char> &Res) {
63907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  for (unsigned i = 0, e = Target.size(); i != e; ++i) {
64907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    switch (Target[i]) {
65907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    case ' ':
66907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    case '\t':
67907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      // Escape the preceding backslashes
68907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
69907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        Res.push_back('\\');
70907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
71907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      // Escape the space/tab
72907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      Res.push_back('\\');
73907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      break;
74907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    case '$':
75907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      Res.push_back('$');
76907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      break;
77907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    case '#':
78907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      Res.push_back('\\');
79907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      break;
80907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    default:
81907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      break;
82907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
83907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
84907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    Res.push_back(Target[i]);
85907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  }
86907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
87907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
88907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgstatic void AddLinkerInputs(const ToolChain &TC,
89907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                            const InputInfoList &Inputs, const ArgList &Args,
90907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                            ArgStringList &CmdArgs) {
91907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  const Driver &D = TC.getDriver();
92907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
93907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  for (InputInfoList::const_iterator
94907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
95907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    const InputInfo &II = *it;
96907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
97907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (!TC.HasNativeLLVMSupport()) {
98907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      // Don't try to pass LLVM inputs unless we have native support.
99907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      if (II.getType() == types::TY_LLVM_IR ||
100907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org          II.getType() == types::TY_LTO_IR ||
101907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org          II.getType() == types::TY_LLVM_BC ||
102907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org          II.getType() == types::TY_LTO_BC)
103907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        D.Diag(clang::diag::err_drv_no_linker_llvm_support)
104907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org          << TC.getTripleString();
105907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
106907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
107907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    // Add filenames immediately.
108907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (II.isFilename()) {
109907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      CmdArgs.push_back(II.getFilename());
110907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      continue;
111907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
112907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
113907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    // Otherwise, this is a linker input argument.
114907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    const Arg &A = II.getInputArg();
115907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
116907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    // Handle reserved library options.
117907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
118907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
119907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) {
120907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      TC.AddCCKextLibArgs(Args, CmdArgs);
121907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    } else
122907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      A.renderAsInput(Args, CmdArgs);
123907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  }
124907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org}
125907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
126907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.orgvoid Clang::AddPreprocessingOptions(const Driver &D,
127907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                    const ArgList &Args,
128907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                    ArgStringList &CmdArgs,
129907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                    const InputInfo &Output,
130907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                    const InputInfoList &Inputs) const {
131907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  Arg *A;
132907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
133907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  CheckPreprocessingOptions(D, Args);
134907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
135907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  Args.AddLastArg(CmdArgs, options::OPT_C);
136907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  Args.AddLastArg(CmdArgs, options::OPT_CC);
137907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
138907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  // Handle dependency file generation.
139907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  if ((A = Args.getLastArg(options::OPT_M)) ||
140907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      (A = Args.getLastArg(options::OPT_MM)) ||
141907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      (A = Args.getLastArg(options::OPT_MD)) ||
142907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      (A = Args.getLastArg(options::OPT_MMD))) {
14322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com    // Determine the output location.
1442f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    const char *DepFile;
145c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (Output.getType() == types::TY_Dependencies) {
1462f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      DepFile = Output.getFilename();
14722a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com    } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
148c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com      DepFile = MF->getValue(Args);
14922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com    } else if (A->getOption().matches(options::OPT_M) ||
15022a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com               A->getOption().matches(options::OPT_MM)) {
15122a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com      DepFile = "-";
15277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    } else {
15322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com      DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
1542f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    }
155c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    CmdArgs.push_back("-dependency-file");
1562f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    CmdArgs.push_back(DepFile);
157c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
1582f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    // Add a default target if one wasn't specified.
1592f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
160907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      const char *DepTarget;
16122a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com
1622f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      // If user provided -o, that is the dependency target, except
1632f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      // when we are only generating a dependency file.
164396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
16577af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
16677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        DepTarget = OutputOpt->getValue(Args);
1672f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      } else {
1682f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        // Otherwise derive from the base input.
16922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com        //
170c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        // FIXME: This should use the computed output file location.
17192b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com        llvm::sys::Path P(Inputs[0].getBaseInput());
17222a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com
17322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com        P.eraseSuffix();
17477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        P.appendSuffix("o");
17522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com        DepTarget = Args.MakeArgString(P.getLast());
176907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      }
177907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
1787b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com      CmdArgs.push_back("-MT");
17977af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com      llvm::SmallString<128> Quoted;
180907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      QuoteTarget(DepTarget, Quoted);
1812f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      CmdArgs.push_back(Args.MakeArgString(Quoted));
1822f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    }
183c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
184c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    if (A->getOption().matches(options::OPT_M) ||
185907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        A->getOption().matches(options::OPT_MD))
186907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      CmdArgs.push_back("-sys-header-deps");
187907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  }
1881aa90cf11e136a722bce71dd77f4bb03cc2b56f8skia.committer@gmail.com
18992b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com  Args.AddLastArg(CmdArgs, options::OPT_MP);
190c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
191c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com  // Convert all -MQ <target> args to -MT <quoted target>
192907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  for (arg_iterator it = Args.filtered_begin(options::OPT_MT,
193907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org                                             options::OPT_MQ),
1942f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com         ie = Args.filtered_end(); it != ie; ++it) {
1952f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    const Arg *A = *it;
1962f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    A->claim();
1972f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
1982f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com    if (A->getOption().matches(options::OPT_MQ)) {
1990ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com      CmdArgs.push_back("-MT");
2000ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com      llvm::SmallString<128> Quoted;
201fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org      QuoteTarget(A->getValue(Args), Quoted);
202907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      CmdArgs.push_back(Args.MakeArgString(Quoted));
203b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com
20477af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com    // -MT flag - no change
2057b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com    } else {
206907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      A->render(Args, CmdArgs);
207907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org    }
208b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com  }
2097b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com
2100ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com  // Add -i* options, and automatically translate to
2116340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com  // -include-pch/-include-pth for transparent PCH support. It's
2126340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com  // wonky, but we include looking for .gch so we can support seamless
213907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  // replacement into a build system already set up to be generating
214907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  // .gch files.
215b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com  for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
21677af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com         ie = Args.filtered_end(); it != ie; ++it) {
217a1ebbe447d5eab098111eb83580e55f2f5f6facabsalomon@google.com    const Arg *A = it;
2180ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com
2197b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com    if (A->getOption().matches(options::OPT_include)) {
2202f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      // Use PCH if the user requested it.
2212f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      bool UsePCH = D.CCCUsePCH;
2221ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
2237b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com      bool FoundPTH = false;
224fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org      bool FoundPCH = false;
225907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org      llvm::sys::Path P(A->getValue(Args));
226b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com      if (UsePCH) {
22777af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        P.appendSuffix("pch");
22877af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com        if (P.exists())
229907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org          FoundPCH = true;
2301ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com        else
2311ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com          P.eraseSuffix();
2322f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      }
2332f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com
2342f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      if (!FoundPCH) {
2352f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        P.appendSuffix("pth");
236396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com        if (P.exists())
237396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com          FoundPTH = true;
2382f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com        else
2392f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com          P.eraseSuffix();
2408a252f79629b189a03de22cd8ff0312c5bccedd1bsalomon@google.com      }
2416340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com
24277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com      if (!FoundPCH && !FoundPTH) {
243c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        P.appendSuffix("gch");
24468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        if (P.exists()) {
24568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com          FoundPCH = UsePCH;
24668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com          FoundPTH = !UsePCH;
247907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org        }
24868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        else
24968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com          P.eraseSuffix();
25068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com      }
25168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com
2522f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com      if (FoundPCH || FoundPTH) {
2530a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com        A->claim();
2540a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com        if (UsePCH)
2550a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com          CmdArgs.push_back("-include-pch");
256f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com        else
2570a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com          CmdArgs.push_back("-include-pth");
258e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org        CmdArgs.push_back(Args.MakeArgString(P.str()));
259e0e385c1d4171e065348ba17c546b3463a0bd651sugoi@google.com        continue;
260c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com      }
2610ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com    }
2626f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com
2636f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com    // Not translated, render as usual.
264fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    A->claim();
2650a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com    A->render(Args, CmdArgs);
2660a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com  }
2670a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com
2680a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
269907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
270907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
2717b7cdd147f5528865238e5ed98c79e6d319fde9bbsalomon@google.com  // Add C++ include arguments, if needed.
272c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com  types::ID InputType = Inputs[0].getType();
27377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com  if (types::isCXX(InputType))
274c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
275c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com
276c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com  // Add -Wp, and -Xassembler if using the preprocessor.
277907fbd53c5e5dd4cbde7b72f9242b51febd7ef95commit-bot@chromium.org
278b86add1ad37776818e1f730359ec587c9fdbff5fhumper@google.com  // FIXME: There is a very unfortunate problem here, some troubled
279c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
2800a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com  // really support that we would have to parse and then translate
281  // those options. :(
282  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
283                       options::OPT_Xpreprocessor);
284
285  // -I- is a deprecated GCC feature, reject it.
286  if (Arg *A = Args.getLastArg(options::OPT_I_))
287    D.Diag(clang::diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
288}
289
290/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targetting.
291//
292// FIXME: tblgen this.
293static const char *getARMTargetCPU(const ArgList &Args,
294                                   const llvm::Triple &Triple) {
295  // FIXME: Warn on inconsistent use of -mcpu and -march.
296
297  // If we have -mcpu=, use that.
298  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
299    return A->getValue(Args);
300
301  llvm::StringRef MArch;
302  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
303    // Otherwise, if we have -march= choose the base CPU for that arch.
304    MArch = A->getValue(Args);
305  } else {
306    // Otherwise, use the Arch from the triple.
307    MArch = Triple.getArchName();
308  }
309
310  if (MArch == "armv2" || MArch == "armv2a")
311    return "arm2";
312  if (MArch == "armv3")
313    return "arm6";
314  if (MArch == "armv3m")
315    return "arm7m";
316  if (MArch == "armv4" || MArch == "armv4t")
317    return "arm7tdmi";
318  if (MArch == "armv5" || MArch == "armv5t")
319    return "arm10tdmi";
320  if (MArch == "armv5e" || MArch == "armv5te")
321    return "arm1026ejs";
322  if (MArch == "armv5tej")
323    return "arm926ej-s";
324  if (MArch == "armv6" || MArch == "armv6k")
325    return "arm1136jf-s";
326  if (MArch == "armv6j")
327    return "arm1136j-s";
328  if (MArch == "armv6z" || MArch == "armv6zk")
329    return "arm1176jzf-s";
330  if (MArch == "armv6t2")
331    return "arm1156t2-s";
332  if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
333    return "cortex-a8";
334  if (MArch == "armv7r" || MArch == "armv7-r")
335    return "cortex-r4";
336  if (MArch == "armv7m" || MArch == "armv7-m")
337    return "cortex-m3";
338  if (MArch == "ep9312")
339    return "ep9312";
340  if (MArch == "iwmmxt")
341    return "iwmmxt";
342  if (MArch == "xscale")
343    return "xscale";
344
345  // If all else failed, return the most base CPU LLVM supports.
346  return "arm7tdmi";
347}
348
349/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
350/// CPU.
351//
352// FIXME: This is redundant with -mcpu, why does LLVM use this.
353// FIXME: tblgen this, or kill it!
354static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {
355  if (CPU == "arm7tdmi" || CPU == "arm7tdmi-s" || CPU == "arm710t" ||
356      CPU == "arm720t" || CPU == "arm9" || CPU == "arm9tdmi" ||
357      CPU == "arm920" || CPU == "arm920t" || CPU == "arm922t" ||
358      CPU == "arm940t" || CPU == "ep9312")
359    return "v4t";
360
361  if (CPU == "arm10tdmi" || CPU == "arm1020t")
362    return "v5";
363
364  if (CPU == "arm9e" || CPU == "arm926ej-s" || CPU == "arm946e-s" ||
365      CPU == "arm966e-s" || CPU == "arm968e-s" || CPU == "arm10e" ||
366      CPU == "arm1020e" || CPU == "arm1022e" || CPU == "xscale" ||
367      CPU == "iwmmxt")
368    return "v5e";
369
370  if (CPU == "arm1136j-s" || CPU == "arm1136jf-s" || CPU == "arm1176jz-s" ||
371      CPU == "arm1176jzf-s" || CPU == "mpcorenovfp" || CPU == "mpcore")
372    return "v6";
373
374  if (CPU == "arm1156t2-s" || CPU == "arm1156t2f-s")
375    return "v6t2";
376
377  if (CPU == "cortex-a8" || CPU == "cortex-a9")
378    return "v7";
379
380  return "";
381}
382
383// FIXME: Move to target hook.
384static bool isSignedCharDefault(const llvm::Triple &Triple) {
385  switch (Triple.getArch()) {
386  default:
387    return true;
388
389  case llvm::Triple::ppc:
390  case llvm::Triple::ppc64:
391    if (Triple.getOS() == llvm::Triple::Darwin)
392      return true;
393    return false;
394
395  case llvm::Triple::systemz:
396    return false;
397  }
398}
399
400void Clang::AddARMTargetArgs(const ArgList &Args,
401                             ArgStringList &CmdArgs) const {
402  const Driver &D = getToolChain().getDriver();
403  llvm::Triple Triple = getToolChain().getTriple();
404
405  // Select the ABI to use.
406  //
407  // FIXME: Support -meabi.
408  const char *ABIName = 0;
409  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
410    ABIName = A->getValue(Args);
411  } else {
412    // Select the default based on the platform.
413    llvm::StringRef env = Triple.getEnvironmentName();
414    if (env == "gnueabi")
415      ABIName = "aapcs-linux";
416    else if (env == "eabi")
417      ABIName = "aapcs";
418    else
419      ABIName = "apcs-gnu";
420  }
421  CmdArgs.push_back("-target-abi");
422  CmdArgs.push_back(ABIName);
423
424  // Set the CPU based on -march= and -mcpu=.
425  CmdArgs.push_back("-target-cpu");
426  CmdArgs.push_back(getARMTargetCPU(Args, Triple));
427
428  // Select the float ABI as determined by -msoft-float, -mhard-float, and
429  // -mfloat-abi=.
430  llvm::StringRef FloatABI;
431  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
432                               options::OPT_mhard_float,
433                               options::OPT_mfloat_abi_EQ)) {
434    if (A->getOption().matches(options::OPT_msoft_float))
435      FloatABI = "soft";
436    else if (A->getOption().matches(options::OPT_mhard_float))
437      FloatABI = "hard";
438    else {
439      FloatABI = A->getValue(Args);
440      if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
441        D.Diag(clang::diag::err_drv_invalid_mfloat_abi)
442          << A->getAsString(Args);
443        FloatABI = "soft";
444      }
445    }
446  }
447
448  // If unspecified, choose the default based on the platform.
449  if (FloatABI.empty()) {
450    const llvm::Triple &Triple = getToolChain().getTriple();
451    switch (Triple.getOS()) {
452    case llvm::Triple::Darwin: {
453      // Darwin defaults to "softfp" for v6 and v7.
454      //
455      // FIXME: Factor out an ARM class so we can cache the arch somewhere.
456      llvm::StringRef ArchName =
457        getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
458      if (ArchName.startswith("v6") || ArchName.startswith("v7"))
459        FloatABI = "softfp";
460      else
461        FloatABI = "soft";
462      break;
463    }
464
465    case llvm::Triple::Linux: {
466      llvm::StringRef Env = getToolChain().getTriple().getEnvironmentName();
467      if (Env == "gnueabi") {
468        FloatABI = "softfp";
469        break;
470      }
471    }
472    // fall through
473
474    default:
475      // Assume "soft", but warn the user we are guessing.
476      FloatABI = "soft";
477      D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
478      break;
479    }
480  }
481
482  if (FloatABI == "soft") {
483    // Floating point operations and argument passing are soft.
484    //
485    // FIXME: This changes CPP defines, we need -target-soft-float.
486    CmdArgs.push_back("-msoft-float");
487    CmdArgs.push_back("-mfloat-abi");
488    CmdArgs.push_back("soft");
489  } else if (FloatABI == "softfp") {
490    // Floating point operations are hard, but argument passing is soft.
491    CmdArgs.push_back("-mfloat-abi");
492    CmdArgs.push_back("soft");
493  } else {
494    // Floating point operations and argument passing are hard.
495    assert(FloatABI == "hard" && "Invalid float abi!");
496    CmdArgs.push_back("-mfloat-abi");
497    CmdArgs.push_back("hard");
498  }
499
500  // Set appropriate target features for floating point mode.
501  //
502  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
503  // yet (it uses the -mfloat-abi and -msoft-float options above), and it is
504  // stripped out by the ARM target.
505
506  // Use software floating point operations?
507  if (FloatABI == "soft") {
508    CmdArgs.push_back("-target-feature");
509    CmdArgs.push_back("+soft-float");
510  }
511
512  // Use software floating point argument passing?
513  if (FloatABI != "hard") {
514    CmdArgs.push_back("-target-feature");
515    CmdArgs.push_back("+soft-float-abi");
516  }
517
518  // Honor -mfpu=.
519  //
520  // FIXME: Centralize feature selection, defaulting shouldn't be also in the
521  // frontend target.
522  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
523    llvm::StringRef FPU = A->getValue(Args);
524
525    // Set the target features based on the FPU.
526    if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
527      // Disable any default FPU support.
528      CmdArgs.push_back("-target-feature");
529      CmdArgs.push_back("-vfp2");
530      CmdArgs.push_back("-target-feature");
531      CmdArgs.push_back("-vfp3");
532      CmdArgs.push_back("-target-feature");
533      CmdArgs.push_back("-neon");
534    } else if (FPU == "vfp") {
535      CmdArgs.push_back("-target-feature");
536      CmdArgs.push_back("+vfp2");
537    } else if (FPU == "vfp3") {
538      CmdArgs.push_back("-target-feature");
539      CmdArgs.push_back("+vfp3");
540    } else if (FPU == "neon") {
541      CmdArgs.push_back("-target-feature");
542      CmdArgs.push_back("+neon");
543    } else
544      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
545  }
546}
547
548void Clang::AddMIPSTargetArgs(const ArgList &Args,
549                             ArgStringList &CmdArgs) const {
550  const Driver &D = getToolChain().getDriver();
551
552  // Select the ABI to use.
553  const char *ABIName = 0;
554  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
555    ABIName = A->getValue(Args);
556  } else {
557    ABIName = "o32";
558  }
559
560  CmdArgs.push_back("-target-abi");
561  CmdArgs.push_back(ABIName);
562
563  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
564    llvm::StringRef MArch = A->getValue(Args);
565    CmdArgs.push_back("-target-cpu");
566
567    if ((MArch == "r2000") || (MArch == "r3000"))
568      CmdArgs.push_back("mips1");
569    else if (MArch == "r6000")
570      CmdArgs.push_back("mips2");
571    else
572      CmdArgs.push_back(MArch.str().c_str());
573  }
574
575  // Select the float ABI as determined by -msoft-float, -mhard-float, and
576  llvm::StringRef FloatABI;
577  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
578                               options::OPT_mhard_float)) {
579    if (A->getOption().matches(options::OPT_msoft_float))
580      FloatABI = "soft";
581    else if (A->getOption().matches(options::OPT_mhard_float))
582      FloatABI = "hard";
583  }
584
585  // If unspecified, choose the default based on the platform.
586  if (FloatABI.empty()) {
587    // Assume "soft", but warn the user we are guessing.
588    FloatABI = "soft";
589    D.Diag(clang::diag::warn_drv_assuming_mfloat_abi_is) << "soft";
590  }
591
592  if (FloatABI == "soft") {
593    // Floating point operations and argument passing are soft.
594    //
595    // FIXME: This changes CPP defines, we need -target-soft-float.
596    CmdArgs.push_back("-msoft-float");
597  } else {
598    assert(FloatABI == "hard" && "Invalid float abi!");
599    CmdArgs.push_back("-mhard-float");
600  }
601}
602
603void Clang::AddX86TargetArgs(const ArgList &Args,
604                             ArgStringList &CmdArgs) const {
605  if (!Args.hasFlag(options::OPT_mred_zone,
606                    options::OPT_mno_red_zone,
607                    true) ||
608      Args.hasArg(options::OPT_mkernel) ||
609      Args.hasArg(options::OPT_fapple_kext))
610    CmdArgs.push_back("-disable-red-zone");
611
612  if (Args.hasFlag(options::OPT_msoft_float,
613                   options::OPT_mno_soft_float,
614                   false))
615    CmdArgs.push_back("-no-implicit-float");
616
617  const char *CPUName = 0;
618  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
619    if (llvm::StringRef(A->getValue(Args)) == "native") {
620      // FIXME: Reject attempts to use -march=native unless the target matches
621      // the host.
622      //
623      // FIXME: We should also incorporate the detected target features for use
624      // with -native.
625      std::string CPU = llvm::sys::getHostCPUName();
626      if (!CPU.empty())
627        CPUName = Args.MakeArgString(CPU);
628    } else
629      CPUName = A->getValue(Args);
630  }
631
632  // Select the default CPU if none was given (or detection failed).
633  if (!CPUName) {
634    // FIXME: Need target hooks.
635    if (getToolChain().getOS().startswith("darwin")) {
636      if (getToolChain().getArchName() == "x86_64")
637        CPUName = "core2";
638      else if (getToolChain().getArchName() == "i386")
639        CPUName = "yonah";
640    } else if (getToolChain().getOS().startswith("haiku"))  {
641      if (getToolChain().getArchName() == "x86_64")
642        CPUName = "x86-64";
643      else if (getToolChain().getArchName() == "i386")
644        CPUName = "i586";
645    } else if (getToolChain().getOS().startswith("openbsd"))  {
646      if (getToolChain().getArchName() == "x86_64")
647        CPUName = "x86-64";
648      else if (getToolChain().getArchName() == "i386")
649        CPUName = "i486";
650    } else {
651      if (getToolChain().getArchName() == "x86_64")
652        CPUName = "x86-64";
653      else if (getToolChain().getArchName() == "i386")
654        CPUName = "pentium4";
655    }
656  }
657
658  if (CPUName) {
659    CmdArgs.push_back("-target-cpu");
660    CmdArgs.push_back(CPUName);
661  }
662
663  for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
664         ie = Args.filtered_end(); it != ie; ++it) {
665    llvm::StringRef Name = (*it)->getOption().getName();
666    (*it)->claim();
667
668    // Skip over "-m".
669    assert(Name.startswith("-m") && "Invalid feature name.");
670    Name = Name.substr(2);
671
672    bool IsNegative = Name.startswith("no-");
673    if (IsNegative)
674      Name = Name.substr(3);
675
676    CmdArgs.push_back("-target-feature");
677    CmdArgs.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
678  }
679}
680
681static bool needsExceptions(const ArgList &Args,  types::ID InputType,
682                            const llvm::Triple &Triple) {
683  // Handle -fno-exceptions.
684  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
685                               options::OPT_fno_exceptions)) {
686    if (A->getOption().matches(options::OPT_fexceptions))
687      return true;
688    else
689      return false;
690  }
691
692  // Otherwise, C++ inputs use exceptions.
693  if (types::isCXX(InputType))
694    return true;
695
696  // As do Objective-C non-fragile ABI inputs and all Objective-C inputs on
697  // x86_64 after SnowLeopard.
698  if (types::isObjC(InputType)) {
699    if (Args.hasArg(options::OPT_fobjc_nonfragile_abi))
700      return true;
701    if (Triple.getOS() != llvm::Triple::Darwin)
702      return false;
703    return (Triple.getDarwinMajorNumber() >= 9 &&
704            Triple.getArch() == llvm::Triple::x86_64);
705  }
706
707  return false;
708}
709
710void Clang::ConstructJob(Compilation &C, const JobAction &JA,
711                         const InputInfo &Output,
712                         const InputInfoList &Inputs,
713                         const ArgList &Args,
714                         const char *LinkingOutput) const {
715  bool KernelOrKext = Args.hasArg(options::OPT_mkernel,
716                                  options::OPT_fapple_kext);
717  const Driver &D = getToolChain().getDriver();
718  ArgStringList CmdArgs;
719
720  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
721
722  // Invoke ourselves in -cc1 mode.
723  //
724  // FIXME: Implement custom jobs for internal actions.
725  CmdArgs.push_back("-cc1");
726
727  // Add the "effective" target triple.
728  CmdArgs.push_back("-triple");
729  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
730  CmdArgs.push_back(Args.MakeArgString(TripleStr));
731
732  // Select the appropriate action.
733  bool IsRewriter = false;
734  if (isa<AnalyzeJobAction>(JA)) {
735    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
736    CmdArgs.push_back("-analyze");
737  } else if (isa<PreprocessJobAction>(JA)) {
738    if (Output.getType() == types::TY_Dependencies)
739      CmdArgs.push_back("-Eonly");
740    else
741      CmdArgs.push_back("-E");
742  } else if (isa<AssembleJobAction>(JA)) {
743    CmdArgs.push_back("-emit-obj");
744
745    // At -O0, we use -mrelax-all by default.
746    bool IsOpt = false;
747    if (Arg *A = Args.getLastArg(options::OPT_O_Group))
748      IsOpt = !A->getOption().matches(options::OPT_O0);
749    if (Args.hasFlag(options::OPT_mrelax_all,
750                      options::OPT_mno_relax_all,
751                      !IsOpt))
752      CmdArgs.push_back("-mrelax-all");
753
754    // When using an integrated assembler, we send -Wa, and -Xassembler options
755    // to -cc1.
756    Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
757                         options::OPT_Xassembler);
758  } else if (isa<PrecompileJobAction>(JA)) {
759    // Use PCH if the user requested it.
760    bool UsePCH = D.CCCUsePCH;
761
762    if (UsePCH)
763      CmdArgs.push_back("-emit-pch");
764    else
765      CmdArgs.push_back("-emit-pth");
766  } else {
767    assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
768
769    if (JA.getType() == types::TY_Nothing) {
770      CmdArgs.push_back("-fsyntax-only");
771    } else if (JA.getType() == types::TY_LLVM_IR ||
772               JA.getType() == types::TY_LTO_IR) {
773      CmdArgs.push_back("-emit-llvm");
774    } else if (JA.getType() == types::TY_LLVM_BC ||
775               JA.getType() == types::TY_LTO_BC) {
776      CmdArgs.push_back("-emit-llvm-bc");
777    } else if (JA.getType() == types::TY_PP_Asm) {
778      CmdArgs.push_back("-S");
779    } else if (JA.getType() == types::TY_AST) {
780      CmdArgs.push_back("-emit-pch");
781    } else if (JA.getType() == types::TY_RewrittenObjC) {
782      CmdArgs.push_back("-rewrite-objc");
783      IsRewriter = true;
784    } else {
785      assert(JA.getType() == types::TY_PP_Asm &&
786             "Unexpected output type!");
787    }
788  }
789
790  // The make clang go fast button.
791  CmdArgs.push_back("-disable-free");
792
793  // Disable the verification pass in -asserts builds.
794#ifdef NDEBUG
795  CmdArgs.push_back("-disable-llvm-verifier");
796#endif
797
798  // Set the main file name, so that debug info works even with
799  // -save-temps.
800  CmdArgs.push_back("-main-file-name");
801  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
802
803  // Some flags which affect the language (via preprocessor
804  // defines). See darwin::CC1::AddCPPArgs.
805  if (Args.hasArg(options::OPT_static))
806    CmdArgs.push_back("-static-define");
807
808  if (isa<AnalyzeJobAction>(JA)) {
809    // Enable region store model by default.
810    CmdArgs.push_back("-analyzer-store=region");
811
812    // Treat blocks as analysis entry points.
813    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
814
815    // Add default argument set.
816    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
817      CmdArgs.push_back("-analyzer-check-dead-stores");
818      // Do not enable the security-syntatic check since it
819      // it needs to be refined (known issues).
820      // CmdArgs.push_back("-analyzer-check-security-syntactic");
821      CmdArgs.push_back("-analyzer-check-objc-mem");
822      CmdArgs.push_back("-analyzer-eagerly-assume");
823      CmdArgs.push_back("-analyzer-check-objc-methodsigs");
824      // Do not enable the missing -dealloc check.
825      // '-analyzer-check-objc-missing-dealloc',
826      CmdArgs.push_back("-analyzer-check-objc-unused-ivars");
827      CmdArgs.push_back("-analyzer-check-idempotent-operations");
828    }
829
830    // Set the output format. The default is plist, for (lame) historical
831    // reasons.
832    CmdArgs.push_back("-analyzer-output");
833    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
834      CmdArgs.push_back(A->getValue(Args));
835    else
836      CmdArgs.push_back("plist");
837
838    // Disable the presentation of standard compiler warnings when
839    // using --analyze.  We only want to show static analyzer diagnostics
840    // or frontend errors.
841    CmdArgs.push_back("-w");
842
843    // Add -Xanalyzer arguments when running as analyzer.
844    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
845  }
846
847  CheckCodeGenerationOptions(D, Args);
848
849  // Perform argument translation for LLVM backend. This
850  // takes some care in reconciling with llvm-gcc. The
851  // issue is that llvm-gcc translates these options based on
852  // the values in cc1, whereas we are processing based on
853  // the driver arguments.
854
855  // This comes from the default translation the driver + cc1
856  // would do to enable flag_pic.
857  //
858  // FIXME: Centralize this code.
859  bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
860                     Args.hasArg(options::OPT_fpic) ||
861                     Args.hasArg(options::OPT_fPIE) ||
862                     Args.hasArg(options::OPT_fpie));
863  bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
864                      Args.hasArg(options::OPT_static));
865  const char *Model = getToolChain().GetForcedPicModel();
866  if (!Model) {
867    if (Args.hasArg(options::OPT_mdynamic_no_pic))
868      Model = "dynamic-no-pic";
869    else if (PICDisabled)
870      Model = "static";
871    else if (PICEnabled)
872      Model = "pic";
873    else
874      Model = getToolChain().GetDefaultRelocationModel();
875  }
876  if (llvm::StringRef(Model) != "pic") {
877    CmdArgs.push_back("-mrelocation-model");
878    CmdArgs.push_back(Model);
879  }
880
881  // Infer the __PIC__ value.
882  //
883  // FIXME:  This isn't quite right on Darwin, which always sets
884  // __PIC__=2.
885  if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
886    CmdArgs.push_back("-pic-level");
887    CmdArgs.push_back(Args.hasArg(options::OPT_fPIC) ? "2" : "1");
888  }
889  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
890                    options::OPT_fno_merge_all_constants))
891    CmdArgs.push_back("-no-merge-all-constants");
892
893  // LLVM Code Generator Options.
894
895  // FIXME: Set --enable-unsafe-fp-math.
896  if (Args.hasFlag(options::OPT_fno_omit_frame_pointer,
897                   options::OPT_fomit_frame_pointer))
898    CmdArgs.push_back("-mdisable-fp-elim");
899  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
900                    options::OPT_fno_zero_initialized_in_bss))
901    CmdArgs.push_back("-mno-zero-initialized-in-bss");
902
903  // Decide whether to use verbose asm. Verbose assembly is the default on
904  // toolchains which have the integrated assembler on by default.
905  bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
906  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
907                   IsVerboseAsmDefault) ||
908      Args.hasArg(options::OPT_dA))
909    CmdArgs.push_back("-masm-verbose");
910
911  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
912    CmdArgs.push_back("-mdebug-pass");
913    CmdArgs.push_back("Structure");
914  }
915  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
916    CmdArgs.push_back("-mdebug-pass");
917    CmdArgs.push_back("Arguments");
918  }
919
920  // Enable -mconstructor-aliases except on darwin, where we have to
921  // work around a linker bug;  see <rdar://problem/7651567>.
922  if (getToolChain().getTriple().getOS() != llvm::Triple::Darwin)
923    CmdArgs.push_back("-mconstructor-aliases");
924
925  // This is a coarse approximation of what llvm-gcc actually does, both
926  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
927  // complicated ways.
928  bool AsynchronousUnwindTables =
929    Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
930                 options::OPT_fno_asynchronous_unwind_tables,
931                 getToolChain().IsUnwindTablesDefault() &&
932                 !KernelOrKext);
933  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
934                   AsynchronousUnwindTables))
935    CmdArgs.push_back("-munwind-tables");
936
937  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
938    CmdArgs.push_back("-mlimit-float-precision");
939    CmdArgs.push_back(A->getValue(Args));
940  }
941
942  // FIXME: Handle -mtune=.
943  (void) Args.hasArg(options::OPT_mtune_EQ);
944
945  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
946    CmdArgs.push_back("-mcode-model");
947    CmdArgs.push_back(A->getValue(Args));
948  }
949
950  // Add target specific cpu and features flags.
951  switch(getToolChain().getTriple().getArch()) {
952  default:
953    break;
954
955  case llvm::Triple::arm:
956  case llvm::Triple::thumb:
957    AddARMTargetArgs(Args, CmdArgs);
958    break;
959
960  case llvm::Triple::mips:
961  case llvm::Triple::mipsel:
962    AddMIPSTargetArgs(Args, CmdArgs);
963    break;
964
965  case llvm::Triple::x86:
966  case llvm::Triple::x86_64:
967    AddX86TargetArgs(Args, CmdArgs);
968    break;
969  }
970
971  // Pass the linker version in use.
972  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
973    CmdArgs.push_back("-target-linker-version");
974    CmdArgs.push_back(A->getValue(Args));
975  }
976
977  // -mno-omit-leaf-frame-pointer is default.
978  if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
979                   options::OPT_mno_omit_leaf_frame_pointer, false))
980    CmdArgs.push_back("-momit-leaf-frame-pointer");
981
982  // -fno-math-errno is default.
983  if (Args.hasFlag(options::OPT_fmath_errno,
984                   options::OPT_fno_math_errno,
985                   false))
986    CmdArgs.push_back("-fmath-errno");
987
988  // Explicitly error on some things we know we don't support and can't just
989  // ignore.
990  types::ID InputType = Inputs[0].getType();
991  Arg *Unsupported;
992  if ((Unsupported = Args.getLastArg(options::OPT_MG)) ||
993      (Unsupported = Args.getLastArg(options::OPT_iframework)) ||
994      (Unsupported = Args.getLastArg(options::OPT_fshort_enums)))
995    D.Diag(clang::diag::err_drv_clang_unsupported)
996      << Unsupported->getOption().getName();
997
998  if (types::isCXX(InputType) &&
999      getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
1000      getToolChain().getTriple().getArch() == llvm::Triple::x86) {
1001    if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)))
1002      D.Diag(clang::diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
1003        << Unsupported->getOption().getName();
1004  }
1005
1006  Args.AddAllArgs(CmdArgs, options::OPT_v);
1007  Args.AddLastArg(CmdArgs, options::OPT_H);
1008  Args.AddLastArg(CmdArgs, options::OPT_P);
1009  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
1010
1011  // Special case debug options to only pass -g to clang. This is
1012  // wrong.
1013  Args.ClaimAllArgs(options::OPT_g_Group);
1014  if (Arg *A = Args.getLastArg(options::OPT_g_Group))
1015    if (!A->getOption().matches(options::OPT_g0))
1016      CmdArgs.push_back("-g");
1017
1018  Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
1019  Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
1020
1021  Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
1022
1023  Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
1024  Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
1025  Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
1026
1027  // Pass the path to compiler resource files.
1028  CmdArgs.push_back("-resource-dir");
1029  CmdArgs.push_back(D.ResourceDir.c_str());
1030
1031  // Add preprocessing options like -I, -D, etc. if we are using the
1032  // preprocessor.
1033  //
1034  // FIXME: Support -fpreprocessed
1035  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
1036    AddPreprocessingOptions(D, Args, CmdArgs, Output, Inputs);
1037
1038  // Manually translate -O to -O2 and -O4 to -O3; let clang reject
1039  // others.
1040  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
1041    if (A->getOption().matches(options::OPT_O4))
1042      CmdArgs.push_back("-O3");
1043    else if (A->getOption().matches(options::OPT_O) &&
1044             A->getValue(Args)[0] == '\0')
1045      CmdArgs.push_back("-O2");
1046    else
1047      A->render(Args, CmdArgs);
1048  }
1049
1050  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
1051  Args.AddLastArg(CmdArgs, options::OPT_pedantic);
1052  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
1053  Args.AddLastArg(CmdArgs, options::OPT_w);
1054
1055  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
1056  // (-ansi is equivalent to -std=c89).
1057  //
1058  // If a std is supplied, only add -trigraphs if it follows the
1059  // option.
1060  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1061    if (Std->getOption().matches(options::OPT_ansi))
1062      if (types::isCXX(InputType))
1063        CmdArgs.push_back("-std=c++98");
1064      else
1065        CmdArgs.push_back("-std=c89");
1066    else
1067      Std->render(Args, CmdArgs);
1068
1069    if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
1070                                 options::OPT_trigraphs))
1071      if (A != Std)
1072        A->render(Args, CmdArgs);
1073  } else {
1074    // Honor -std-default.
1075    //
1076    // FIXME: Clang doesn't correctly handle -std= when the input language
1077    // doesn't match. For the time being just ignore this for C++ inputs;
1078    // eventually we want to do all the standard defaulting here instead of
1079    // splitting it between the driver and clang -cc1.
1080    if (!types::isCXX(InputType))
1081        Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1082                                  "-std=", /*Joined=*/true);
1083    Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
1084  }
1085
1086  // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
1087  if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
1088    if (Asm->getOption().matches(options::OPT_fasm))
1089      CmdArgs.push_back("-fgnu-keywords");
1090    else
1091      CmdArgs.push_back("-fno-gnu-keywords");
1092  }
1093
1094  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) {
1095    CmdArgs.push_back("-ftemplate-depth");
1096    CmdArgs.push_back(A->getValue(Args));
1097  }
1098
1099  if (Args.hasArg(options::OPT__relocatable_pch))
1100    CmdArgs.push_back("-relocatable-pch");
1101
1102  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
1103    CmdArgs.push_back("-fconstant-string-class");
1104    CmdArgs.push_back(A->getValue(Args));
1105  }
1106
1107  if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
1108    CmdArgs.push_back("-ftabstop");
1109    CmdArgs.push_back(A->getValue(Args));
1110  }
1111
1112  CmdArgs.push_back("-ferror-limit");
1113  if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
1114    CmdArgs.push_back(A->getValue(Args));
1115  else
1116    CmdArgs.push_back("19");
1117
1118  if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
1119    CmdArgs.push_back("-fmacro-backtrace-limit");
1120    CmdArgs.push_back(A->getValue(Args));
1121  }
1122
1123  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
1124    CmdArgs.push_back("-ftemplate-backtrace-limit");
1125    CmdArgs.push_back(A->getValue(Args));
1126  }
1127
1128  // Pass -fmessage-length=.
1129  CmdArgs.push_back("-fmessage-length");
1130  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
1131    CmdArgs.push_back(A->getValue(Args));
1132  } else {
1133    // If -fmessage-length=N was not specified, determine whether this is a
1134    // terminal and, if so, implicitly define -fmessage-length appropriately.
1135    unsigned N = llvm::sys::Process::StandardErrColumns();
1136    CmdArgs.push_back(Args.MakeArgString(llvm::Twine(N)));
1137  }
1138
1139  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ)) {
1140    CmdArgs.push_back("-fvisibility");
1141    CmdArgs.push_back(A->getValue(Args));
1142  }
1143
1144  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
1145
1146  // -fhosted is default.
1147  if (KernelOrKext || Args.hasFlag(options::OPT_ffreestanding,
1148                                   options::OPT_fhosted,
1149                                   false))
1150    CmdArgs.push_back("-ffreestanding");
1151
1152  // Forward -f (flag) options which we can pass directly.
1153  Args.AddLastArg(CmdArgs, options::OPT_fcatch_undefined_behavior);
1154  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
1155  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
1156
1157  // -flax-vector-conversions is default.
1158  if (!Args.hasFlag(options::OPT_flax_vector_conversions,
1159                    options::OPT_fno_lax_vector_conversions))
1160    CmdArgs.push_back("-fno-lax-vector-conversions");
1161
1162  // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
1163  // takes precedence.
1164  const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
1165  if (!GCArg)
1166    GCArg = Args.getLastArg(options::OPT_fobjc_gc);
1167  if (GCArg) {
1168    if (getToolChain().SupportsObjCGC()) {
1169      GCArg->render(Args, CmdArgs);
1170    } else {
1171      // FIXME: We should move this to a hard error.
1172      D.Diag(clang::diag::warn_drv_objc_gc_unsupported)
1173        << GCArg->getAsString(Args);
1174    }
1175  }
1176
1177  Args.AddLastArg(CmdArgs, options::OPT_fno_show_column);
1178  Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
1179  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
1180  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
1181  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
1182  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
1183
1184  if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
1185    CmdArgs.push_back("-ftrapv-handler");
1186    CmdArgs.push_back(A->getValue(Args));
1187  }
1188
1189  Args.AddLastArg(CmdArgs, options::OPT_fwrapv);
1190  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
1191  Args.AddLastArg(CmdArgs, options::OPT_funroll_loops);
1192
1193  Args.AddLastArg(CmdArgs, options::OPT_pthread);
1194
1195  // -stack-protector=0 is default.
1196  unsigned StackProtectorLevel = 0;
1197  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
1198                               options::OPT_fstack_protector_all,
1199                               options::OPT_fstack_protector)) {
1200    if (A->getOption().matches(options::OPT_fstack_protector))
1201      StackProtectorLevel = 1;
1202    else if (A->getOption().matches(options::OPT_fstack_protector_all))
1203      StackProtectorLevel = 2;
1204  } else
1205    StackProtectorLevel = getToolChain().GetDefaultStackProtectorLevel();
1206  if (StackProtectorLevel) {
1207    CmdArgs.push_back("-stack-protector");
1208    CmdArgs.push_back(Args.MakeArgString(llvm::Twine(StackProtectorLevel)));
1209  }
1210
1211  // Forward -f options with positive and negative forms; we translate
1212  // these by hand.
1213
1214  // -fbuiltin is default.
1215  if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
1216    CmdArgs.push_back("-fno-builtin");
1217
1218  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
1219                    options::OPT_fno_assume_sane_operator_new))
1220    CmdArgs.push_back("-fno-assume-sane-operator-new");
1221
1222  // -fblocks=0 is default.
1223  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
1224                   getToolChain().IsBlocksDefault())) {
1225    CmdArgs.push_back("-fblocks");
1226  }
1227
1228  // -faccess-control is default.
1229  if (Args.hasFlag(options::OPT_fno_access_control,
1230                   options::OPT_faccess_control,
1231                   false))
1232    CmdArgs.push_back("-fno-access-control");
1233
1234  // -fexceptions=0 is default.
1235  if (!KernelOrKext &&
1236      needsExceptions(Args, InputType, getToolChain().getTriple()))
1237    CmdArgs.push_back("-fexceptions");
1238
1239  if (getToolChain().UseSjLjExceptions())
1240    CmdArgs.push_back("-fsjlj-exceptions");
1241
1242  // -frtti is default.
1243  if (KernelOrKext ||
1244      !Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
1245    CmdArgs.push_back("-fno-rtti");
1246
1247  // -fsigned-char is default.
1248  if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
1249                    isSignedCharDefault(getToolChain().getTriple())))
1250    CmdArgs.push_back("-fno-signed-char");
1251
1252  // -fthreadsafe-static is default.
1253  if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
1254                    options::OPT_fno_threadsafe_statics))
1255    CmdArgs.push_back("-fno-threadsafe-statics");
1256
1257  // -fuse-cxa-atexit is default.
1258  if (KernelOrKext ||
1259    !Args.hasFlag(options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
1260                  getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 &&
1261                  getToolChain().getTriple().getOS() != llvm::Triple::MinGW64))
1262    CmdArgs.push_back("-fno-use-cxa-atexit");
1263
1264  // -fms-extensions=0 is default.
1265  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
1266                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
1267    CmdArgs.push_back("-fms-extensions");
1268
1269  // -fborland-extensions=0 is default.
1270  if (Args.hasFlag(options::OPT_fborland_extensions,
1271                   options::OPT_fno_borland_extensions, false))
1272    CmdArgs.push_back("-fborland-extensions");
1273
1274  // -fgnu-keywords default varies depending on language; only pass if
1275  // specified.
1276  if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
1277                               options::OPT_fno_gnu_keywords))
1278    A->render(Args, CmdArgs);
1279
1280  // -fnext-runtime defaults to on Darwin and when rewriting Objective-C, and is
1281  // -the -cc1 default.
1282  bool NeXTRuntimeIsDefault =
1283    IsRewriter || getToolChain().getTriple().getOS() == llvm::Triple::Darwin;
1284  if (!Args.hasFlag(options::OPT_fnext_runtime, options::OPT_fgnu_runtime,
1285                    NeXTRuntimeIsDefault))
1286    CmdArgs.push_back("-fgnu-runtime");
1287
1288  // -fobjc-nonfragile-abi=0 is default.
1289  if (types::isObjC(InputType)) {
1290    // Compute the Objective-C ABI "version" to use. Version numbers are
1291    // slightly confusing for historical reasons:
1292    //   1 - Traditional "fragile" ABI
1293    //   2 - Non-fragile ABI, version 1
1294    //   3 - Non-fragile ABI, version 2
1295    unsigned Version = 1;
1296    // If -fobjc-abi-version= is present, use that to set the version.
1297    if (Arg *A = Args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
1298      if (llvm::StringRef(A->getValue(Args)) == "1")
1299        Version = 1;
1300      else if (llvm::StringRef(A->getValue(Args)) == "2")
1301        Version = 2;
1302      else if (llvm::StringRef(A->getValue(Args)) == "3")
1303        Version = 3;
1304      else
1305        D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
1306    } else {
1307      // Otherwise, determine if we are using the non-fragile ABI.
1308      if (Args.hasFlag(options::OPT_fobjc_nonfragile_abi,
1309                       options::OPT_fno_objc_nonfragile_abi,
1310                       getToolChain().IsObjCNonFragileABIDefault())) {
1311        // Determine the non-fragile ABI version to use.
1312        unsigned NonFragileABIVersion = 2;
1313
1314        if (Arg *A = Args.getLastArg(
1315              options::OPT_fobjc_nonfragile_abi_version_EQ)) {
1316          if (llvm::StringRef(A->getValue(Args)) == "1")
1317            NonFragileABIVersion = 1;
1318          else if (llvm::StringRef(A->getValue(Args)) == "2")
1319            NonFragileABIVersion = 2;
1320          else
1321            D.Diag(clang::diag::err_drv_clang_unsupported)
1322              << A->getAsString(Args);
1323        }
1324
1325        Version = 1 + NonFragileABIVersion;
1326      } else {
1327        Version = 1;
1328      }
1329    }
1330
1331    if (Version == 2 || Version == 3) {
1332      if (Version == 2)
1333        CmdArgs.push_back("-fobjc-nonfragile-abi");
1334      else
1335        CmdArgs.push_back("-fobjc-nonfragile-abi2");
1336
1337      // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
1338      // legacy is the default.
1339      if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
1340                        options::OPT_fno_objc_legacy_dispatch,
1341                        getToolChain().IsObjCLegacyDispatchDefault())) {
1342        if (getToolChain().UseObjCMixedDispatch())
1343          CmdArgs.push_back("-fobjc-dispatch-method=mixed");
1344        else
1345          CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
1346      }
1347    }
1348  }
1349
1350  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
1351                    options::OPT_fno_assume_sane_operator_new))
1352    CmdArgs.push_back("-fno-assume-sane-operator-new");
1353
1354  // -fconstant-cfstrings is default, and may be subject to argument translation
1355  // on Darwin.
1356  if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
1357                    options::OPT_fno_constant_cfstrings) ||
1358      !Args.hasFlag(options::OPT_mconstant_cfstrings,
1359                    options::OPT_mno_constant_cfstrings))
1360    CmdArgs.push_back("-fno-constant-cfstrings");
1361
1362  // -fshort-wchar default varies depending on platform; only
1363  // pass if specified.
1364  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar))
1365    A->render(Args, CmdArgs);
1366
1367  // -fno-pascal-strings is default, only pass non-default. If the tool chain
1368  // happened to translate to -mpascal-strings, we want to back translate here.
1369  //
1370  // FIXME: This is gross; that translation should be pulled from the
1371  // tool chain.
1372  if (Args.hasFlag(options::OPT_fpascal_strings,
1373                   options::OPT_fno_pascal_strings,
1374                   false) ||
1375      Args.hasFlag(options::OPT_mpascal_strings,
1376                   options::OPT_mno_pascal_strings,
1377                   false))
1378    CmdArgs.push_back("-fpascal-strings");
1379
1380  // -fcommon is default, only pass non-default.
1381  if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
1382    CmdArgs.push_back("-fno-common");
1383
1384  // -fsigned-bitfields is default, and clang doesn't yet support
1385  // --funsigned-bitfields.
1386  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
1387                    options::OPT_funsigned_bitfields))
1388    D.Diag(clang::diag::warn_drv_clang_unsupported)
1389      << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
1390
1391  // -fcaret-diagnostics is default.
1392  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
1393                    options::OPT_fno_caret_diagnostics, true))
1394    CmdArgs.push_back("-fno-caret-diagnostics");
1395
1396  // -fdiagnostics-fixit-info is default, only pass non-default.
1397  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
1398                    options::OPT_fno_diagnostics_fixit_info))
1399    CmdArgs.push_back("-fno-diagnostics-fixit-info");
1400
1401  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_binary);
1402
1403  // Enable -fdiagnostics-show-option by default.
1404  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
1405                   options::OPT_fno_diagnostics_show_option))
1406    CmdArgs.push_back("-fdiagnostics-show-option");
1407
1408  if (const Arg *A =
1409        Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
1410    CmdArgs.push_back("-fdiagnostics-show-category");
1411    CmdArgs.push_back(A->getValue(Args));
1412  }
1413
1414  // Color diagnostics are the default, unless the terminal doesn't support
1415  // them.
1416  if (Args.hasFlag(options::OPT_fcolor_diagnostics,
1417                   options::OPT_fno_color_diagnostics,
1418                   llvm::sys::Process::StandardErrHasColors()))
1419    CmdArgs.push_back("-fcolor-diagnostics");
1420
1421  if (!Args.hasFlag(options::OPT_fshow_source_location,
1422                    options::OPT_fno_show_source_location))
1423    CmdArgs.push_back("-fno-show-source-location");
1424
1425  if (!Args.hasFlag(options::OPT_fspell_checking,
1426                    options::OPT_fno_spell_checking))
1427    CmdArgs.push_back("-fno-spell-checking");
1428
1429  if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
1430    A->render(Args, CmdArgs);
1431
1432  // -fdollars-in-identifiers default varies depending on platform and
1433  // language; only pass if specified.
1434  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
1435                               options::OPT_fno_dollars_in_identifiers)) {
1436    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
1437      CmdArgs.push_back("-fdollars-in-identifiers");
1438    else
1439      CmdArgs.push_back("-fno-dollars-in-identifiers");
1440  }
1441
1442  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
1443  // practical purposes.
1444  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
1445                               options::OPT_fno_unit_at_a_time)) {
1446    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
1447      D.Diag(clang::diag::warn_drv_clang_unsupported) << A->getAsString(Args);
1448  }
1449
1450  // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
1451  //
1452  // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
1453#if 0
1454  if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin &&
1455      (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1456       getToolChain().getTriple().getArch() == llvm::Triple::thumb)) {
1457    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
1458      CmdArgs.push_back("-fno-builtin-strcat");
1459    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
1460      CmdArgs.push_back("-fno-builtin-strcpy");
1461  }
1462#endif
1463
1464  if (Arg *A = Args.getLastArg(options::OPT_traditional,
1465                               options::OPT_traditional_cpp))
1466    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
1467
1468  Args.AddLastArg(CmdArgs, options::OPT_dM);
1469  Args.AddLastArg(CmdArgs, options::OPT_dD);
1470
1471  // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
1472  // parser.
1473  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
1474  for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
1475         ie = Args.filtered_end(); it != ie; ++it) {
1476    (*it)->claim();
1477
1478    // We translate this by hand to the -cc1 argument, since nightly test uses
1479    // it and developers have been trained to spell it with -mllvm.
1480    if (llvm::StringRef((*it)->getValue(Args, 0)) == "-disable-llvm-optzns")
1481      CmdArgs.push_back("-disable-llvm-optzns");
1482    else
1483      (*it)->render(Args, CmdArgs);
1484  }
1485
1486  if (Output.getType() == types::TY_Dependencies) {
1487    // Handled with other dependency code.
1488  } else if (Output.isFilename()) {
1489    CmdArgs.push_back("-o");
1490    CmdArgs.push_back(Output.getFilename());
1491  } else {
1492    assert(Output.isNothing() && "Invalid output.");
1493  }
1494
1495  for (InputInfoList::const_iterator
1496         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1497    const InputInfo &II = *it;
1498    CmdArgs.push_back("-x");
1499    CmdArgs.push_back(types::getTypeName(II.getType()));
1500    if (II.isFilename())
1501      CmdArgs.push_back(II.getFilename());
1502    else
1503      II.getInputArg().renderAsInput(Args, CmdArgs);
1504  }
1505
1506  Args.AddAllArgs(CmdArgs, options::OPT_undef);
1507
1508  const char *Exec = getToolChain().getDriver().getClangProgramPath();
1509
1510  // Optionally embed the -cc1 level arguments into the debug info, for build
1511  // analysis.
1512  if (getToolChain().UseDwarfDebugFlags()) {
1513    ArgStringList OriginalArgs;
1514    for (ArgList::const_iterator it = Args.begin(),
1515           ie = Args.end(); it != ie; ++it)
1516      (*it)->render(Args, OriginalArgs);
1517
1518    llvm::SmallString<256> Flags;
1519    Flags += Exec;
1520    for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
1521      Flags += " ";
1522      Flags += OriginalArgs[i];
1523    }
1524    CmdArgs.push_back("-dwarf-debug-flags");
1525    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
1526  }
1527
1528  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
1529
1530  // Explicitly warn that these options are unsupported, even though
1531  // we are allowing compilation to continue.
1532  for (arg_iterator it = Args.filtered_begin(options::OPT_pg),
1533         ie = Args.filtered_end(); it != ie; ++it) {
1534    (*it)->claim();
1535    D.Diag(clang::diag::warn_drv_clang_unsupported) << (*it)->getAsString(Args);
1536  }
1537
1538  // Claim some arguments which clang supports automatically.
1539
1540  // -fpch-preprocess is used with gcc to add a special marker in the output to
1541  // include the PCH file. Clang's PTH solution is completely transparent, so we
1542  // do not need to deal with it at all.
1543  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
1544
1545  // Claim some arguments which clang doesn't support, but we don't
1546  // care to warn the user about.
1547  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
1548  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
1549}
1550
1551void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
1552                           const InputInfo &Output,
1553                           const InputInfoList &Inputs,
1554                           const ArgList &Args,
1555                           const char *LinkingOutput) const {
1556  ArgStringList CmdArgs;
1557
1558  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
1559  const InputInfo &Input = Inputs[0];
1560
1561  // Invoke ourselves in -cc1as mode.
1562  //
1563  // FIXME: Implement custom jobs for internal actions.
1564  CmdArgs.push_back("-cc1as");
1565
1566  // Add the "effective" target triple.
1567  CmdArgs.push_back("-triple");
1568  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
1569  CmdArgs.push_back(Args.MakeArgString(TripleStr));
1570
1571  // Set the output mode, we currently only expect to be used as a real
1572  // assembler.
1573  CmdArgs.push_back("-filetype");
1574  CmdArgs.push_back("obj");
1575
1576  // At -O0, we use -mrelax-all by default.
1577  bool IsOpt = false;
1578  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1579    IsOpt = !A->getOption().matches(options::OPT_O0);
1580  if (Args.hasFlag(options::OPT_mrelax_all,
1581                    options::OPT_mno_relax_all,
1582                    !IsOpt))
1583    CmdArgs.push_back("-relax-all");
1584
1585  // FIXME: Add -force_cpusubtype_ALL support, once we have it.
1586
1587  // FIXME: Add -g support, once we have it.
1588
1589  // FIXME: Add -static support, once we have it.
1590
1591  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
1592                       options::OPT_Xassembler);
1593
1594  assert(Output.isFilename() && "Unexpected lipo output.");
1595  CmdArgs.push_back("-o");
1596  CmdArgs.push_back(Output.getFilename());
1597
1598  assert(Input.isFilename() && "Invalid input.");
1599  CmdArgs.push_back(Input.getFilename());
1600
1601  const char *Exec = getToolChain().getDriver().getClangProgramPath();
1602  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
1603}
1604
1605void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
1606                               const InputInfo &Output,
1607                               const InputInfoList &Inputs,
1608                               const ArgList &Args,
1609                               const char *LinkingOutput) const {
1610  const Driver &D = getToolChain().getDriver();
1611  ArgStringList CmdArgs;
1612
1613  for (ArgList::const_iterator
1614         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
1615    Arg *A = *it;
1616    if (A->getOption().hasForwardToGCC()) {
1617      // Don't forward any -g arguments to assembly steps.
1618      if (isa<AssembleJobAction>(JA) &&
1619          A->getOption().matches(options::OPT_g_Group))
1620        continue;
1621
1622      // It is unfortunate that we have to claim here, as this means
1623      // we will basically never report anything interesting for
1624      // platforms using a generic gcc, even if we are just using gcc
1625      // to get to the assembler.
1626      A->claim();
1627      A->render(Args, CmdArgs);
1628    }
1629  }
1630
1631  RenderExtraToolArgs(JA, CmdArgs);
1632
1633  // If using a driver driver, force the arch.
1634  const std::string &Arch = getToolChain().getArchName();
1635  if (getToolChain().getTriple().getOS() == llvm::Triple::Darwin) {
1636    CmdArgs.push_back("-arch");
1637
1638    // FIXME: Remove these special cases.
1639    if (Arch == "powerpc")
1640      CmdArgs.push_back("ppc");
1641    else if (Arch == "powerpc64")
1642      CmdArgs.push_back("ppc64");
1643    else
1644      CmdArgs.push_back(Args.MakeArgString(Arch));
1645  }
1646
1647  // Try to force gcc to match the tool chain we want, if we recognize
1648  // the arch.
1649  //
1650  // FIXME: The triple class should directly provide the information we want
1651  // here.
1652  if (Arch == "i386" || Arch == "powerpc")
1653    CmdArgs.push_back("-m32");
1654  else if (Arch == "x86_64" || Arch == "powerpc64")
1655    CmdArgs.push_back("-m64");
1656
1657  if (Output.isFilename()) {
1658    CmdArgs.push_back("-o");
1659    CmdArgs.push_back(Output.getFilename());
1660  } else {
1661    assert(Output.isNothing() && "Unexpected output");
1662    CmdArgs.push_back("-fsyntax-only");
1663  }
1664
1665
1666  // Only pass -x if gcc will understand it; otherwise hope gcc
1667  // understands the suffix correctly. The main use case this would go
1668  // wrong in is for linker inputs if they happened to have an odd
1669  // suffix; really the only way to get this to happen is a command
1670  // like '-x foobar a.c' which will treat a.c like a linker input.
1671  //
1672  // FIXME: For the linker case specifically, can we safely convert
1673  // inputs into '-Wl,' options?
1674  for (InputInfoList::const_iterator
1675         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
1676    const InputInfo &II = *it;
1677
1678    // Don't try to pass LLVM or AST inputs to a generic gcc.
1679    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
1680        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
1681      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
1682        << getToolChain().getTripleString();
1683    else if (II.getType() == types::TY_AST)
1684      D.Diag(clang::diag::err_drv_no_ast_support)
1685        << getToolChain().getTripleString();
1686
1687    if (types::canTypeBeUserSpecified(II.getType())) {
1688      CmdArgs.push_back("-x");
1689      CmdArgs.push_back(types::getTypeName(II.getType()));
1690    }
1691
1692    if (II.isFilename())
1693      CmdArgs.push_back(II.getFilename());
1694    else
1695      // Don't render as input, we need gcc to do the translations.
1696      II.getInputArg().render(Args, CmdArgs);
1697  }
1698
1699  const char *GCCName = getToolChain().getDriver().getCCCGenericGCCName().c_str();
1700  const char *Exec =
1701    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
1702  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
1703}
1704
1705void gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
1706                                          ArgStringList &CmdArgs) const {
1707  CmdArgs.push_back("-E");
1708}
1709
1710void gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
1711                                          ArgStringList &CmdArgs) const {
1712  // The type is good enough.
1713}
1714
1715void gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
1716                                       ArgStringList &CmdArgs) const {
1717  const Driver &D = getToolChain().getDriver();
1718
1719  // If -flto, etc. are present then make sure not to force assembly output.
1720  if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
1721      JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
1722    CmdArgs.push_back("-c");
1723  else {
1724    if (JA.getType() != types::TY_PP_Asm)
1725      D.Diag(clang::diag::err_drv_invalid_gcc_output_type)
1726        << getTypeName(JA.getType());
1727
1728    CmdArgs.push_back("-S");
1729  }
1730}
1731
1732void gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
1733                                        ArgStringList &CmdArgs) const {
1734  CmdArgs.push_back("-c");
1735}
1736
1737void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
1738                                    ArgStringList &CmdArgs) const {
1739  // The types are (hopefully) good enough.
1740}
1741
1742const char *darwin::CC1::getCC1Name(types::ID Type) const {
1743  switch (Type) {
1744  default:
1745    assert(0 && "Unexpected type for Darwin CC1 tool.");
1746  case types::TY_Asm:
1747  case types::TY_C: case types::TY_CHeader:
1748  case types::TY_PP_C: case types::TY_PP_CHeader:
1749    return "cc1";
1750  case types::TY_ObjC: case types::TY_ObjCHeader:
1751  case types::TY_PP_ObjC: case types::TY_PP_ObjCHeader:
1752    return "cc1obj";
1753  case types::TY_CXX: case types::TY_CXXHeader:
1754  case types::TY_PP_CXX: case types::TY_PP_CXXHeader:
1755    return "cc1plus";
1756  case types::TY_ObjCXX: case types::TY_ObjCXXHeader:
1757  case types::TY_PP_ObjCXX: case types::TY_PP_ObjCXXHeader:
1758    return "cc1objplus";
1759  }
1760}
1761
1762const char *darwin::CC1::getBaseInputName(const ArgList &Args,
1763                                          const InputInfoList &Inputs) {
1764  llvm::sys::Path P(Inputs[0].getBaseInput());
1765  return Args.MakeArgString(P.getLast());
1766}
1767
1768const char *darwin::CC1::getBaseInputStem(const ArgList &Args,
1769                                          const InputInfoList &Inputs) {
1770  const char *Str = getBaseInputName(Args, Inputs);
1771
1772  if (const char *End = strchr(Str, '.'))
1773    return Args.MakeArgString(std::string(Str, End));
1774
1775  return Str;
1776}
1777
1778const char *
1779darwin::CC1::getDependencyFileName(const ArgList &Args,
1780                                   const InputInfoList &Inputs) {
1781  // FIXME: Think about this more.
1782  std::string Res;
1783
1784  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
1785    std::string Str(OutputOpt->getValue(Args));
1786
1787    Res = Str.substr(0, Str.rfind('.'));
1788  } else
1789    Res = darwin::CC1::getBaseInputStem(Args, Inputs);
1790
1791  return Args.MakeArgString(Res + ".d");
1792}
1793
1794void darwin::CC1::AddCC1Args(const ArgList &Args,
1795                             ArgStringList &CmdArgs) const {
1796  const Driver &D = getToolChain().getDriver();
1797
1798  CheckCodeGenerationOptions(D, Args);
1799
1800  // Derived from cc1 spec.
1801  if (!Args.hasArg(options::OPT_mkernel) && !Args.hasArg(options::OPT_static) &&
1802      !Args.hasArg(options::OPT_mdynamic_no_pic))
1803    CmdArgs.push_back("-fPIC");
1804
1805  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1806      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
1807    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
1808      CmdArgs.push_back("-fno-builtin-strcat");
1809    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
1810      CmdArgs.push_back("-fno-builtin-strcpy");
1811  }
1812
1813  // gcc has some code here to deal with when no -mmacosx-version-min
1814  // and no -miphoneos-version-min is present, but this never happens
1815  // due to tool chain specific argument translation.
1816
1817  if (Args.hasArg(options::OPT_g_Flag) &&
1818      !Args.hasArg(options::OPT_fno_eliminate_unused_debug_symbols))
1819    CmdArgs.push_back("-feliminate-unused-debug-symbols");
1820}
1821
1822void darwin::CC1::AddCC1OptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
1823                                    const InputInfoList &Inputs,
1824                                    const ArgStringList &OutputArgs) const {
1825  const Driver &D = getToolChain().getDriver();
1826
1827  // Derived from cc1_options spec.
1828  if (Args.hasArg(options::OPT_fast) ||
1829      Args.hasArg(options::OPT_fastf) ||
1830      Args.hasArg(options::OPT_fastcp))
1831    CmdArgs.push_back("-O3");
1832
1833  if (Arg *A = Args.getLastArg(options::OPT_pg))
1834    if (Args.hasArg(options::OPT_fomit_frame_pointer))
1835      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1836        << A->getAsString(Args) << "-fomit-frame-pointer";
1837
1838  AddCC1Args(Args, CmdArgs);
1839
1840  if (!Args.hasArg(options::OPT_Q))
1841    CmdArgs.push_back("-quiet");
1842
1843  CmdArgs.push_back("-dumpbase");
1844  CmdArgs.push_back(darwin::CC1::getBaseInputName(Args, Inputs));
1845
1846  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
1847
1848  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
1849  Args.AddAllArgs(CmdArgs, options::OPT_a_Group);
1850
1851  // FIXME: The goal is to use the user provided -o if that is our
1852  // final output, otherwise to drive from the original input
1853  // name. Find a clean way to go about this.
1854  if ((Args.hasArg(options::OPT_c) || Args.hasArg(options::OPT_S)) &&
1855      Args.hasArg(options::OPT_o)) {
1856    Arg *OutputOpt = Args.getLastArg(options::OPT_o);
1857    CmdArgs.push_back("-auxbase-strip");
1858    CmdArgs.push_back(OutputOpt->getValue(Args));
1859  } else {
1860    CmdArgs.push_back("-auxbase");
1861    CmdArgs.push_back(darwin::CC1::getBaseInputStem(Args, Inputs));
1862  }
1863
1864  Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
1865
1866  Args.AddAllArgs(CmdArgs, options::OPT_O);
1867  // FIXME: -Wall is getting some special treatment. Investigate.
1868  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
1869  Args.AddLastArg(CmdArgs, options::OPT_w);
1870  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
1871                  options::OPT_trigraphs);
1872  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1873    // Honor -std-default.
1874    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1875                              "-std=", /*Joined=*/true);
1876  }
1877
1878  if (Args.hasArg(options::OPT_v))
1879    CmdArgs.push_back("-version");
1880  if (Args.hasArg(options::OPT_pg))
1881    CmdArgs.push_back("-p");
1882  Args.AddLastArg(CmdArgs, options::OPT_p);
1883
1884  // The driver treats -fsyntax-only specially.
1885  if (getToolChain().getTriple().getArch() == llvm::Triple::arm ||
1886      getToolChain().getTriple().getArch() == llvm::Triple::thumb) {
1887    // Removes -fbuiltin-str{cat,cpy}; these aren't recognized by cc1 but are
1888    // used to inhibit the default -fno-builtin-str{cat,cpy}.
1889    //
1890    // FIXME: Should we grow a better way to deal with "removing" args?
1891    for (arg_iterator it = Args.filtered_begin(options::OPT_f_Group,
1892                                               options::OPT_fsyntax_only),
1893           ie = Args.filtered_end(); it != ie; ++it) {
1894      if (!(*it)->getOption().matches(options::OPT_fbuiltin_strcat) &&
1895          !(*it)->getOption().matches(options::OPT_fbuiltin_strcpy)) {
1896        (*it)->claim();
1897        (*it)->render(Args, CmdArgs);
1898      }
1899    }
1900  } else
1901    Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
1902
1903  Args.AddAllArgs(CmdArgs, options::OPT_undef);
1904  if (Args.hasArg(options::OPT_Qn))
1905    CmdArgs.push_back("-fno-ident");
1906
1907  // FIXME: This isn't correct.
1908  //Args.AddLastArg(CmdArgs, options::OPT__help)
1909  //Args.AddLastArg(CmdArgs, options::OPT__targetHelp)
1910
1911  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1912
1913  // FIXME: Still don't get what is happening here. Investigate.
1914  Args.AddAllArgs(CmdArgs, options::OPT__param);
1915
1916  if (Args.hasArg(options::OPT_fmudflap) ||
1917      Args.hasArg(options::OPT_fmudflapth)) {
1918    CmdArgs.push_back("-fno-builtin");
1919    CmdArgs.push_back("-fno-merge-constants");
1920  }
1921
1922  if (Args.hasArg(options::OPT_coverage)) {
1923    CmdArgs.push_back("-fprofile-arcs");
1924    CmdArgs.push_back("-ftest-coverage");
1925  }
1926
1927  if (types::isCXX(Inputs[0].getType()))
1928    CmdArgs.push_back("-D__private_extern__=extern");
1929}
1930
1931void darwin::CC1::AddCPPOptionsArgs(const ArgList &Args, ArgStringList &CmdArgs,
1932                                    const InputInfoList &Inputs,
1933                                    const ArgStringList &OutputArgs) const {
1934  // Derived from cpp_options
1935  AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
1936
1937  CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
1938
1939  AddCC1Args(Args, CmdArgs);
1940
1941  // NOTE: The code below has some commonality with cpp_options, but
1942  // in classic gcc style ends up sending things in different
1943  // orders. This may be a good merge candidate once we drop pedantic
1944  // compatibility.
1945
1946  Args.AddAllArgs(CmdArgs, options::OPT_m_Group);
1947  Args.AddAllArgs(CmdArgs, options::OPT_std_EQ, options::OPT_ansi,
1948                  options::OPT_trigraphs);
1949  if (!Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
1950    // Honor -std-default.
1951    Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
1952                              "-std=", /*Joined=*/true);
1953  }
1954  Args.AddAllArgs(CmdArgs, options::OPT_W_Group, options::OPT_pedantic_Group);
1955  Args.AddLastArg(CmdArgs, options::OPT_w);
1956
1957  // The driver treats -fsyntax-only specially.
1958  Args.AddAllArgs(CmdArgs, options::OPT_f_Group, options::OPT_fsyntax_only);
1959
1960  if (Args.hasArg(options::OPT_g_Group) && !Args.hasArg(options::OPT_g0) &&
1961      !Args.hasArg(options::OPT_fno_working_directory))
1962    CmdArgs.push_back("-fworking-directory");
1963
1964  Args.AddAllArgs(CmdArgs, options::OPT_O);
1965  Args.AddAllArgs(CmdArgs, options::OPT_undef);
1966  if (Args.hasArg(options::OPT_save_temps))
1967    CmdArgs.push_back("-fpch-preprocess");
1968}
1969
1970void darwin::CC1::AddCPPUniqueOptionsArgs(const ArgList &Args,
1971                                          ArgStringList &CmdArgs,
1972                                          const InputInfoList &Inputs) const {
1973  const Driver &D = getToolChain().getDriver();
1974
1975  CheckPreprocessingOptions(D, Args);
1976
1977  // Derived from cpp_unique_options.
1978  // -{C,CC} only with -E is checked in CheckPreprocessingOptions().
1979  Args.AddLastArg(CmdArgs, options::OPT_C);
1980  Args.AddLastArg(CmdArgs, options::OPT_CC);
1981  if (!Args.hasArg(options::OPT_Q))
1982    CmdArgs.push_back("-quiet");
1983  Args.AddAllArgs(CmdArgs, options::OPT_nostdinc);
1984  Args.AddAllArgs(CmdArgs, options::OPT_nostdincxx);
1985  Args.AddLastArg(CmdArgs, options::OPT_v);
1986  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
1987  Args.AddLastArg(CmdArgs, options::OPT_P);
1988
1989  // FIXME: Handle %I properly.
1990  if (getToolChain().getArchName() == "x86_64") {
1991    CmdArgs.push_back("-imultilib");
1992    CmdArgs.push_back("x86_64");
1993  }
1994
1995  if (Args.hasArg(options::OPT_MD)) {
1996    CmdArgs.push_back("-MD");
1997    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
1998  }
1999
2000  if (Args.hasArg(options::OPT_MMD)) {
2001    CmdArgs.push_back("-MMD");
2002    CmdArgs.push_back(darwin::CC1::getDependencyFileName(Args, Inputs));
2003  }
2004
2005  Args.AddLastArg(CmdArgs, options::OPT_M);
2006  Args.AddLastArg(CmdArgs, options::OPT_MM);
2007  Args.AddAllArgs(CmdArgs, options::OPT_MF);
2008  Args.AddLastArg(CmdArgs, options::OPT_MG);
2009  Args.AddLastArg(CmdArgs, options::OPT_MP);
2010  Args.AddAllArgs(CmdArgs, options::OPT_MQ);
2011  Args.AddAllArgs(CmdArgs, options::OPT_MT);
2012  if (!Args.hasArg(options::OPT_M) && !Args.hasArg(options::OPT_MM) &&
2013      (Args.hasArg(options::OPT_MD) || Args.hasArg(options::OPT_MMD))) {
2014    if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
2015      CmdArgs.push_back("-MQ");
2016      CmdArgs.push_back(OutputOpt->getValue(Args));
2017    }
2018  }
2019
2020  Args.AddLastArg(CmdArgs, options::OPT_remap);
2021  if (Args.hasArg(options::OPT_g3))
2022    CmdArgs.push_back("-dD");
2023  Args.AddLastArg(CmdArgs, options::OPT_H);
2024
2025  AddCPPArgs(Args, CmdArgs);
2026
2027  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U, options::OPT_A);
2028  Args.AddAllArgs(CmdArgs, options::OPT_i_Group);
2029
2030  for (InputInfoList::const_iterator
2031         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2032    const InputInfo &II = *it;
2033
2034    CmdArgs.push_back(II.getFilename());
2035  }
2036
2037  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
2038                       options::OPT_Xpreprocessor);
2039
2040  if (Args.hasArg(options::OPT_fmudflap)) {
2041    CmdArgs.push_back("-D_MUDFLAP");
2042    CmdArgs.push_back("-include");
2043    CmdArgs.push_back("mf-runtime.h");
2044  }
2045
2046  if (Args.hasArg(options::OPT_fmudflapth)) {
2047    CmdArgs.push_back("-D_MUDFLAP");
2048    CmdArgs.push_back("-D_MUDFLAPTH");
2049    CmdArgs.push_back("-include");
2050    CmdArgs.push_back("mf-runtime.h");
2051  }
2052}
2053
2054void darwin::CC1::AddCPPArgs(const ArgList &Args,
2055                             ArgStringList &CmdArgs) const {
2056  // Derived from cpp spec.
2057
2058  if (Args.hasArg(options::OPT_static)) {
2059    // The gcc spec is broken here, it refers to dynamic but
2060    // that has been translated. Start by being bug compatible.
2061
2062    // if (!Args.hasArg(arglist.parser.dynamicOption))
2063    CmdArgs.push_back("-D__STATIC__");
2064  } else
2065    CmdArgs.push_back("-D__DYNAMIC__");
2066
2067  if (Args.hasArg(options::OPT_pthread))
2068    CmdArgs.push_back("-D_REENTRANT");
2069}
2070
2071void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
2072                                      const InputInfo &Output,
2073                                      const InputInfoList &Inputs,
2074                                      const ArgList &Args,
2075                                      const char *LinkingOutput) const {
2076  ArgStringList CmdArgs;
2077
2078  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
2079
2080  CmdArgs.push_back("-E");
2081
2082  if (Args.hasArg(options::OPT_traditional) ||
2083      Args.hasArg(options::OPT_traditional_cpp))
2084    CmdArgs.push_back("-traditional-cpp");
2085
2086  ArgStringList OutputArgs;
2087  assert(Output.isFilename() && "Unexpected CC1 output.");
2088  OutputArgs.push_back("-o");
2089  OutputArgs.push_back(Output.getFilename());
2090
2091  if (Args.hasArg(options::OPT_E)) {
2092    AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
2093  } else {
2094    AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
2095    CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
2096  }
2097
2098  Args.AddAllArgs(CmdArgs, options::OPT_d_Group);
2099
2100  const char *CC1Name = getCC1Name(Inputs[0].getType());
2101  const char *Exec =
2102    Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
2103  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2104}
2105
2106void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
2107                                   const InputInfo &Output,
2108                                   const InputInfoList &Inputs,
2109                                   const ArgList &Args,
2110                                   const char *LinkingOutput) const {
2111  const Driver &D = getToolChain().getDriver();
2112  ArgStringList CmdArgs;
2113
2114  assert(Inputs.size() == 1 && "Unexpected number of inputs!");
2115
2116  types::ID InputType = Inputs[0].getType();
2117  const Arg *A;
2118  if ((A = Args.getLastArg(options::OPT_traditional)))
2119    D.Diag(clang::diag::err_drv_argument_only_allowed_with)
2120      << A->getAsString(Args) << "-E";
2121
2122  if (JA.getType() == types::TY_LLVM_IR ||
2123      JA.getType() == types::TY_LTO_IR)
2124    CmdArgs.push_back("-emit-llvm");
2125  else if (JA.getType() == types::TY_LLVM_BC ||
2126           JA.getType() == types::TY_LTO_BC)
2127    CmdArgs.push_back("-emit-llvm-bc");
2128  else if (Output.getType() == types::TY_AST)
2129    D.Diag(clang::diag::err_drv_no_ast_support)
2130      << getToolChain().getTripleString();
2131  else if (JA.getType() != types::TY_PP_Asm &&
2132           JA.getType() != types::TY_PCH)
2133    D.Diag(clang::diag::err_drv_invalid_gcc_output_type)
2134      << getTypeName(JA.getType());
2135
2136  ArgStringList OutputArgs;
2137  if (Output.getType() != types::TY_PCH) {
2138    OutputArgs.push_back("-o");
2139    if (Output.isNothing())
2140      OutputArgs.push_back("/dev/null");
2141    else
2142      OutputArgs.push_back(Output.getFilename());
2143  }
2144
2145  // There is no need for this level of compatibility, but it makes
2146  // diffing easier.
2147  bool OutputArgsEarly = (Args.hasArg(options::OPT_fsyntax_only) ||
2148                          Args.hasArg(options::OPT_S));
2149
2150  if (types::getPreprocessedType(InputType) != types::TY_INVALID) {
2151    AddCPPUniqueOptionsArgs(Args, CmdArgs, Inputs);
2152    if (OutputArgsEarly) {
2153      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
2154    } else {
2155      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
2156      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
2157    }
2158  } else {
2159    CmdArgs.push_back("-fpreprocessed");
2160
2161    for (InputInfoList::const_iterator
2162           it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2163      const InputInfo &II = *it;
2164
2165      // Reject AST inputs.
2166      if (II.getType() == types::TY_AST) {
2167        D.Diag(clang::diag::err_drv_no_ast_support)
2168          << getToolChain().getTripleString();
2169        return;
2170      }
2171
2172      CmdArgs.push_back(II.getFilename());
2173    }
2174
2175    if (OutputArgsEarly) {
2176      AddCC1OptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
2177    } else {
2178      AddCC1OptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
2179      CmdArgs.append(OutputArgs.begin(), OutputArgs.end());
2180    }
2181  }
2182
2183  if (Output.getType() == types::TY_PCH) {
2184    assert(Output.isFilename() && "Invalid PCH output.");
2185
2186    CmdArgs.push_back("-o");
2187    // NOTE: gcc uses a temp .s file for this, but there doesn't seem
2188    // to be a good reason.
2189    CmdArgs.push_back("/dev/null");
2190
2191    CmdArgs.push_back("--output-pch=");
2192    CmdArgs.push_back(Output.getFilename());
2193  }
2194
2195  const char *CC1Name = getCC1Name(Inputs[0].getType());
2196  const char *Exec =
2197    Args.MakeArgString(getToolChain().GetProgramPath(CC1Name));
2198  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2199}
2200
2201void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2202                                    const InputInfo &Output,
2203                                    const InputInfoList &Inputs,
2204                                    const ArgList &Args,
2205                                    const char *LinkingOutput) const {
2206  ArgStringList CmdArgs;
2207
2208  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
2209  const InputInfo &Input = Inputs[0];
2210
2211  // Bit of a hack, this is only used for original inputs.
2212  //
2213  // FIXME: This is broken for preprocessed .s inputs.
2214  if (Input.isFilename() &&
2215      strcmp(Input.getFilename(), Input.getBaseInput()) == 0) {
2216    if (Args.hasArg(options::OPT_gstabs))
2217      CmdArgs.push_back("--gstabs");
2218    else if (Args.hasArg(options::OPT_g_Group))
2219      CmdArgs.push_back("--gdwarf2");
2220  }
2221
2222  // Derived from asm spec.
2223  AddDarwinArch(Args, CmdArgs);
2224
2225  // Use -force_cpusubtype_ALL on x86 by default.
2226  if (getToolChain().getTriple().getArch() == llvm::Triple::x86 ||
2227      getToolChain().getTriple().getArch() == llvm::Triple::x86_64 ||
2228      Args.hasArg(options::OPT_force__cpusubtype__ALL))
2229    CmdArgs.push_back("-force_cpusubtype_ALL");
2230
2231  if (getToolChain().getTriple().getArch() != llvm::Triple::x86_64 &&
2232      (Args.hasArg(options::OPT_mkernel) ||
2233       Args.hasArg(options::OPT_static) ||
2234       Args.hasArg(options::OPT_fapple_kext)))
2235    CmdArgs.push_back("-static");
2236
2237  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2238                       options::OPT_Xassembler);
2239
2240  assert(Output.isFilename() && "Unexpected lipo output.");
2241  CmdArgs.push_back("-o");
2242  CmdArgs.push_back(Output.getFilename());
2243
2244  assert(Input.isFilename() && "Invalid input.");
2245  CmdArgs.push_back(Input.getFilename());
2246
2247  // asm_final spec is empty.
2248
2249  const char *Exec =
2250    Args.MakeArgString(getToolChain().GetProgramPath("as"));
2251  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2252}
2253
2254void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
2255                                       ArgStringList &CmdArgs) const {
2256  llvm::StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
2257
2258  // Derived from darwin_arch spec.
2259  CmdArgs.push_back("-arch");
2260  CmdArgs.push_back(Args.MakeArgString(ArchName));
2261
2262  // FIXME: Is this needed anymore?
2263  if (ArchName == "arm")
2264    CmdArgs.push_back("-force_cpusubtype_ALL");
2265}
2266
2267void darwin::Link::AddLinkArgs(Compilation &C,
2268                               const ArgList &Args,
2269                               ArgStringList &CmdArgs) const {
2270  const Driver &D = getToolChain().getDriver();
2271
2272  unsigned Version[3] = { 0, 0, 0 };
2273  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
2274    bool HadExtra;
2275    if (!Driver::GetReleaseVersion(A->getValue(Args), Version[0],
2276                                   Version[1], Version[2], HadExtra) ||
2277        HadExtra)
2278      D.Diag(clang::diag::err_drv_invalid_version_number)
2279        << A->getAsString(Args);
2280  }
2281
2282  // Newer linkers support -demangle, pass it if supported and not disabled by
2283  // the user.
2284  if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) {
2285    // Don't pass -demangle to ld_classic.
2286    //
2287    // FIXME: This is a temporary workaround, ld should be handling this.
2288    bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 &&
2289                          Args.hasArg(options::OPT_static));
2290    if (getToolChain().getArch() == llvm::Triple::x86) {
2291      for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker,
2292                                                 options::OPT_Wl_COMMA),
2293             ie = Args.filtered_end(); it != ie; ++it) {
2294        const Arg *A = *it;
2295        for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
2296          if (llvm::StringRef(A->getValue(Args, i)) == "-kext")
2297            UsesLdClassic = true;
2298      }
2299    }
2300    if (!UsesLdClassic)
2301      CmdArgs.push_back("-demangle");
2302  }
2303
2304  // Derived from the "link" spec.
2305  Args.AddAllArgs(CmdArgs, options::OPT_static);
2306  if (!Args.hasArg(options::OPT_static))
2307    CmdArgs.push_back("-dynamic");
2308  if (Args.hasArg(options::OPT_fgnu_runtime)) {
2309    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
2310    // here. How do we wish to handle such things?
2311  }
2312
2313  if (!Args.hasArg(options::OPT_dynamiclib)) {
2314    AddDarwinArch(Args, CmdArgs);
2315    // FIXME: Why do this only on this path?
2316    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
2317
2318    Args.AddLastArg(CmdArgs, options::OPT_bundle);
2319    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
2320    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
2321
2322    Arg *A;
2323    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
2324        (A = Args.getLastArg(options::OPT_current__version)) ||
2325        (A = Args.getLastArg(options::OPT_install__name)))
2326      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
2327        << A->getAsString(Args) << "-dynamiclib";
2328
2329    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
2330    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
2331    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
2332  } else {
2333    CmdArgs.push_back("-dylib");
2334
2335    Arg *A;
2336    if ((A = Args.getLastArg(options::OPT_bundle)) ||
2337        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
2338        (A = Args.getLastArg(options::OPT_client__name)) ||
2339        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
2340        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
2341        (A = Args.getLastArg(options::OPT_private__bundle)))
2342      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
2343        << A->getAsString(Args) << "-dynamiclib";
2344
2345    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
2346                              "-dylib_compatibility_version");
2347    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
2348                              "-dylib_current_version");
2349
2350    AddDarwinArch(Args, CmdArgs);
2351
2352    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
2353                              "-dylib_install_name");
2354  }
2355
2356  Args.AddLastArg(CmdArgs, options::OPT_all__load);
2357  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
2358  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
2359  if (getDarwinToolChain().isTargetIPhoneOS())
2360    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
2361  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
2362  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
2363  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
2364  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
2365  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
2366  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
2367  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
2368  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
2369  Args.AddAllArgs(CmdArgs, options::OPT_init);
2370
2371  // Adding all arguments doesn't make sense here but this is what gcc does. One
2372  // of this should always be present thanks to argument translation.
2373  assert((Args.hasArg(options::OPT_mmacosx_version_min_EQ) ||
2374          Args.hasArg(options::OPT_miphoneos_version_min_EQ)) &&
2375         "Missing version argument (lost in translation)?");
2376  Args.AddAllArgsTranslated(CmdArgs, options::OPT_mmacosx_version_min_EQ,
2377                            "-macosx_version_min");
2378  Args.AddAllArgsTranslated(CmdArgs, options::OPT_miphoneos_version_min_EQ,
2379                            "-iphoneos_version_min");
2380  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
2381  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
2382  Args.AddLastArg(CmdArgs, options::OPT_single__module);
2383  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
2384  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
2385
2386  if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
2387                                     options::OPT_fno_pie,
2388                                     options::OPT_fno_PIE)) {
2389    if (A->getOption().matches(options::OPT_fpie) ||
2390        A->getOption().matches(options::OPT_fPIE))
2391      CmdArgs.push_back("-pie");
2392    else
2393      CmdArgs.push_back("-no_pie");
2394  }
2395
2396  Args.AddLastArg(CmdArgs, options::OPT_prebind);
2397  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
2398  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
2399  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
2400  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
2401  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
2402  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
2403  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
2404  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
2405  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
2406  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
2407  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
2408  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
2409  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
2410  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
2411  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
2412
2413  Args.AddAllArgsTranslated(CmdArgs, options::OPT_isysroot, "-syslibroot");
2414  if (getDarwinToolChain().isTargetIPhoneOS()) {
2415    if (!Args.hasArg(options::OPT_isysroot)) {
2416      CmdArgs.push_back("-syslibroot");
2417      CmdArgs.push_back("/Developer/SDKs/Extra");
2418    }
2419  }
2420
2421  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
2422  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
2423  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
2424  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
2425  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
2426  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
2427  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
2428  Args.AddAllArgs(CmdArgs, options::OPT_y);
2429  Args.AddLastArg(CmdArgs, options::OPT_w);
2430  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
2431  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
2432  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
2433  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
2434  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
2435  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
2436  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
2437  Args.AddLastArg(CmdArgs, options::OPT_whyload);
2438  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
2439  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
2440  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
2441  Args.AddLastArg(CmdArgs, options::OPT_Mach);
2442}
2443
2444void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
2445                                const InputInfo &Output,
2446                                const InputInfoList &Inputs,
2447                                const ArgList &Args,
2448                                const char *LinkingOutput) const {
2449  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
2450
2451  // The logic here is derived from gcc's behavior; most of which
2452  // comes from specs (starting with link_command). Consult gcc for
2453  // more information.
2454  ArgStringList CmdArgs;
2455
2456  // I'm not sure why this particular decomposition exists in gcc, but
2457  // we follow suite for ease of comparison.
2458  AddLinkArgs(C, Args, CmdArgs);
2459
2460  Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
2461  Args.AddAllArgs(CmdArgs, options::OPT_s);
2462  Args.AddAllArgs(CmdArgs, options::OPT_t);
2463  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
2464  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
2465  Args.AddAllArgs(CmdArgs, options::OPT_A);
2466  Args.AddLastArg(CmdArgs, options::OPT_e);
2467  Args.AddAllArgs(CmdArgs, options::OPT_m_Separate);
2468  Args.AddAllArgs(CmdArgs, options::OPT_r);
2469
2470  CmdArgs.push_back("-o");
2471  CmdArgs.push_back(Output.getFilename());
2472
2473  if (!Args.hasArg(options::OPT_A) &&
2474      !Args.hasArg(options::OPT_nostdlib) &&
2475      !Args.hasArg(options::OPT_nostartfiles)) {
2476    // Derived from startfile spec.
2477    if (Args.hasArg(options::OPT_dynamiclib)) {
2478      // Derived from darwin_dylib1 spec.
2479      if (getDarwinToolChain().isTargetIPhoneOS()) {
2480        if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
2481          CmdArgs.push_back("-ldylib1.o");
2482      } else {
2483        if (getDarwinToolChain().isMacosxVersionLT(10, 5))
2484          CmdArgs.push_back("-ldylib1.o");
2485        else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
2486          CmdArgs.push_back("-ldylib1.10.5.o");
2487      }
2488    } else {
2489      if (Args.hasArg(options::OPT_bundle)) {
2490        if (!Args.hasArg(options::OPT_static)) {
2491          // Derived from darwin_bundle1 spec.
2492          if (getDarwinToolChain().isTargetIPhoneOS()) {
2493            if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
2494              CmdArgs.push_back("-lbundle1.o");
2495          } else {
2496            if (getDarwinToolChain().isMacosxVersionLT(10, 6))
2497              CmdArgs.push_back("-lbundle1.o");
2498          }
2499        }
2500      } else {
2501        if (Args.hasArg(options::OPT_pg)) {
2502          if (Args.hasArg(options::OPT_static) ||
2503              Args.hasArg(options::OPT_object) ||
2504              Args.hasArg(options::OPT_preload)) {
2505            CmdArgs.push_back("-lgcrt0.o");
2506          } else {
2507            CmdArgs.push_back("-lgcrt1.o");
2508
2509            // darwin_crt2 spec is empty.
2510          }
2511        } else {
2512          if (Args.hasArg(options::OPT_static) ||
2513              Args.hasArg(options::OPT_object) ||
2514              Args.hasArg(options::OPT_preload)) {
2515            CmdArgs.push_back("-lcrt0.o");
2516          } else {
2517            // Derived from darwin_crt1 spec.
2518            if (getDarwinToolChain().isTargetIPhoneOS()) {
2519              if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
2520                CmdArgs.push_back("-lcrt1.o");
2521              else
2522                CmdArgs.push_back("-lcrt1.3.1.o");
2523            } else {
2524              if (getDarwinToolChain().isMacosxVersionLT(10, 5))
2525                CmdArgs.push_back("-lcrt1.o");
2526              else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
2527                CmdArgs.push_back("-lcrt1.10.5.o");
2528              else
2529                CmdArgs.push_back("-lcrt1.10.6.o");
2530
2531              // darwin_crt2 spec is empty.
2532            }
2533          }
2534        }
2535      }
2536    }
2537
2538    if (!getDarwinToolChain().isTargetIPhoneOS() &&
2539        Args.hasArg(options::OPT_shared_libgcc) &&
2540        getDarwinToolChain().isMacosxVersionLT(10, 5)) {
2541      const char *Str =
2542        Args.MakeArgString(getToolChain().GetFilePath("crt3.o"));
2543      CmdArgs.push_back(Str);
2544    }
2545  }
2546
2547  Args.AddAllArgs(CmdArgs, options::OPT_L);
2548
2549  if (Args.hasArg(options::OPT_fopenmp))
2550    // This is more complicated in gcc...
2551    CmdArgs.push_back("-lgomp");
2552
2553  getDarwinToolChain().AddLinkSearchPathArgs(Args, CmdArgs);
2554
2555  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
2556
2557  if (LinkingOutput) {
2558    CmdArgs.push_back("-arch_multiple");
2559    CmdArgs.push_back("-final_output");
2560    CmdArgs.push_back(LinkingOutput);
2561  }
2562
2563  if (Args.hasArg(options::OPT_fprofile_arcs) ||
2564      Args.hasArg(options::OPT_fprofile_generate) ||
2565      Args.hasArg(options::OPT_fcreate_profile) ||
2566      Args.hasArg(options::OPT_coverage))
2567    CmdArgs.push_back("-lgcov");
2568
2569  if (Args.hasArg(options::OPT_fnested_functions))
2570    CmdArgs.push_back("-allow_stack_execute");
2571
2572  if (!Args.hasArg(options::OPT_nostdlib) &&
2573      !Args.hasArg(options::OPT_nodefaultlibs)) {
2574    if (getToolChain().getDriver().CCCIsCXX)
2575      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
2576
2577    // link_ssp spec is empty.
2578
2579    // Let the tool chain choose which runtime library to link.
2580    getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
2581  }
2582
2583  if (!Args.hasArg(options::OPT_A) &&
2584      !Args.hasArg(options::OPT_nostdlib) &&
2585      !Args.hasArg(options::OPT_nostartfiles)) {
2586    // endfile_spec is empty.
2587  }
2588
2589  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2590  Args.AddAllArgs(CmdArgs, options::OPT_F);
2591
2592  const char *Exec =
2593    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
2594  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2595}
2596
2597void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
2598                                const InputInfo &Output,
2599                                const InputInfoList &Inputs,
2600                                const ArgList &Args,
2601                                const char *LinkingOutput) const {
2602  ArgStringList CmdArgs;
2603
2604  CmdArgs.push_back("-create");
2605  assert(Output.isFilename() && "Unexpected lipo output.");
2606
2607  CmdArgs.push_back("-output");
2608  CmdArgs.push_back(Output.getFilename());
2609
2610  for (InputInfoList::const_iterator
2611         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2612    const InputInfo &II = *it;
2613    assert(II.isFilename() && "Unexpected lipo input.");
2614    CmdArgs.push_back(II.getFilename());
2615  }
2616  const char *Exec =
2617    Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
2618  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2619}
2620
2621void darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
2622                                    const InputInfo &Output,
2623                                    const InputInfoList &Inputs,
2624                                    const ArgList &Args,
2625                                    const char *LinkingOutput) const {
2626  ArgStringList CmdArgs;
2627
2628  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
2629  const InputInfo &Input = Inputs[0];
2630  assert(Input.isFilename() && "Unexpected dsymutil input.");
2631  CmdArgs.push_back(Input.getFilename());
2632
2633  CmdArgs.push_back("-o");
2634  CmdArgs.push_back(Output.getFilename());
2635
2636  const char *Exec =
2637    Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
2638  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2639}
2640
2641void auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2642                                      const InputInfo &Output,
2643                                      const InputInfoList &Inputs,
2644                                      const ArgList &Args,
2645                                      const char *LinkingOutput) const {
2646  ArgStringList CmdArgs;
2647
2648  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2649                       options::OPT_Xassembler);
2650
2651  CmdArgs.push_back("-o");
2652  CmdArgs.push_back(Output.getFilename());
2653
2654  for (InputInfoList::const_iterator
2655         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2656    const InputInfo &II = *it;
2657    CmdArgs.push_back(II.getFilename());
2658  }
2659
2660  const char *Exec =
2661    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
2662  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2663}
2664
2665void auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
2666                                  const InputInfo &Output,
2667                                  const InputInfoList &Inputs,
2668                                  const ArgList &Args,
2669                                  const char *LinkingOutput) const {
2670  ArgStringList CmdArgs;
2671
2672  if ((!Args.hasArg(options::OPT_nostdlib)) &&
2673      (!Args.hasArg(options::OPT_shared))) {
2674    CmdArgs.push_back("-e");
2675    CmdArgs.push_back("_start");
2676  }
2677
2678  if (Args.hasArg(options::OPT_static)) {
2679    CmdArgs.push_back("-Bstatic");
2680    CmdArgs.push_back("-dn");
2681  } else {
2682//    CmdArgs.push_back("--eh-frame-hdr");
2683    CmdArgs.push_back("-Bdynamic");
2684    if (Args.hasArg(options::OPT_shared)) {
2685      CmdArgs.push_back("-shared");
2686    } else {
2687      CmdArgs.push_back("--dynamic-linker");
2688      CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
2689    }
2690  }
2691
2692  if (Output.isFilename()) {
2693    CmdArgs.push_back("-o");
2694    CmdArgs.push_back(Output.getFilename());
2695  } else {
2696    assert(Output.isNothing() && "Invalid output.");
2697  }
2698
2699  if (!Args.hasArg(options::OPT_nostdlib) &&
2700      !Args.hasArg(options::OPT_nostartfiles)) {
2701    if (!Args.hasArg(options::OPT_shared)) {
2702      CmdArgs.push_back(Args.MakeArgString(
2703                                getToolChain().GetFilePath("crt1.o")));
2704      CmdArgs.push_back(Args.MakeArgString(
2705                                getToolChain().GetFilePath("crti.o")));
2706      CmdArgs.push_back(Args.MakeArgString(
2707                                getToolChain().GetFilePath("crtbegin.o")));
2708    } else {
2709      CmdArgs.push_back(Args.MakeArgString(
2710                                getToolChain().GetFilePath("crti.o")));
2711    }
2712    CmdArgs.push_back(Args.MakeArgString(
2713                                getToolChain().GetFilePath("crtn.o")));
2714  }
2715
2716  CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
2717                                       + getToolChain().getTripleString()
2718                                       + "/4.2.4"));
2719
2720  Args.AddAllArgs(CmdArgs, options::OPT_L);
2721  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2722  Args.AddAllArgs(CmdArgs, options::OPT_e);
2723
2724  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
2725
2726  if (!Args.hasArg(options::OPT_nostdlib) &&
2727      !Args.hasArg(options::OPT_nodefaultlibs)) {
2728    // FIXME: For some reason GCC passes -lgcc before adding
2729    // the default system libraries. Just mimic this for now.
2730    CmdArgs.push_back("-lgcc");
2731
2732    if (Args.hasArg(options::OPT_pthread))
2733      CmdArgs.push_back("-pthread");
2734    if (!Args.hasArg(options::OPT_shared))
2735      CmdArgs.push_back("-lc");
2736    CmdArgs.push_back("-lgcc");
2737  }
2738
2739  if (!Args.hasArg(options::OPT_nostdlib) &&
2740      !Args.hasArg(options::OPT_nostartfiles)) {
2741    if (!Args.hasArg(options::OPT_shared))
2742      CmdArgs.push_back(Args.MakeArgString(
2743                                getToolChain().GetFilePath("crtend.o")));
2744  }
2745
2746  const char *Exec =
2747    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
2748  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2749}
2750
2751void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2752                                     const InputInfo &Output,
2753                                     const InputInfoList &Inputs,
2754                                     const ArgList &Args,
2755                                     const char *LinkingOutput) const {
2756  ArgStringList CmdArgs;
2757
2758  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2759                       options::OPT_Xassembler);
2760
2761  CmdArgs.push_back("-o");
2762  CmdArgs.push_back(Output.getFilename());
2763
2764  for (InputInfoList::const_iterator
2765         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2766    const InputInfo &II = *it;
2767    CmdArgs.push_back(II.getFilename());
2768  }
2769
2770  const char *Exec =
2771    Args.MakeArgString(getToolChain().GetProgramPath("as"));
2772  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2773}
2774
2775void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
2776                                 const InputInfo &Output,
2777                                 const InputInfoList &Inputs,
2778                                 const ArgList &Args,
2779                                 const char *LinkingOutput) const {
2780  const Driver &D = getToolChain().getDriver();
2781  ArgStringList CmdArgs;
2782
2783  if ((!Args.hasArg(options::OPT_nostdlib)) &&
2784      (!Args.hasArg(options::OPT_shared))) {
2785    CmdArgs.push_back("-e");
2786    CmdArgs.push_back("__start");
2787  }
2788
2789  if (Args.hasArg(options::OPT_static)) {
2790    CmdArgs.push_back("-Bstatic");
2791  } else {
2792    CmdArgs.push_back("--eh-frame-hdr");
2793    CmdArgs.push_back("-Bdynamic");
2794    if (Args.hasArg(options::OPT_shared)) {
2795      CmdArgs.push_back("-shared");
2796    } else {
2797      CmdArgs.push_back("-dynamic-linker");
2798      CmdArgs.push_back("/usr/libexec/ld.so");
2799    }
2800  }
2801
2802  if (Output.isFilename()) {
2803    CmdArgs.push_back("-o");
2804    CmdArgs.push_back(Output.getFilename());
2805  } else {
2806    assert(Output.isNothing() && "Invalid output.");
2807  }
2808
2809  if (!Args.hasArg(options::OPT_nostdlib) &&
2810      !Args.hasArg(options::OPT_nostartfiles)) {
2811    if (!Args.hasArg(options::OPT_shared)) {
2812      CmdArgs.push_back(Args.MakeArgString(
2813                              getToolChain().GetFilePath("crt0.o")));
2814      CmdArgs.push_back(Args.MakeArgString(
2815                              getToolChain().GetFilePath("crtbegin.o")));
2816    } else {
2817      CmdArgs.push_back(Args.MakeArgString(
2818                              getToolChain().GetFilePath("crtbeginS.o")));
2819    }
2820  }
2821
2822  std::string Triple = getToolChain().getTripleString();
2823  if (Triple.substr(0, 6) == "x86_64")
2824    Triple.replace(0, 6, "amd64");
2825  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
2826                                       "/4.2.1"));
2827
2828  Args.AddAllArgs(CmdArgs, options::OPT_L);
2829  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2830  Args.AddAllArgs(CmdArgs, options::OPT_e);
2831
2832  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
2833
2834  if (!Args.hasArg(options::OPT_nostdlib) &&
2835      !Args.hasArg(options::OPT_nodefaultlibs)) {
2836    if (D.CCCIsCXX) {
2837      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
2838      CmdArgs.push_back("-lm");
2839    }
2840
2841    // FIXME: For some reason GCC passes -lgcc before adding
2842    // the default system libraries. Just mimic this for now.
2843    CmdArgs.push_back("-lgcc");
2844
2845    if (Args.hasArg(options::OPT_pthread))
2846      CmdArgs.push_back("-pthread");
2847    if (!Args.hasArg(options::OPT_shared))
2848      CmdArgs.push_back("-lc");
2849    CmdArgs.push_back("-lgcc");
2850  }
2851
2852  if (!Args.hasArg(options::OPT_nostdlib) &&
2853      !Args.hasArg(options::OPT_nostartfiles)) {
2854    if (!Args.hasArg(options::OPT_shared))
2855      CmdArgs.push_back(Args.MakeArgString(
2856                              getToolChain().GetFilePath("crtend.o")));
2857    else
2858      CmdArgs.push_back(Args.MakeArgString(
2859                              getToolChain().GetFilePath("crtendS.o")));
2860  }
2861
2862  const char *Exec =
2863    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
2864  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2865}
2866
2867void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
2868                                     const InputInfo &Output,
2869                                     const InputInfoList &Inputs,
2870                                     const ArgList &Args,
2871                                     const char *LinkingOutput) const {
2872  ArgStringList CmdArgs;
2873
2874  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
2875  // instruct as in the base system to assemble 32-bit code.
2876  if (getToolChain().getArchName() == "i386")
2877    CmdArgs.push_back("--32");
2878
2879
2880  // Set byte order explicitly
2881  if (getToolChain().getArchName() == "mips")
2882    CmdArgs.push_back("-EB");
2883  else if (getToolChain().getArchName() == "mipsel")
2884    CmdArgs.push_back("-EL");
2885
2886  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
2887                       options::OPT_Xassembler);
2888
2889  CmdArgs.push_back("-o");
2890  CmdArgs.push_back(Output.getFilename());
2891
2892  for (InputInfoList::const_iterator
2893         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
2894    const InputInfo &II = *it;
2895    CmdArgs.push_back(II.getFilename());
2896  }
2897
2898  const char *Exec =
2899    Args.MakeArgString(getToolChain().GetProgramPath("as"));
2900  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
2901}
2902
2903void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
2904                                 const InputInfo &Output,
2905                                 const InputInfoList &Inputs,
2906                                 const ArgList &Args,
2907                                 const char *LinkingOutput) const {
2908  const Driver &D = getToolChain().getDriver();
2909  ArgStringList CmdArgs;
2910
2911  if (Args.hasArg(options::OPT_static)) {
2912    CmdArgs.push_back("-Bstatic");
2913  } else {
2914    CmdArgs.push_back("--eh-frame-hdr");
2915    if (Args.hasArg(options::OPT_shared)) {
2916      CmdArgs.push_back("-Bshareable");
2917    } else {
2918      CmdArgs.push_back("-dynamic-linker");
2919      CmdArgs.push_back("/libexec/ld-elf.so.1");
2920    }
2921  }
2922
2923  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
2924  // instruct ld in the base system to link 32-bit code.
2925  if (getToolChain().getArchName() == "i386") {
2926    CmdArgs.push_back("-m");
2927    CmdArgs.push_back("elf_i386_fbsd");
2928  }
2929
2930  if (Output.isFilename()) {
2931    CmdArgs.push_back("-o");
2932    CmdArgs.push_back(Output.getFilename());
2933  } else {
2934    assert(Output.isNothing() && "Invalid output.");
2935  }
2936
2937  if (!Args.hasArg(options::OPT_nostdlib) &&
2938      !Args.hasArg(options::OPT_nostartfiles)) {
2939    if (!Args.hasArg(options::OPT_shared)) {
2940      CmdArgs.push_back(Args.MakeArgString(
2941                              getToolChain().GetFilePath("crt1.o")));
2942      CmdArgs.push_back(Args.MakeArgString(
2943                              getToolChain().GetFilePath("crti.o")));
2944      CmdArgs.push_back(Args.MakeArgString(
2945                              getToolChain().GetFilePath("crtbegin.o")));
2946    } else {
2947      CmdArgs.push_back(Args.MakeArgString(
2948                              getToolChain().GetFilePath("crti.o")));
2949      CmdArgs.push_back(Args.MakeArgString(
2950                              getToolChain().GetFilePath("crtbeginS.o")));
2951    }
2952  }
2953
2954  Args.AddAllArgs(CmdArgs, options::OPT_L);
2955  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
2956  Args.AddAllArgs(CmdArgs, options::OPT_e);
2957  Args.AddAllArgs(CmdArgs, options::OPT_s);
2958  Args.AddAllArgs(CmdArgs, options::OPT_t);
2959  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
2960  Args.AddAllArgs(CmdArgs, options::OPT_r);
2961
2962  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
2963
2964  if (!Args.hasArg(options::OPT_nostdlib) &&
2965      !Args.hasArg(options::OPT_nodefaultlibs)) {
2966    if (D.CCCIsCXX) {
2967      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
2968      CmdArgs.push_back("-lm");
2969    }
2970    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
2971    // the default system libraries. Just mimic this for now.
2972    CmdArgs.push_back("-lgcc");
2973    if (Args.hasArg(options::OPT_static)) {
2974      CmdArgs.push_back("-lgcc_eh");
2975    } else {
2976      CmdArgs.push_back("--as-needed");
2977      CmdArgs.push_back("-lgcc_s");
2978      CmdArgs.push_back("--no-as-needed");
2979    }
2980
2981    if (Args.hasArg(options::OPT_pthread))
2982      CmdArgs.push_back("-lpthread");
2983    CmdArgs.push_back("-lc");
2984
2985    CmdArgs.push_back("-lgcc");
2986    if (Args.hasArg(options::OPT_static)) {
2987      CmdArgs.push_back("-lgcc_eh");
2988    } else {
2989      CmdArgs.push_back("--as-needed");
2990      CmdArgs.push_back("-lgcc_s");
2991      CmdArgs.push_back("--no-as-needed");
2992    }
2993  }
2994
2995  if (!Args.hasArg(options::OPT_nostdlib) &&
2996      !Args.hasArg(options::OPT_nostartfiles)) {
2997    if (!Args.hasArg(options::OPT_shared))
2998      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
2999                                                                  "crtend.o")));
3000    else
3001      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
3002                                                                 "crtendS.o")));
3003    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
3004                                                                    "crtn.o")));
3005  }
3006
3007  const char *Exec =
3008    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
3009  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3010}
3011
3012void linuxtools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
3013                                        const InputInfo &Output,
3014                                        const InputInfoList &Inputs,
3015                                        const ArgList &Args,
3016                                        const char *LinkingOutput) const {
3017  ArgStringList CmdArgs;
3018
3019  // Add --32/--64 to make sure we get the format we want.
3020  // This is incomplete
3021  if (getToolChain().getArch() == llvm::Triple::x86) {
3022    CmdArgs.push_back("--32");
3023  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
3024    CmdArgs.push_back("--64");
3025  } else if (getToolChain().getArch() == llvm::Triple::arm) {
3026    llvm::StringRef MArch = getToolChain().getArchName();
3027    if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
3028      CmdArgs.push_back("-mfpu=neon");
3029  }
3030
3031  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
3032                       options::OPT_Xassembler);
3033
3034  CmdArgs.push_back("-o");
3035  CmdArgs.push_back(Output.getFilename());
3036
3037  for (InputInfoList::const_iterator
3038         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
3039    const InputInfo &II = *it;
3040    CmdArgs.push_back(II.getFilename());
3041  }
3042
3043  const char *Exec =
3044    Args.MakeArgString(getToolChain().GetProgramPath("as"));
3045  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3046}
3047
3048
3049void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
3050                                   const InputInfo &Output,
3051                                   const InputInfoList &Inputs,
3052                                   const ArgList &Args,
3053                                   const char *LinkingOutput) const {
3054  ArgStringList CmdArgs;
3055
3056  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
3057                       options::OPT_Xassembler);
3058
3059  CmdArgs.push_back("-o");
3060  CmdArgs.push_back(Output.getFilename());
3061
3062  for (InputInfoList::const_iterator
3063         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
3064    const InputInfo &II = *it;
3065    CmdArgs.push_back(II.getFilename());
3066  }
3067
3068  const char *Exec =
3069    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
3070  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3071}
3072
3073void minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
3074                               const InputInfo &Output,
3075                               const InputInfoList &Inputs,
3076                               const ArgList &Args,
3077                               const char *LinkingOutput) const {
3078  const Driver &D = getToolChain().getDriver();
3079  ArgStringList CmdArgs;
3080
3081  if (Output.isFilename()) {
3082    CmdArgs.push_back("-o");
3083    CmdArgs.push_back(Output.getFilename());
3084  } else {
3085    assert(Output.isNothing() && "Invalid output.");
3086  }
3087
3088  if (!Args.hasArg(options::OPT_nostdlib) &&
3089      !Args.hasArg(options::OPT_nostartfiles))
3090    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
3091                                                      "/usr/gnu/lib/crtso.o")));
3092
3093  Args.AddAllArgs(CmdArgs, options::OPT_L);
3094  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
3095  Args.AddAllArgs(CmdArgs, options::OPT_e);
3096
3097  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
3098
3099  if (!Args.hasArg(options::OPT_nostdlib) &&
3100      !Args.hasArg(options::OPT_nodefaultlibs)) {
3101    if (D.CCCIsCXX) {
3102      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
3103      CmdArgs.push_back("-lm");
3104    }
3105
3106    if (Args.hasArg(options::OPT_pthread))
3107      CmdArgs.push_back("-lpthread");
3108    CmdArgs.push_back("-lc");
3109    CmdArgs.push_back("-lgcc");
3110    CmdArgs.push_back("-L/usr/gnu/lib");
3111    // FIXME: fill in the correct search path for the final
3112    // support libraries.
3113    CmdArgs.push_back("-L/usr/gnu/lib/gcc/i686-pc-minix/4.4.3");
3114  }
3115
3116  if (!Args.hasArg(options::OPT_nostdlib) &&
3117      !Args.hasArg(options::OPT_nostartfiles)) {
3118    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
3119                                              "/usr/gnu/lib/libend.a")));
3120  }
3121
3122  const char *Exec =
3123    Args.MakeArgString(getToolChain().GetProgramPath("/usr/gnu/bin/gld"));
3124  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3125}
3126
3127/// DragonFly Tools
3128
3129// For now, DragonFly Assemble does just about the same as for
3130// FreeBSD, but this may change soon.
3131void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
3132                                       const InputInfo &Output,
3133                                       const InputInfoList &Inputs,
3134                                       const ArgList &Args,
3135                                       const char *LinkingOutput) const {
3136  ArgStringList CmdArgs;
3137
3138  // When building 32-bit code on DragonFly/pc64, we have to explicitly
3139  // instruct as in the base system to assemble 32-bit code.
3140  if (getToolChain().getArchName() == "i386")
3141    CmdArgs.push_back("--32");
3142
3143  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
3144                       options::OPT_Xassembler);
3145
3146  CmdArgs.push_back("-o");
3147  CmdArgs.push_back(Output.getFilename());
3148
3149  for (InputInfoList::const_iterator
3150         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
3151    const InputInfo &II = *it;
3152    CmdArgs.push_back(II.getFilename());
3153  }
3154
3155  const char *Exec =
3156    Args.MakeArgString(getToolChain().GetProgramPath("as"));
3157  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3158}
3159
3160void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
3161                                   const InputInfo &Output,
3162                                   const InputInfoList &Inputs,
3163                                   const ArgList &Args,
3164                                   const char *LinkingOutput) const {
3165  const Driver &D = getToolChain().getDriver();
3166  ArgStringList CmdArgs;
3167
3168  if (Args.hasArg(options::OPT_static)) {
3169    CmdArgs.push_back("-Bstatic");
3170  } else {
3171    if (Args.hasArg(options::OPT_shared))
3172      CmdArgs.push_back("-Bshareable");
3173    else {
3174      CmdArgs.push_back("-dynamic-linker");
3175      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
3176    }
3177  }
3178
3179  // When building 32-bit code on DragonFly/pc64, we have to explicitly
3180  // instruct ld in the base system to link 32-bit code.
3181  if (getToolChain().getArchName() == "i386") {
3182    CmdArgs.push_back("-m");
3183    CmdArgs.push_back("elf_i386");
3184  }
3185
3186  if (Output.isFilename()) {
3187    CmdArgs.push_back("-o");
3188    CmdArgs.push_back(Output.getFilename());
3189  } else {
3190    assert(Output.isNothing() && "Invalid output.");
3191  }
3192
3193  if (!Args.hasArg(options::OPT_nostdlib) &&
3194      !Args.hasArg(options::OPT_nostartfiles)) {
3195    if (!Args.hasArg(options::OPT_shared)) {
3196      CmdArgs.push_back(
3197            Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
3198      CmdArgs.push_back(
3199            Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
3200      CmdArgs.push_back(
3201            Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
3202    } else {
3203      CmdArgs.push_back(
3204            Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
3205      CmdArgs.push_back(
3206            Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o")));
3207    }
3208  }
3209
3210  Args.AddAllArgs(CmdArgs, options::OPT_L);
3211  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
3212  Args.AddAllArgs(CmdArgs, options::OPT_e);
3213
3214  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
3215
3216  if (!Args.hasArg(options::OPT_nostdlib) &&
3217      !Args.hasArg(options::OPT_nodefaultlibs)) {
3218    // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
3219    //         rpaths
3220    CmdArgs.push_back("-L/usr/lib/gcc41");
3221
3222    if (!Args.hasArg(options::OPT_static)) {
3223      CmdArgs.push_back("-rpath");
3224      CmdArgs.push_back("/usr/lib/gcc41");
3225
3226      CmdArgs.push_back("-rpath-link");
3227      CmdArgs.push_back("/usr/lib/gcc41");
3228
3229      CmdArgs.push_back("-rpath");
3230      CmdArgs.push_back("/usr/lib");
3231
3232      CmdArgs.push_back("-rpath-link");
3233      CmdArgs.push_back("/usr/lib");
3234    }
3235
3236    if (D.CCCIsCXX) {
3237      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
3238      CmdArgs.push_back("-lm");
3239    }
3240
3241    if (Args.hasArg(options::OPT_shared)) {
3242      CmdArgs.push_back("-lgcc_pic");
3243    } else {
3244      CmdArgs.push_back("-lgcc");
3245    }
3246
3247
3248    if (Args.hasArg(options::OPT_pthread))
3249      CmdArgs.push_back("-lpthread");
3250
3251    if (!Args.hasArg(options::OPT_nolibc)) {
3252      CmdArgs.push_back("-lc");
3253    }
3254
3255    if (Args.hasArg(options::OPT_shared)) {
3256      CmdArgs.push_back("-lgcc_pic");
3257    } else {
3258      CmdArgs.push_back("-lgcc");
3259    }
3260  }
3261
3262  if (!Args.hasArg(options::OPT_nostdlib) &&
3263      !Args.hasArg(options::OPT_nostartfiles)) {
3264    if (!Args.hasArg(options::OPT_shared))
3265      CmdArgs.push_back(Args.MakeArgString(
3266                              getToolChain().GetFilePath("crtend.o")));
3267    else
3268      CmdArgs.push_back(Args.MakeArgString(
3269                              getToolChain().GetFilePath("crtendS.o")));
3270    CmdArgs.push_back(Args.MakeArgString(
3271                              getToolChain().GetFilePath("crtn.o")));
3272  }
3273
3274  const char *Exec =
3275    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
3276  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3277}
3278
3279void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
3280                                      const InputInfo &Output,
3281                                      const InputInfoList &Inputs,
3282                                      const ArgList &Args,
3283                                      const char *LinkingOutput) const {
3284  ArgStringList CmdArgs;
3285
3286  if (Output.isFilename()) {
3287    CmdArgs.push_back(Args.MakeArgString(std::string("-out:") +
3288                                         Output.getFilename()));
3289  } else {
3290    assert(Output.isNothing() && "Invalid output.");
3291  }
3292
3293  if (!Args.hasArg(options::OPT_nostdlib) &&
3294    !Args.hasArg(options::OPT_nostartfiles)) {
3295    CmdArgs.push_back("-defaultlib:libcmt");
3296  }
3297
3298  CmdArgs.push_back("-nologo");
3299
3300  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
3301
3302  const char *Exec =
3303    Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
3304  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3305}
3306