1218893Sdim//===--- Tools.cpp - Tools Implementations --------------------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed
10193326Sed#include "Tools.h"
11249423Sdim#include "InputInfo.h"
12249423Sdim#include "ToolChains.h"
13249423Sdim#include "clang/Basic/ObjCRuntime.h"
14249423Sdim#include "clang/Basic/Version.h"
15193326Sed#include "clang/Driver/Action.h"
16249423Sdim#include "clang/Driver/Compilation.h"
17198893Srdivacky#include "clang/Driver/Driver.h"
18198893Srdivacky#include "clang/Driver/DriverDiagnostic.h"
19193326Sed#include "clang/Driver/Job.h"
20199512Srdivacky#include "clang/Driver/Options.h"
21263508Sdim#include "clang/Driver/SanitizerArgs.h"
22193326Sed#include "clang/Driver/ToolChain.h"
23193326Sed#include "clang/Driver/Util.h"
24263508Sdim#include "clang/Sema/SemaDiagnostic.h"
25198092Srdivacky#include "llvm/ADT/SmallString.h"
26263508Sdim#include "llvm/ADT/StringExtras.h"
27198893Srdivacky#include "llvm/ADT/StringSwitch.h"
28198092Srdivacky#include "llvm/ADT/Twine.h"
29263508Sdim#include "llvm/Option/Arg.h"
30263508Sdim#include "llvm/Option/ArgList.h"
31263508Sdim#include "llvm/Option/Option.h"
32249423Sdim#include "llvm/Support/ErrorHandling.h"
33218893Sdim#include "llvm/Support/FileSystem.h"
34193326Sed#include "llvm/Support/Format.h"
35218893Sdim#include "llvm/Support/Host.h"
36263508Sdim#include "llvm/Support/Path.h"
37263508Sdim#include "llvm/Support/Program.h"
38218893Sdim#include "llvm/Support/Process.h"
39249423Sdim#include "llvm/Support/raw_ostream.h"
40263508Sdim#include <sys/stat.h>
41193326Sed
42193326Sedusing namespace clang::driver;
43193326Sedusing namespace clang::driver::tools;
44226633Sdimusing namespace clang;
45263508Sdimusing namespace llvm::opt;
46193326Sed
47198092Srdivacky/// CheckPreprocessingOptions - Perform some validation of preprocessing
48198092Srdivacky/// arguments that is shared with gcc.
49198092Srdivackystatic void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
50198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
51263508Sdim    if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP())
52226633Sdim      D.Diag(diag::err_drv_argument_only_allowed_with)
53198092Srdivacky        << A->getAsString(Args) << "-E";
54198092Srdivacky}
55198092Srdivacky
56198092Srdivacky/// CheckCodeGenerationOptions - Perform some validation of code generation
57198092Srdivacky/// arguments that is shared with gcc.
58198092Srdivackystatic void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) {
59198092Srdivacky  // In gcc, only ARM checks this, but it seems reasonable to check universally.
60198092Srdivacky  if (Args.hasArg(options::OPT_static))
61198092Srdivacky    if (const Arg *A = Args.getLastArg(options::OPT_dynamic,
62198092Srdivacky                                       options::OPT_mdynamic_no_pic))
63226633Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
64198092Srdivacky        << A->getAsString(Args) << "-static";
65198092Srdivacky}
66198092Srdivacky
67206084Srdivacky// Quote target names for inclusion in GNU Make dependency files.
68206084Srdivacky// Only the characters '$', '#', ' ', '\t' are quoted.
69226633Sdimstatic void QuoteTarget(StringRef Target,
70226633Sdim                        SmallVectorImpl<char> &Res) {
71206084Srdivacky  for (unsigned i = 0, e = Target.size(); i != e; ++i) {
72206084Srdivacky    switch (Target[i]) {
73206084Srdivacky    case ' ':
74206084Srdivacky    case '\t':
75206084Srdivacky      // Escape the preceding backslashes
76206084Srdivacky      for (int j = i - 1; j >= 0 && Target[j] == '\\'; --j)
77206084Srdivacky        Res.push_back('\\');
78206084Srdivacky
79206084Srdivacky      // Escape the space/tab
80206084Srdivacky      Res.push_back('\\');
81206084Srdivacky      break;
82206084Srdivacky    case '$':
83206084Srdivacky      Res.push_back('$');
84206084Srdivacky      break;
85206084Srdivacky    case '#':
86206084Srdivacky      Res.push_back('\\');
87206084Srdivacky      break;
88206084Srdivacky    default:
89206084Srdivacky      break;
90206084Srdivacky    }
91206084Srdivacky
92206084Srdivacky    Res.push_back(Target[i]);
93206084Srdivacky  }
94206084Srdivacky}
95206084Srdivacky
96234353Sdimstatic void addDirectoryList(const ArgList &Args,
97234353Sdim                             ArgStringList &CmdArgs,
98234353Sdim                             const char *ArgName,
99234353Sdim                             const char *EnvVar) {
100234353Sdim  const char *DirList = ::getenv(EnvVar);
101243830Sdim  bool CombinedArg = false;
102243830Sdim
103234353Sdim  if (!DirList)
104234353Sdim    return; // Nothing to do.
105234353Sdim
106243830Sdim  StringRef Name(ArgName);
107243830Sdim  if (Name.equals("-I") || Name.equals("-L"))
108243830Sdim    CombinedArg = true;
109243830Sdim
110234353Sdim  StringRef Dirs(DirList);
111234353Sdim  if (Dirs.empty()) // Empty string should not add '.'.
112234353Sdim    return;
113234353Sdim
114234353Sdim  StringRef::size_type Delim;
115263508Sdim  while ((Delim = Dirs.find(llvm::sys::EnvPathSeparator)) != StringRef::npos) {
116234353Sdim    if (Delim == 0) { // Leading colon.
117243830Sdim      if (CombinedArg) {
118243830Sdim        CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
119243830Sdim      } else {
120243830Sdim        CmdArgs.push_back(ArgName);
121243830Sdim        CmdArgs.push_back(".");
122243830Sdim      }
123234353Sdim    } else {
124243830Sdim      if (CombinedArg) {
125243830Sdim        CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs.substr(0, Delim)));
126243830Sdim      } else {
127243830Sdim        CmdArgs.push_back(ArgName);
128243830Sdim        CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
129243830Sdim      }
130234353Sdim    }
131234353Sdim    Dirs = Dirs.substr(Delim + 1);
132234353Sdim  }
133234353Sdim
134234353Sdim  if (Dirs.empty()) { // Trailing colon.
135243830Sdim    if (CombinedArg) {
136243830Sdim      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + "."));
137243830Sdim    } else {
138243830Sdim      CmdArgs.push_back(ArgName);
139243830Sdim      CmdArgs.push_back(".");
140243830Sdim    }
141234353Sdim  } else { // Add the last path.
142243830Sdim    if (CombinedArg) {
143243830Sdim      CmdArgs.push_back(Args.MakeArgString(std::string(ArgName) + Dirs));
144243830Sdim    } else {
145243830Sdim      CmdArgs.push_back(ArgName);
146243830Sdim      CmdArgs.push_back(Args.MakeArgString(Dirs));
147243830Sdim    }
148234353Sdim  }
149234353Sdim}
150234353Sdim
151218893Sdimstatic void AddLinkerInputs(const ToolChain &TC,
152218893Sdim                            const InputInfoList &Inputs, const ArgList &Args,
153218893Sdim                            ArgStringList &CmdArgs) {
154218893Sdim  const Driver &D = TC.getDriver();
155218893Sdim
156218893Sdim  // Add extra linker input arguments which are not treated as inputs
157218893Sdim  // (constructed via -Xarch_).
158218893Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
159218893Sdim
160218893Sdim  for (InputInfoList::const_iterator
161218893Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
162218893Sdim    const InputInfo &II = *it;
163218893Sdim
164218893Sdim    if (!TC.HasNativeLLVMSupport()) {
165218893Sdim      // Don't try to pass LLVM inputs unless we have native support.
166218893Sdim      if (II.getType() == types::TY_LLVM_IR ||
167218893Sdim          II.getType() == types::TY_LTO_IR ||
168218893Sdim          II.getType() == types::TY_LLVM_BC ||
169218893Sdim          II.getType() == types::TY_LTO_BC)
170226633Sdim        D.Diag(diag::err_drv_no_linker_llvm_support)
171218893Sdim          << TC.getTripleString();
172218893Sdim    }
173218893Sdim
174218893Sdim    // Add filenames immediately.
175218893Sdim    if (II.isFilename()) {
176218893Sdim      CmdArgs.push_back(II.getFilename());
177218893Sdim      continue;
178218893Sdim    }
179218893Sdim
180218893Sdim    // Otherwise, this is a linker input argument.
181218893Sdim    const Arg &A = II.getInputArg();
182218893Sdim
183218893Sdim    // Handle reserved library options.
184218893Sdim    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
185218893Sdim      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
186218893Sdim    } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) {
187218893Sdim      TC.AddCCKextLibArgs(Args, CmdArgs);
188218893Sdim    } else
189218893Sdim      A.renderAsInput(Args, CmdArgs);
190218893Sdim  }
191234353Sdim
192234353Sdim  // LIBRARY_PATH - included following the user specified library paths.
193234353Sdim  addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
194218893Sdim}
195218893Sdim
196224145Sdim/// \brief Determine whether Objective-C automated reference counting is
197224145Sdim/// enabled.
198224145Sdimstatic bool isObjCAutoRefCount(const ArgList &Args) {
199224145Sdim  return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false);
200224145Sdim}
201224145Sdim
202234353Sdim/// \brief Determine whether we are linking the ObjC runtime.
203234353Sdimstatic bool isObjCRuntimeLinked(const ArgList &Args) {
204239462Sdim  if (isObjCAutoRefCount(Args)) {
205239462Sdim    Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
206234353Sdim    return true;
207239462Sdim  }
208234353Sdim  return Args.hasArg(options::OPT_fobjc_link_runtime);
209234353Sdim}
210234353Sdim
211223017Sdimstatic void addProfileRT(const ToolChain &TC, const ArgList &Args,
212224145Sdim                         ArgStringList &CmdArgs,
213224145Sdim                         llvm::Triple Triple) {
214224145Sdim  if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
215224145Sdim        Args.hasArg(options::OPT_fprofile_generate) ||
216224145Sdim        Args.hasArg(options::OPT_fcreate_profile) ||
217224145Sdim        Args.hasArg(options::OPT_coverage)))
218224145Sdim    return;
219224145Sdim
220224145Sdim  // GCC links libgcov.a by adding -L<inst>/gcc/lib/gcc/<triple>/<ver> -lgcov to
221224145Sdim  // the link line. We cannot do the same thing because unlike gcov there is a
222224145Sdim  // libprofile_rt.so. We used to use the -l:libprofile_rt.a syntax, but that is
223224145Sdim  // not supported by old linkers.
224234353Sdim  std::string ProfileRT =
225234353Sdim    std::string(TC.getDriver().Dir) + "/../lib/libprofile_rt.a";
226224145Sdim
227224145Sdim  CmdArgs.push_back(Args.MakeArgString(ProfileRT));
228223017Sdim}
229223017Sdim
230243830Sdimstatic bool forwardToGCC(const Option &O) {
231263508Sdim  // Don't forward inputs from the original command line.  They are added from
232263508Sdim  // InputInfoList.
233263508Sdim  return O.getKind() != Option::InputClass &&
234243830Sdim         !O.hasFlag(options::DriverOption) &&
235243830Sdim         !O.hasFlag(options::LinkerInput);
236243830Sdim}
237243830Sdim
238234353Sdimvoid Clang::AddPreprocessingOptions(Compilation &C,
239249423Sdim                                    const JobAction &JA,
240234353Sdim                                    const Driver &D,
241193326Sed                                    const ArgList &Args,
242193326Sed                                    ArgStringList &CmdArgs,
243193326Sed                                    const InputInfo &Output,
244193326Sed                                    const InputInfoList &Inputs) const {
245194179Sed  Arg *A;
246194179Sed
247198092Srdivacky  CheckPreprocessingOptions(D, Args);
248194179Sed
249198092Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_C);
250198092Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_CC);
251198092Srdivacky
252193326Sed  // Handle dependency file generation.
253218893Sdim  if ((A = Args.getLastArg(options::OPT_M, options::OPT_MM)) ||
254193326Sed      (A = Args.getLastArg(options::OPT_MD)) ||
255193326Sed      (A = Args.getLastArg(options::OPT_MMD))) {
256193326Sed    // Determine the output location.
257193326Sed    const char *DepFile;
258241163Sdim    if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
259243830Sdim      DepFile = MF->getValue();
260249423Sdim      C.addFailureResultFile(DepFile, &JA);
261241163Sdim    } else if (Output.getType() == types::TY_Dependencies) {
262241163Sdim      DepFile = Output.getFilename();
263199512Srdivacky    } else if (A->getOption().matches(options::OPT_M) ||
264199512Srdivacky               A->getOption().matches(options::OPT_MM)) {
265193326Sed      DepFile = "-";
266193326Sed    } else {
267249423Sdim      DepFile = getDependencyFileName(Args, Inputs);
268249423Sdim      C.addFailureResultFile(DepFile, &JA);
269193326Sed    }
270193326Sed    CmdArgs.push_back("-dependency-file");
271193326Sed    CmdArgs.push_back(DepFile);
272193326Sed
273206084Srdivacky    // Add a default target if one wasn't specified.
274193326Sed    if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) {
275193326Sed      const char *DepTarget;
276193326Sed
277193326Sed      // If user provided -o, that is the dependency target, except
278193326Sed      // when we are only generating a dependency file.
279193326Sed      Arg *OutputOpt = Args.getLastArg(options::OPT_o);
280193326Sed      if (OutputOpt && Output.getType() != types::TY_Dependencies) {
281243830Sdim        DepTarget = OutputOpt->getValue();
282193326Sed      } else {
283193326Sed        // Otherwise derive from the base input.
284193326Sed        //
285193326Sed        // FIXME: This should use the computed output file location.
286234353Sdim        SmallString<128> P(Inputs[0].getBaseInput());
287218893Sdim        llvm::sys::path::replace_extension(P, "o");
288218893Sdim        DepTarget = Args.MakeArgString(llvm::sys::path::filename(P));
289193326Sed      }
290193326Sed
291193326Sed      CmdArgs.push_back("-MT");
292234353Sdim      SmallString<128> Quoted;
293206084Srdivacky      QuoteTarget(DepTarget, Quoted);
294206084Srdivacky      CmdArgs.push_back(Args.MakeArgString(Quoted));
295193326Sed    }
296193326Sed
297199512Srdivacky    if (A->getOption().matches(options::OPT_M) ||
298199512Srdivacky        A->getOption().matches(options::OPT_MD))
299193326Sed      CmdArgs.push_back("-sys-header-deps");
300193326Sed  }
301193326Sed
302224145Sdim  if (Args.hasArg(options::OPT_MG)) {
303224145Sdim    if (!A || A->getOption().matches(options::OPT_MD) ||
304224145Sdim              A->getOption().matches(options::OPT_MMD))
305226633Sdim      D.Diag(diag::err_drv_mg_requires_m_or_mm);
306224145Sdim    CmdArgs.push_back("-MG");
307224145Sdim  }
308224145Sdim
309193326Sed  Args.AddLastArg(CmdArgs, options::OPT_MP);
310193326Sed
311206084Srdivacky  // Convert all -MQ <target> args to -MT <quoted target>
312206084Srdivacky  for (arg_iterator it = Args.filtered_begin(options::OPT_MT,
313206084Srdivacky                                             options::OPT_MQ),
314206084Srdivacky         ie = Args.filtered_end(); it != ie; ++it) {
315210299Sed    const Arg *A = *it;
316210299Sed    A->claim();
317206084Srdivacky
318210299Sed    if (A->getOption().matches(options::OPT_MQ)) {
319206084Srdivacky      CmdArgs.push_back("-MT");
320234353Sdim      SmallString<128> Quoted;
321243830Sdim      QuoteTarget(A->getValue(), Quoted);
322206084Srdivacky      CmdArgs.push_back(Args.MakeArgString(Quoted));
323206084Srdivacky
324206084Srdivacky    // -MT flag - no change
325206084Srdivacky    } else {
326210299Sed      A->render(Args, CmdArgs);
327206084Srdivacky    }
328206084Srdivacky  }
329206084Srdivacky
330193326Sed  // Add -i* options, and automatically translate to
331193326Sed  // -include-pch/-include-pth for transparent PCH support. It's
332193326Sed  // wonky, but we include looking for .gch so we can support seamless
333193326Sed  // replacement into a build system already set up to be generating
334193326Sed  // .gch files.
335218893Sdim  bool RenderedImplicitInclude = false;
336199990Srdivacky  for (arg_iterator it = Args.filtered_begin(options::OPT_clang_i_Group),
337199990Srdivacky         ie = Args.filtered_end(); it != ie; ++it) {
338199990Srdivacky    const Arg *A = it;
339193326Sed
340193326Sed    if (A->getOption().matches(options::OPT_include)) {
341218893Sdim      bool IsFirstImplicitInclude = !RenderedImplicitInclude;
342218893Sdim      RenderedImplicitInclude = true;
343218893Sdim
344212904Sdim      // Use PCH if the user requested it.
345198398Srdivacky      bool UsePCH = D.CCCUsePCH;
346198398Srdivacky
347193326Sed      bool FoundPTH = false;
348193326Sed      bool FoundPCH = false;
349263508Sdim      SmallString<128> P(A->getValue());
350263508Sdim      // We want the files to have a name like foo.h.pch. Add a dummy extension
351263508Sdim      // so that replace_extension does the right thing.
352263508Sdim      P += ".dummy";
353198398Srdivacky      if (UsePCH) {
354263508Sdim        llvm::sys::path::replace_extension(P, "pch");
355263508Sdim        if (llvm::sys::fs::exists(P.str()))
356193326Sed          FoundPCH = true;
357193326Sed      }
358193326Sed
359193326Sed      if (!FoundPCH) {
360263508Sdim        llvm::sys::path::replace_extension(P, "pth");
361263508Sdim        if (llvm::sys::fs::exists(P.str()))
362193326Sed          FoundPTH = true;
363198092Srdivacky      }
364198092Srdivacky
365193326Sed      if (!FoundPCH && !FoundPTH) {
366263508Sdim        llvm::sys::path::replace_extension(P, "gch");
367263508Sdim        if (llvm::sys::fs::exists(P.str())) {
368198398Srdivacky          FoundPCH = UsePCH;
369198398Srdivacky          FoundPTH = !UsePCH;
370193326Sed        }
371193326Sed      }
372193326Sed
373193326Sed      if (FoundPCH || FoundPTH) {
374218893Sdim        if (IsFirstImplicitInclude) {
375218893Sdim          A->claim();
376218893Sdim          if (UsePCH)
377218893Sdim            CmdArgs.push_back("-include-pch");
378218893Sdim          else
379218893Sdim            CmdArgs.push_back("-include-pth");
380218893Sdim          CmdArgs.push_back(Args.MakeArgString(P.str()));
381218893Sdim          continue;
382218893Sdim        } else {
383218893Sdim          // Ignore the PCH if not first on command line and emit warning.
384226633Sdim          D.Diag(diag::warn_drv_pch_not_first_include)
385218893Sdim              << P.str() << A->getAsString(Args);
386218893Sdim        }
387193326Sed      }
388193326Sed    }
389193326Sed
390193326Sed    // Not translated, render as usual.
391193326Sed    A->claim();
392193326Sed    A->render(Args, CmdArgs);
393193326Sed  }
394193326Sed
395193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
396226633Sdim  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
397226633Sdim                  options::OPT_index_header_map);
398193326Sed
399193326Sed  // Add -Wp, and -Xassembler if using the preprocessor.
400193326Sed
401193326Sed  // FIXME: There is a very unfortunate problem here, some troubled
402193326Sed  // souls abuse -Wp, to pass preprocessor options in gcc syntax. To
403193326Sed  // really support that we would have to parse and then translate
404193326Sed  // those options. :(
405193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wp_COMMA,
406193326Sed                       options::OPT_Xpreprocessor);
407198893Srdivacky
408198893Srdivacky  // -I- is a deprecated GCC feature, reject it.
409198893Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_I_))
410226633Sdim    D.Diag(diag::err_drv_I_dash_not_supported) << A->getAsString(Args);
411218893Sdim
412218893Sdim  // If we have a --sysroot, and don't have an explicit -isysroot flag, add an
413218893Sdim  // -isysroot to the CC1 invocation.
414234982Sdim  StringRef sysroot = C.getSysRoot();
415234982Sdim  if (sysroot != "") {
416218893Sdim    if (!Args.hasArg(options::OPT_isysroot)) {
417218893Sdim      CmdArgs.push_back("-isysroot");
418234982Sdim      CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
419218893Sdim    }
420218893Sdim  }
421249423Sdim
422226633Sdim  // Parse additional include paths from environment variables.
423234353Sdim  // FIXME: We should probably sink the logic for handling these from the
424234353Sdim  // frontend into the driver. It will allow deleting 4 otherwise unused flags.
425226633Sdim  // CPATH - included following the user specified includes (but prior to
426226633Sdim  // builtin and standard includes).
427234353Sdim  addDirectoryList(Args, CmdArgs, "-I", "CPATH");
428226633Sdim  // C_INCLUDE_PATH - system includes enabled when compiling C.
429234353Sdim  addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
430226633Sdim  // CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
431234353Sdim  addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
432226633Sdim  // OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
433234353Sdim  addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
434226633Sdim  // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
435234353Sdim  addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
436228379Sdim
437228379Sdim  // Add C++ include arguments, if needed.
438228379Sdim  if (types::isCXX(Inputs[0].getType()))
439228379Sdim    getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
440228379Sdim
441228379Sdim  // Add system include arguments.
442228379Sdim  getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
443193326Sed}
444193326Sed
445239462Sdim/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
446239462Sdim/// CPU.
447239462Sdim//
448239462Sdim// FIXME: This is redundant with -mcpu, why does LLVM use this.
449239462Sdim// FIXME: tblgen this, or kill it!
450239462Sdimstatic const char *getLLVMArchSuffixForARM(StringRef CPU) {
451239462Sdim  return llvm::StringSwitch<const char *>(CPU)
452263508Sdim    .Case("strongarm", "v4")
453239462Sdim    .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
454239462Sdim    .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
455239462Sdim    .Cases("arm920", "arm920t", "arm922t", "v4t")
456239462Sdim    .Cases("arm940t", "ep9312","v4t")
457239462Sdim    .Cases("arm10tdmi",  "arm1020t", "v5")
458239462Sdim    .Cases("arm9e",  "arm926ej-s",  "arm946e-s", "v5e")
459239462Sdim    .Cases("arm966e-s",  "arm968e-s",  "arm10e", "v5e")
460239462Sdim    .Cases("arm1020e",  "arm1022e",  "xscale", "iwmmxt", "v5e")
461239462Sdim    .Cases("arm1136j-s",  "arm1136jf-s",  "arm1176jz-s", "v6")
462239462Sdim    .Cases("arm1176jzf-s",  "mpcorenovfp",  "mpcore", "v6")
463239462Sdim    .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
464249423Sdim    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
465263508Sdim    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "v7")
466263508Sdim    .Cases("cortex-r4", "cortex-r5", "v7r")
467249423Sdim    .Case("cortex-m0", "v6m")
468239462Sdim    .Case("cortex-m3", "v7m")
469249423Sdim    .Case("cortex-m4", "v7em")
470243830Sdim    .Case("cortex-a9-mp", "v7f")
471243830Sdim    .Case("swift", "v7s")
472263508Sdim    .Cases("cortex-a53", "cortex-a57", "v8")
473239462Sdim    .Default("");
474239462Sdim}
475239462Sdim
476221345Sdim/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
477198092Srdivacky//
478198092Srdivacky// FIXME: tblgen this.
479239462Sdimstatic std::string getARMTargetCPU(const ArgList &Args,
480210299Sed                                   const llvm::Triple &Triple) {
481198092Srdivacky  // FIXME: Warn on inconsistent use of -mcpu and -march.
482198092Srdivacky
483198092Srdivacky  // If we have -mcpu=, use that.
484239462Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
485243830Sdim    StringRef MCPU = A->getValue();
486239462Sdim    // Handle -mcpu=native.
487239462Sdim    if (MCPU == "native")
488239462Sdim      return llvm::sys::getHostCPUName();
489239462Sdim    else
490239462Sdim      return MCPU;
491239462Sdim  }
492198092Srdivacky
493226633Sdim  StringRef MArch;
494198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
495210299Sed    // Otherwise, if we have -march= choose the base CPU for that arch.
496243830Sdim    MArch = A->getValue();
497210299Sed  } else {
498210299Sed    // Otherwise, use the Arch from the triple.
499210299Sed    MArch = Triple.getArchName();
500198092Srdivacky  }
501198092Srdivacky
502270072Sian  if (Triple.getOS() == llvm::Triple::NetBSD ||
503270072Sian      Triple.getOS() == llvm::Triple::FreeBSD) {
504263508Sdim    if (MArch == "armv6")
505263508Sdim      return "arm1176jzf-s";
506263508Sdim  }
507263508Sdim
508239462Sdim  // Handle -march=native.
509239462Sdim  std::string NativeMArch;
510239462Sdim  if (MArch == "native") {
511239462Sdim    std::string CPU = llvm::sys::getHostCPUName();
512239462Sdim    if (CPU != "generic") {
513239462Sdim      // Translate the native cpu into the architecture. The switch below will
514239462Sdim      // then chose the minimum cpu for that arch.
515239462Sdim      NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU);
516239462Sdim      MArch = NativeMArch;
517239462Sdim    }
518239462Sdim  }
519239462Sdim
520226633Sdim  return llvm::StringSwitch<const char *>(MArch)
521226633Sdim    .Cases("armv2", "armv2a","arm2")
522226633Sdim    .Case("armv3", "arm6")
523226633Sdim    .Case("armv3m", "arm7m")
524263508Sdim    .Case("armv4", "strongarm")
525263508Sdim    .Case("armv4t", "arm7tdmi")
526226633Sdim    .Cases("armv5", "armv5t", "arm10tdmi")
527239462Sdim    .Cases("armv5e", "armv5te", "arm1022e")
528226633Sdim    .Case("armv5tej", "arm926ej-s")
529226633Sdim    .Cases("armv6", "armv6k", "arm1136jf-s")
530226633Sdim    .Case("armv6j", "arm1136j-s")
531226633Sdim    .Cases("armv6z", "armv6zk", "arm1176jzf-s")
532226633Sdim    .Case("armv6t2", "arm1156t2-s")
533249423Sdim    .Cases("armv6m", "armv6-m", "cortex-m0")
534226633Sdim    .Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
535249423Sdim    .Cases("armv7em", "armv7e-m", "cortex-m4")
536243830Sdim    .Cases("armv7f", "armv7-f", "cortex-a9-mp")
537243830Sdim    .Cases("armv7s", "armv7-s", "swift")
538226633Sdim    .Cases("armv7r", "armv7-r", "cortex-r4")
539226633Sdim    .Cases("armv7m", "armv7-m", "cortex-m3")
540263508Sdim    .Cases("armv8", "armv8a", "armv8-a", "cortex-a53")
541226633Sdim    .Case("ep9312", "ep9312")
542226633Sdim    .Case("iwmmxt", "iwmmxt")
543226633Sdim    .Case("xscale", "xscale")
544263508Sdim    // If all else failed, return the most base CPU with thumb interworking
545263508Sdim    // supported by LLVM.
546226633Sdim    .Default("arm7tdmi");
547198092Srdivacky}
548198092Srdivacky
549263508Sdim/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are targeting.
550263508Sdim//
551263508Sdim// FIXME: tblgen this.
552263508Sdimstatic std::string getAArch64TargetCPU(const ArgList &Args,
553263508Sdim                                       const llvm::Triple &Triple) {
554263508Sdim  // FIXME: Warn on inconsistent use of -mcpu and -march.
555263508Sdim
556263508Sdim  // If we have -mcpu=, use that.
557263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
558263508Sdim    StringRef MCPU = A->getValue();
559263508Sdim    // Handle -mcpu=native.
560263508Sdim    if (MCPU == "native")
561263508Sdim      return llvm::sys::getHostCPUName();
562263508Sdim    else
563263508Sdim      return MCPU;
564263508Sdim  }
565263508Sdim
566263508Sdim  return "generic";
567263508Sdim}
568263508Sdim
569199482Srdivacky// FIXME: Move to target hook.
570199482Srdivackystatic bool isSignedCharDefault(const llvm::Triple &Triple) {
571199482Srdivacky  switch (Triple.getArch()) {
572199482Srdivacky  default:
573199482Srdivacky    return true;
574199482Srdivacky
575249423Sdim  case llvm::Triple::aarch64:
576223017Sdim  case llvm::Triple::arm:
577199482Srdivacky  case llvm::Triple::ppc:
578199482Srdivacky  case llvm::Triple::ppc64:
579226633Sdim    if (Triple.isOSDarwin())
580199482Srdivacky      return true;
581199482Srdivacky    return false;
582251662Sdim
583263508Sdim  case llvm::Triple::ppc64le:
584251662Sdim  case llvm::Triple::systemz:
585263508Sdim  case llvm::Triple::xcore:
586251662Sdim    return false;
587199482Srdivacky  }
588199482Srdivacky}
589199482Srdivacky
590263508Sdimstatic bool isNoCommonDefault(const llvm::Triple &Triple) {
591263508Sdim  switch (Triple.getArch()) {
592263508Sdim  default:
593263508Sdim    return false;
594263508Sdim
595263508Sdim  case llvm::Triple::xcore:
596263508Sdim    return true;
597263508Sdim  }
598263508Sdim}
599263508Sdim
600234353Sdim// Handle -mfpu=.
601234353Sdim//
602234353Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the
603234353Sdim// frontend target.
604263508Sdimstatic void getAArch64FPUFeatures(const Driver &D, const Arg *A,
605263508Sdim                                  const ArgList &Args,
606263508Sdim                                  std::vector<const char *> &Features) {
607243830Sdim  StringRef FPU = A->getValue();
608263508Sdim  if (FPU == "fp-armv8") {
609263508Sdim    Features.push_back("+fp-armv8");
610263508Sdim  } else if (FPU == "neon-fp-armv8") {
611263508Sdim    Features.push_back("+fp-armv8");
612263508Sdim    Features.push_back("+neon");
613263508Sdim  } else if (FPU == "crypto-neon-fp-armv8") {
614263508Sdim    Features.push_back("+fp-armv8");
615263508Sdim    Features.push_back("+neon");
616263508Sdim    Features.push_back("+crypto");
617263508Sdim  } else if (FPU == "neon") {
618263508Sdim    Features.push_back("+neon");
619263508Sdim  } else if (FPU == "none") {
620263508Sdim    Features.push_back("-fp-armv8");
621263508Sdim    Features.push_back("-crypto");
622263508Sdim    Features.push_back("-neon");
623263508Sdim  } else
624263508Sdim    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
625263508Sdim}
626198092Srdivacky
627263508Sdim// Handle -mhwdiv=.
628263508Sdimstatic void getARMHWDivFeatures(const Driver &D, const Arg *A,
629263508Sdim                              const ArgList &Args,
630263508Sdim                              std::vector<const char *> &Features) {
631263508Sdim  StringRef HWDiv = A->getValue();
632263508Sdim  if (HWDiv == "arm") {
633263508Sdim    Features.push_back("+hwdiv-arm");
634263508Sdim    Features.push_back("-hwdiv");
635263508Sdim  } else if (HWDiv == "thumb") {
636263508Sdim    Features.push_back("-hwdiv-arm");
637263508Sdim    Features.push_back("+hwdiv");
638263508Sdim  } else if (HWDiv == "arm,thumb" || HWDiv == "thumb,arm") {
639263508Sdim    Features.push_back("+hwdiv-arm");
640263508Sdim    Features.push_back("+hwdiv");
641263508Sdim  } else if (HWDiv == "none") {
642263508Sdim    Features.push_back("-hwdiv-arm");
643263508Sdim    Features.push_back("-hwdiv");
644263508Sdim  } else
645263508Sdim    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
646263508Sdim}
647263508Sdim
648263508Sdim// Handle -mfpu=.
649263508Sdim//
650263508Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the
651263508Sdim// frontend target.
652263508Sdimstatic void getARMFPUFeatures(const Driver &D, const Arg *A,
653263508Sdim                              const ArgList &Args,
654263508Sdim                              std::vector<const char *> &Features) {
655263508Sdim  StringRef FPU = A->getValue();
656263508Sdim
657234353Sdim  // Set the target features based on the FPU.
658234353Sdim  if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
659234353Sdim    // Disable any default FPU support.
660263508Sdim    Features.push_back("-vfp2");
661263508Sdim    Features.push_back("-vfp3");
662263508Sdim    Features.push_back("-neon");
663234353Sdim  } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") {
664263508Sdim    Features.push_back("+vfp3");
665263508Sdim    Features.push_back("+d16");
666263508Sdim    Features.push_back("-neon");
667234353Sdim  } else if (FPU == "vfp") {
668263508Sdim    Features.push_back("+vfp2");
669263508Sdim    Features.push_back("-neon");
670234353Sdim  } else if (FPU == "vfp3" || FPU == "vfpv3") {
671263508Sdim    Features.push_back("+vfp3");
672263508Sdim    Features.push_back("-neon");
673263508Sdim  } else if (FPU == "fp-armv8") {
674263508Sdim    Features.push_back("+fp-armv8");
675263508Sdim    Features.push_back("-neon");
676263508Sdim    Features.push_back("-crypto");
677263508Sdim  } else if (FPU == "neon-fp-armv8") {
678263508Sdim    Features.push_back("+fp-armv8");
679263508Sdim    Features.push_back("+neon");
680263508Sdim    Features.push_back("-crypto");
681263508Sdim  } else if (FPU == "crypto-neon-fp-armv8") {
682263508Sdim    Features.push_back("+fp-armv8");
683263508Sdim    Features.push_back("+neon");
684263508Sdim    Features.push_back("+crypto");
685234353Sdim  } else if (FPU == "neon") {
686263508Sdim    Features.push_back("+neon");
687263508Sdim  } else if (FPU == "none") {
688263508Sdim    Features.push_back("-vfp2");
689263508Sdim    Features.push_back("-vfp3");
690263508Sdim    Features.push_back("-vfp4");
691263508Sdim    Features.push_back("-fp-armv8");
692263508Sdim    Features.push_back("-crypto");
693263508Sdim    Features.push_back("-neon");
694234353Sdim  } else
695234353Sdim    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
696234353Sdim}
697198092Srdivacky
698234353Sdim// Select the float ABI as determined by -msoft-float, -mhard-float, and
699234353Sdim// -mfloat-abi=.
700234353Sdimstatic StringRef getARMFloatABI(const Driver &D,
701234353Sdim                                const ArgList &Args,
702234353Sdim                                const llvm::Triple &Triple) {
703226633Sdim  StringRef FloatABI;
704198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
705198092Srdivacky                               options::OPT_mhard_float,
706198092Srdivacky                               options::OPT_mfloat_abi_EQ)) {
707198092Srdivacky    if (A->getOption().matches(options::OPT_msoft_float))
708198092Srdivacky      FloatABI = "soft";
709198092Srdivacky    else if (A->getOption().matches(options::OPT_mhard_float))
710198092Srdivacky      FloatABI = "hard";
711198092Srdivacky    else {
712243830Sdim      FloatABI = A->getValue();
713198092Srdivacky      if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
714226633Sdim        D.Diag(diag::err_drv_invalid_mfloat_abi)
715198092Srdivacky          << A->getAsString(Args);
716198092Srdivacky        FloatABI = "soft";
717198092Srdivacky      }
718198092Srdivacky    }
719198092Srdivacky  }
720198092Srdivacky
721198092Srdivacky  // If unspecified, choose the default based on the platform.
722198092Srdivacky  if (FloatABI.empty()) {
723210299Sed    switch (Triple.getOS()) {
724226633Sdim    case llvm::Triple::Darwin:
725226633Sdim    case llvm::Triple::MacOSX:
726226633Sdim    case llvm::Triple::IOS: {
727198092Srdivacky      // Darwin defaults to "softfp" for v6 and v7.
728198092Srdivacky      //
729198092Srdivacky      // FIXME: Factor out an ARM class so we can cache the arch somewhere.
730239462Sdim      std::string ArchName =
731210299Sed        getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
732239462Sdim      if (StringRef(ArchName).startswith("v6") ||
733239462Sdim          StringRef(ArchName).startswith("v7"))
734198092Srdivacky        FloatABI = "softfp";
735198092Srdivacky      else
736198092Srdivacky        FloatABI = "soft";
737198092Srdivacky      break;
738198092Srdivacky    }
739198092Srdivacky
740244640Sandrew    case llvm::Triple::FreeBSD:
741244640Sandrew      // FreeBSD defaults to soft float
742244640Sandrew      FloatABI = "soft";
743244640Sandrew      break;
744244640Sandrew
745198092Srdivacky    default:
746218893Sdim      switch(Triple.getEnvironment()) {
747239462Sdim      case llvm::Triple::GNUEABIHF:
748239462Sdim        FloatABI = "hard";
749239462Sdim        break;
750218893Sdim      case llvm::Triple::GNUEABI:
751218893Sdim        FloatABI = "softfp";
752218893Sdim        break;
753218893Sdim      case llvm::Triple::EABI:
754218893Sdim        // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
755218893Sdim        FloatABI = "softfp";
756218893Sdim        break;
757243830Sdim      case llvm::Triple::Android: {
758239462Sdim        std::string ArchName =
759234353Sdim          getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
760239462Sdim        if (StringRef(ArchName).startswith("v7"))
761234353Sdim          FloatABI = "softfp";
762234353Sdim        else
763234353Sdim          FloatABI = "soft";
764234353Sdim        break;
765234353Sdim      }
766218893Sdim      default:
767218893Sdim        // Assume "soft", but warn the user we are guessing.
768218893Sdim        FloatABI = "soft";
769226633Sdim        D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
770218893Sdim        break;
771218893Sdim      }
772198092Srdivacky    }
773198092Srdivacky  }
774198092Srdivacky
775234353Sdim  return FloatABI;
776234353Sdim}
777234353Sdim
778263508Sdimstatic void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
779263508Sdim                                 const ArgList &Args,
780263508Sdim                                 std::vector<const char *> &Features) {
781263508Sdim  StringRef FloatABI = getARMFloatABI(D, Args, Triple);
782263508Sdim  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
783263508Sdim  // yet (it uses the -mfloat-abi and -msoft-float options), and it is
784263508Sdim  // stripped out by the ARM target.
785263508Sdim  // Use software floating point operations?
786263508Sdim  if (FloatABI == "soft")
787263508Sdim    Features.push_back("+soft-float");
788234353Sdim
789263508Sdim  // Use software floating point argument passing?
790263508Sdim  if (FloatABI != "hard")
791263508Sdim    Features.push_back("+soft-float-abi");
792263508Sdim
793263508Sdim  // Honor -mfpu=.
794263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
795263508Sdim    getARMFPUFeatures(D, A, Args, Features);
796263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
797263508Sdim    getARMHWDivFeatures(D, A, Args, Features);
798263508Sdim
799263508Sdim  // Setting -msoft-float effectively disables NEON because of the GCC
800263508Sdim  // implementation, although the same isn't true of VFP or VFP3.
801263508Sdim  if (FloatABI == "soft")
802263508Sdim    Features.push_back("-neon");
803263508Sdim
804263508Sdim  // En/disable crc
805263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcrc,
806263508Sdim                               options::OPT_mnocrc)) {
807263508Sdim    if (A->getOption().matches(options::OPT_mcrc))
808263508Sdim      Features.push_back("+crc");
809263508Sdim    else
810263508Sdim      Features.push_back("-crc");
811263508Sdim  }
812263508Sdim}
813263508Sdim
814234353Sdimvoid Clang::AddARMTargetArgs(const ArgList &Args,
815234353Sdim                             ArgStringList &CmdArgs,
816234353Sdim                             bool KernelOrKext) const {
817234353Sdim  const Driver &D = getToolChain().getDriver();
818243830Sdim  // Get the effective triple, which takes into account the deployment target.
819243830Sdim  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
820243830Sdim  llvm::Triple Triple(TripleStr);
821243830Sdim  std::string CPUName = getARMTargetCPU(Args, Triple);
822234353Sdim
823234353Sdim  // Select the ABI to use.
824234353Sdim  //
825234353Sdim  // FIXME: Support -meabi.
826234353Sdim  const char *ABIName = 0;
827234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
828243830Sdim    ABIName = A->getValue();
829243830Sdim  } else if (Triple.isOSDarwin()) {
830243830Sdim    // The backend is hardwired to assume AAPCS for M-class processors, ensure
831243830Sdim    // the frontend matches that.
832263508Sdim    if (Triple.getEnvironment() == llvm::Triple::EABI ||
833263508Sdim        StringRef(CPUName).startswith("cortex-m")) {
834243830Sdim      ABIName = "aapcs";
835243830Sdim    } else {
836243830Sdim      ABIName = "apcs-gnu";
837243830Sdim    }
838234353Sdim  } else {
839234353Sdim    // Select the default based on the platform.
840234353Sdim    switch(Triple.getEnvironment()) {
841243830Sdim    case llvm::Triple::Android:
842234353Sdim    case llvm::Triple::GNUEABI:
843239462Sdim    case llvm::Triple::GNUEABIHF:
844234353Sdim      ABIName = "aapcs-linux";
845234353Sdim      break;
846234353Sdim    case llvm::Triple::EABI:
847234353Sdim      ABIName = "aapcs";
848234353Sdim      break;
849234353Sdim    default:
850234353Sdim      ABIName = "apcs-gnu";
851234353Sdim    }
852234353Sdim  }
853234353Sdim  CmdArgs.push_back("-target-abi");
854234353Sdim  CmdArgs.push_back(ABIName);
855234353Sdim
856234353Sdim  // Determine floating point ABI from the options & target defaults.
857234353Sdim  StringRef FloatABI = getARMFloatABI(D, Args, Triple);
858198092Srdivacky  if (FloatABI == "soft") {
859198092Srdivacky    // Floating point operations and argument passing are soft.
860198092Srdivacky    //
861198092Srdivacky    // FIXME: This changes CPP defines, we need -target-soft-float.
862199990Srdivacky    CmdArgs.push_back("-msoft-float");
863200583Srdivacky    CmdArgs.push_back("-mfloat-abi");
864200583Srdivacky    CmdArgs.push_back("soft");
865198092Srdivacky  } else if (FloatABI == "softfp") {
866198092Srdivacky    // Floating point operations are hard, but argument passing is soft.
867200583Srdivacky    CmdArgs.push_back("-mfloat-abi");
868200583Srdivacky    CmdArgs.push_back("soft");
869198092Srdivacky  } else {
870198092Srdivacky    // Floating point operations and argument passing are hard.
871198092Srdivacky    assert(FloatABI == "hard" && "Invalid float abi!");
872200583Srdivacky    CmdArgs.push_back("-mfloat-abi");
873200583Srdivacky    CmdArgs.push_back("hard");
874198092Srdivacky  }
875201361Srdivacky
876221345Sdim  // Kernel code has more strict alignment requirements.
877221345Sdim  if (KernelOrKext) {
878263508Sdim    if (!Triple.isiOS() || Triple.isOSVersionLT(6)) {
879243830Sdim      CmdArgs.push_back("-backend-option");
880243830Sdim      CmdArgs.push_back("-arm-long-calls");
881243830Sdim    }
882221345Sdim
883221345Sdim    CmdArgs.push_back("-backend-option");
884221345Sdim    CmdArgs.push_back("-arm-strict-align");
885221345Sdim
886221345Sdim    // The kext linker doesn't know how to deal with movw/movt.
887221345Sdim    CmdArgs.push_back("-backend-option");
888263508Sdim    CmdArgs.push_back("-arm-use-movt=0");
889221345Sdim  }
890226633Sdim
891226633Sdim  // Setting -mno-global-merge disables the codegen global merge pass. Setting
892226633Sdim  // -mglobal-merge has no effect as the pass is enabled by default.
893226633Sdim  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
894226633Sdim                               options::OPT_mno_global_merge)) {
895226633Sdim    if (A->getOption().matches(options::OPT_mno_global_merge))
896226633Sdim      CmdArgs.push_back("-mno-global-merge");
897226633Sdim  }
898239462Sdim
899251662Sdim  if (!Args.hasFlag(options::OPT_mimplicit_float,
900251662Sdim                    options::OPT_mno_implicit_float,
901251662Sdim                    true))
902239462Sdim    CmdArgs.push_back("-no-implicit-float");
903198092Srdivacky
904263508Sdim    // llvm does not support reserving registers in general. There is support
905263508Sdim    // for reserving r9 on ARM though (defined as a platform-specific register
906263508Sdim    // in ARM EABI).
907263508Sdim    if (Args.hasArg(options::OPT_ffixed_r9)) {
908263508Sdim      CmdArgs.push_back("-backend-option");
909263508Sdim      CmdArgs.push_back("-arm-reserve-r9");
910263508Sdim    }
911226633Sdim}
912226633Sdim
913234353Sdim// Get CPU and ABI names. They are not independent
914234353Sdim// so we have to calculate them together.
915234353Sdimstatic void getMipsCPUAndABI(const ArgList &Args,
916263508Sdim                             const llvm::Triple &Triple,
917234353Sdim                             StringRef &CPUName,
918234353Sdim                             StringRef &ABIName) {
919243830Sdim  const char *DefMips32CPU = "mips32";
920243830Sdim  const char *DefMips64CPU = "mips64";
921226633Sdim
922243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
923263508Sdim                               options::OPT_mcpu_EQ))
924263508Sdim    CPUName = A->getValue();
925243830Sdim
926251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
927243830Sdim    ABIName = A->getValue();
928251662Sdim    // Convert a GNU style Mips ABI name to the name
929251662Sdim    // accepted by LLVM Mips backend.
930251662Sdim    ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
931251662Sdim      .Case("32", "o32")
932251662Sdim      .Case("64", "n64")
933251662Sdim      .Default(ABIName);
934251662Sdim  }
935243830Sdim
936243830Sdim  // Setup default CPU and ABI names.
937243830Sdim  if (CPUName.empty() && ABIName.empty()) {
938263508Sdim    switch (Triple.getArch()) {
939243830Sdim    default:
940243830Sdim      llvm_unreachable("Unexpected triple arch name");
941243830Sdim    case llvm::Triple::mips:
942243830Sdim    case llvm::Triple::mipsel:
943243830Sdim      CPUName = DefMips32CPU;
944243830Sdim      break;
945243830Sdim    case llvm::Triple::mips64:
946243830Sdim    case llvm::Triple::mips64el:
947243830Sdim      CPUName = DefMips64CPU;
948243830Sdim      break;
949243830Sdim    }
950243830Sdim  }
951243830Sdim
952243830Sdim  if (!ABIName.empty()) {
953243830Sdim    // Deduce CPU name from ABI name.
954243830Sdim    CPUName = llvm::StringSwitch<const char *>(ABIName)
955249423Sdim      .Cases("32", "o32", "eabi", DefMips32CPU)
956249423Sdim      .Cases("n32", "n64", "64", DefMips64CPU)
957243830Sdim      .Default("");
958243830Sdim  }
959243830Sdim  else if (!CPUName.empty()) {
960243830Sdim    // Deduce ABI name from CPU name.
961243830Sdim    ABIName = llvm::StringSwitch<const char *>(CPUName)
962243830Sdim      .Cases("mips32", "mips32r2", "o32")
963243830Sdim      .Cases("mips64", "mips64r2", "n64")
964243830Sdim      .Default("");
965243830Sdim  }
966243830Sdim
967243830Sdim  // FIXME: Warn on inconsistent cpu and abi usage.
968234353Sdim}
969204643Srdivacky
970249423Sdim// Convert ABI name to the GNU tools acceptable variant.
971249423Sdimstatic StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
972249423Sdim  return llvm::StringSwitch<llvm::StringRef>(ABI)
973249423Sdim    .Case("o32", "32")
974249423Sdim    .Case("n64", "64")
975249423Sdim    .Default(ABI);
976249423Sdim}
977249423Sdim
978239462Sdim// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
979239462Sdim// and -mfloat-abi=.
980239462Sdimstatic StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
981226633Sdim  StringRef FloatABI;
982204643Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
983234353Sdim                               options::OPT_mhard_float,
984234353Sdim                               options::OPT_mfloat_abi_EQ)) {
985204643Srdivacky    if (A->getOption().matches(options::OPT_msoft_float))
986204643Srdivacky      FloatABI = "soft";
987204643Srdivacky    else if (A->getOption().matches(options::OPT_mhard_float))
988204643Srdivacky      FloatABI = "hard";
989234353Sdim    else {
990243830Sdim      FloatABI = A->getValue();
991251662Sdim      if (FloatABI != "soft" && FloatABI != "hard") {
992239462Sdim        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
993234353Sdim        FloatABI = "hard";
994234353Sdim      }
995234353Sdim    }
996204643Srdivacky  }
997204643Srdivacky
998204643Srdivacky  // If unspecified, choose the default based on the platform.
999204643Srdivacky  if (FloatABI.empty()) {
1000234353Sdim    // Assume "hard", because it's a default value used by gcc.
1001234353Sdim    // When we start to recognize specific target MIPS processors,
1002234353Sdim    // we will be able to select the default more correctly.
1003234353Sdim    FloatABI = "hard";
1004204643Srdivacky  }
1005204643Srdivacky
1006239462Sdim  return FloatABI;
1007239462Sdim}
1008239462Sdim
1009239462Sdimstatic void AddTargetFeature(const ArgList &Args,
1010263508Sdim                             std::vector<const char *> &Features,
1011263508Sdim                             OptSpecifier OnOpt, OptSpecifier OffOpt,
1012239462Sdim                             StringRef FeatureName) {
1013239462Sdim  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
1014239462Sdim    if (A->getOption().matches(OnOpt))
1015263508Sdim      Features.push_back(Args.MakeArgString("+" + FeatureName));
1016239462Sdim    else
1017263508Sdim      Features.push_back(Args.MakeArgString("-" + FeatureName));
1018239462Sdim  }
1019239462Sdim}
1020239462Sdim
1021263508Sdimstatic void getMIPSTargetFeatures(const Driver &D, const ArgList &Args,
1022263508Sdim                                  std::vector<const char *> &Features) {
1023263508Sdim  StringRef FloatABI = getMipsFloatABI(D, Args);
1024263508Sdim  bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
1025263508Sdim  if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
1026263508Sdim    // FIXME: Note, this is a hack. We need to pass the selected float
1027263508Sdim    // mode to the MipsTargetInfoBase to define appropriate macros there.
1028263508Sdim    // Now it is the only method.
1029263508Sdim    Features.push_back("+soft-float");
1030263508Sdim  }
1031263508Sdim
1032263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
1033263508Sdim    if (StringRef(A->getValue()) == "2008")
1034263508Sdim      Features.push_back("+nan2008");
1035263508Sdim  }
1036263508Sdim
1037263508Sdim  AddTargetFeature(Args, Features, options::OPT_msingle_float,
1038263508Sdim                   options::OPT_mdouble_float, "single-float");
1039263508Sdim  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
1040263508Sdim                   "mips16");
1041263508Sdim  AddTargetFeature(Args, Features, options::OPT_mmicromips,
1042263508Sdim                   options::OPT_mno_micromips, "micromips");
1043263508Sdim  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
1044263508Sdim                   "dsp");
1045263508Sdim  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
1046263508Sdim                   "dspr2");
1047263508Sdim  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
1048263508Sdim                   "msa");
1049263508Sdim  AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
1050263508Sdim                   "fp64");
1051263508Sdim}
1052263508Sdim
1053239462Sdimvoid Clang::AddMIPSTargetArgs(const ArgList &Args,
1054251662Sdim                              ArgStringList &CmdArgs) const {
1055239462Sdim  const Driver &D = getToolChain().getDriver();
1056239462Sdim  StringRef CPUName;
1057239462Sdim  StringRef ABIName;
1058263508Sdim  const llvm::Triple &Triple = getToolChain().getTriple();
1059263508Sdim  getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1060239462Sdim
1061239462Sdim  CmdArgs.push_back("-target-abi");
1062239462Sdim  CmdArgs.push_back(ABIName.data());
1063239462Sdim
1064239462Sdim  StringRef FloatABI = getMipsFloatABI(D, Args);
1065239462Sdim
1066249423Sdim  bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
1067249423Sdim
1068249423Sdim  if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
1069204643Srdivacky    // Floating point operations and argument passing are soft.
1070204643Srdivacky    CmdArgs.push_back("-msoft-float");
1071234353Sdim    CmdArgs.push_back("-mfloat-abi");
1072234353Sdim    CmdArgs.push_back("soft");
1073234353Sdim
1074249423Sdim    if (FloatABI == "hard" && IsMips16) {
1075249423Sdim      CmdArgs.push_back("-mllvm");
1076249423Sdim      CmdArgs.push_back("-mips16-hard-float");
1077249423Sdim    }
1078234353Sdim  }
1079234353Sdim  else {
1080234353Sdim    // Floating point operations and argument passing are hard.
1081204643Srdivacky    assert(FloatABI == "hard" && "Invalid float abi!");
1082234353Sdim    CmdArgs.push_back("-mfloat-abi");
1083234353Sdim    CmdArgs.push_back("hard");
1084204643Srdivacky  }
1085239462Sdim
1086249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
1087249423Sdim    if (A->getOption().matches(options::OPT_mxgot)) {
1088249423Sdim      CmdArgs.push_back("-mllvm");
1089249423Sdim      CmdArgs.push_back("-mxgot");
1090249423Sdim    }
1091249423Sdim  }
1092249423Sdim
1093263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
1094263508Sdim                               options::OPT_mno_ldc1_sdc1)) {
1095263508Sdim    if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
1096263508Sdim      CmdArgs.push_back("-mllvm");
1097263508Sdim      CmdArgs.push_back("-mno-ldc1-sdc1");
1098263508Sdim    }
1099263508Sdim  }
1100263508Sdim
1101263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
1102263508Sdim                               options::OPT_mno_check_zero_division)) {
1103263508Sdim    if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
1104263508Sdim      CmdArgs.push_back("-mllvm");
1105263508Sdim      CmdArgs.push_back("-mno-check-zero-division");
1106263508Sdim    }
1107263508Sdim  }
1108263508Sdim
1109243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_G)) {
1110243830Sdim    StringRef v = A->getValue();
1111243830Sdim    CmdArgs.push_back("-mllvm");
1112243830Sdim    CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
1113243830Sdim    A->claim();
1114243830Sdim  }
1115204643Srdivacky}
1116204643Srdivacky
1117239462Sdim/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
1118239462Sdimstatic std::string getPPCTargetCPU(const ArgList &Args) {
1119239462Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1120243830Sdim    StringRef CPUName = A->getValue();
1121239462Sdim
1122239462Sdim    if (CPUName == "native") {
1123239462Sdim      std::string CPU = llvm::sys::getHostCPUName();
1124239462Sdim      if (!CPU.empty() && CPU != "generic")
1125239462Sdim        return CPU;
1126239462Sdim      else
1127239462Sdim        return "";
1128239462Sdim    }
1129239462Sdim
1130239462Sdim    return llvm::StringSwitch<const char *>(CPUName)
1131239462Sdim      .Case("common", "generic")
1132239462Sdim      .Case("440", "440")
1133239462Sdim      .Case("440fp", "440")
1134239462Sdim      .Case("450", "450")
1135239462Sdim      .Case("601", "601")
1136239462Sdim      .Case("602", "602")
1137239462Sdim      .Case("603", "603")
1138239462Sdim      .Case("603e", "603e")
1139239462Sdim      .Case("603ev", "603ev")
1140239462Sdim      .Case("604", "604")
1141239462Sdim      .Case("604e", "604e")
1142239462Sdim      .Case("620", "620")
1143249423Sdim      .Case("630", "pwr3")
1144239462Sdim      .Case("G3", "g3")
1145239462Sdim      .Case("7400", "7400")
1146239462Sdim      .Case("G4", "g4")
1147239462Sdim      .Case("7450", "7450")
1148239462Sdim      .Case("G4+", "g4+")
1149239462Sdim      .Case("750", "750")
1150239462Sdim      .Case("970", "970")
1151239462Sdim      .Case("G5", "g5")
1152239462Sdim      .Case("a2", "a2")
1153249423Sdim      .Case("a2q", "a2q")
1154243830Sdim      .Case("e500mc", "e500mc")
1155243830Sdim      .Case("e5500", "e5500")
1156249423Sdim      .Case("power3", "pwr3")
1157249423Sdim      .Case("power4", "pwr4")
1158249423Sdim      .Case("power5", "pwr5")
1159249423Sdim      .Case("power5x", "pwr5x")
1160239462Sdim      .Case("power6", "pwr6")
1161249423Sdim      .Case("power6x", "pwr6x")
1162239462Sdim      .Case("power7", "pwr7")
1163249423Sdim      .Case("pwr3", "pwr3")
1164249423Sdim      .Case("pwr4", "pwr4")
1165249423Sdim      .Case("pwr5", "pwr5")
1166249423Sdim      .Case("pwr5x", "pwr5x")
1167249423Sdim      .Case("pwr6", "pwr6")
1168249423Sdim      .Case("pwr6x", "pwr6x")
1169249423Sdim      .Case("pwr7", "pwr7")
1170239462Sdim      .Case("powerpc", "ppc")
1171239462Sdim      .Case("powerpc64", "ppc64")
1172263508Sdim      .Case("powerpc64le", "ppc64le")
1173239462Sdim      .Default("");
1174239462Sdim  }
1175239462Sdim
1176239462Sdim  return "";
1177239462Sdim}
1178239462Sdim
1179263508Sdimstatic void getPPCTargetFeatures(const ArgList &Args,
1180263508Sdim                                 std::vector<const char *> &Features) {
1181263508Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT_m_ppc_Features_Group),
1182263508Sdim                    ie = Args.filtered_end();
1183263508Sdim       it != ie; ++it) {
1184263508Sdim    StringRef Name = (*it)->getOption().getName();
1185263508Sdim    (*it)->claim();
1186239462Sdim
1187263508Sdim    // Skip over "-m".
1188263508Sdim    assert(Name.startswith("m") && "Invalid feature name.");
1189263508Sdim    Name = Name.substr(1);
1190239462Sdim
1191263508Sdim    bool IsNegative = Name.startswith("no-");
1192263508Sdim    if (IsNegative)
1193263508Sdim      Name = Name.substr(3);
1194249423Sdim
1195263508Sdim    // Note that gcc calls this mfcrf and LLVM calls this mfocrf so we
1196263508Sdim    // pass the correct option to the backend while calling the frontend
1197263508Sdim    // option the same.
1198263508Sdim    // TODO: Change the LLVM backend option maybe?
1199263508Sdim    if (Name == "mfcrf")
1200263508Sdim      Name = "mfocrf";
1201249423Sdim
1202263508Sdim    Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
1203263508Sdim  }
1204249423Sdim
1205263508Sdim  // Altivec is a bit weird, allow overriding of the Altivec feature here.
1206263508Sdim  AddTargetFeature(Args, Features, options::OPT_faltivec,
1207263508Sdim                   options::OPT_fno_altivec, "altivec");
1208239462Sdim}
1209239462Sdim
1210249423Sdim/// Get the (LLVM) name of the R600 gpu we are targeting.
1211249423Sdimstatic std::string getR600TargetGPU(const ArgList &Args) {
1212249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1213263508Sdim    const char *GPUName = A->getValue();
1214249423Sdim    return llvm::StringSwitch<const char *>(GPUName)
1215251662Sdim      .Cases("rv630", "rv635", "r600")
1216251662Sdim      .Cases("rv610", "rv620", "rs780", "rs880")
1217249423Sdim      .Case("rv740", "rv770")
1218249423Sdim      .Case("palm", "cedar")
1219251662Sdim      .Cases("sumo", "sumo2", "sumo")
1220249423Sdim      .Case("hemlock", "cypress")
1221249423Sdim      .Case("aruba", "cayman")
1222263508Sdim      .Default(GPUName);
1223249423Sdim  }
1224249423Sdim  return "";
1225249423Sdim}
1226249423Sdim
1227263508Sdimstatic void getSparcTargetFeatures(const ArgList &Args,
1228263508Sdim                                   std::vector<const char *> Features) {
1229263508Sdim  bool SoftFloatABI = true;
1230263508Sdim  if (Arg *A =
1231263508Sdim          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) {
1232263508Sdim    if (A->getOption().matches(options::OPT_mhard_float))
1233263508Sdim      SoftFloatABI = false;
1234263508Sdim  }
1235263508Sdim  if (SoftFloatABI)
1236263508Sdim    Features.push_back("+soft-float");
1237249423Sdim}
1238249423Sdim
1239218893Sdimvoid Clang::AddSparcTargetArgs(const ArgList &Args,
1240218893Sdim                             ArgStringList &CmdArgs) const {
1241218893Sdim  const Driver &D = getToolChain().getDriver();
1242218893Sdim
1243218893Sdim  // Select the float ABI as determined by -msoft-float, -mhard-float, and
1244226633Sdim  StringRef FloatABI;
1245218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1246218893Sdim                               options::OPT_mhard_float)) {
1247218893Sdim    if (A->getOption().matches(options::OPT_msoft_float))
1248218893Sdim      FloatABI = "soft";
1249218893Sdim    else if (A->getOption().matches(options::OPT_mhard_float))
1250218893Sdim      FloatABI = "hard";
1251218893Sdim  }
1252218893Sdim
1253218893Sdim  // If unspecified, choose the default based on the platform.
1254218893Sdim  if (FloatABI.empty()) {
1255263508Sdim    // Assume "soft", but warn the user we are guessing.
1256263508Sdim    FloatABI = "soft";
1257263508Sdim    D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
1258218893Sdim  }
1259218893Sdim
1260218893Sdim  if (FloatABI == "soft") {
1261218893Sdim    // Floating point operations and argument passing are soft.
1262218893Sdim    //
1263218893Sdim    // FIXME: This changes CPP defines, we need -target-soft-float.
1264218893Sdim    CmdArgs.push_back("-msoft-float");
1265218893Sdim  } else {
1266218893Sdim    assert(FloatABI == "hard" && "Invalid float abi!");
1267218893Sdim    CmdArgs.push_back("-mhard-float");
1268218893Sdim  }
1269218893Sdim}
1270218893Sdim
1271263508Sdimstatic const char *getSystemZTargetCPU(const ArgList &Args) {
1272263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
1273263508Sdim    return A->getValue();
1274263508Sdim  return "z10";
1275263508Sdim}
1276263508Sdim
1277247166Sdimstatic const char *getX86TargetCPU(const ArgList &Args,
1278247166Sdim                                   const llvm::Triple &Triple) {
1279247166Sdim  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1280263508Sdim    if (StringRef(A->getValue()) != "native") {
1281263508Sdim      if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
1282263508Sdim        return "core-avx2";
1283263508Sdim
1284247166Sdim      return A->getValue();
1285263508Sdim    }
1286247166Sdim
1287247166Sdim    // FIXME: Reject attempts to use -march=native unless the target matches
1288247166Sdim    // the host.
1289247166Sdim    //
1290247166Sdim    // FIXME: We should also incorporate the detected target features for use
1291247166Sdim    // with -native.
1292247166Sdim    std::string CPU = llvm::sys::getHostCPUName();
1293247166Sdim    if (!CPU.empty() && CPU != "generic")
1294247166Sdim      return Args.MakeArgString(CPU);
1295247166Sdim  }
1296247166Sdim
1297247166Sdim  // Select the default CPU if none was given (or detection failed).
1298247166Sdim
1299247166Sdim  if (Triple.getArch() != llvm::Triple::x86_64 &&
1300247166Sdim      Triple.getArch() != llvm::Triple::x86)
1301247166Sdim    return 0; // This routine is only handling x86 targets.
1302247166Sdim
1303247166Sdim  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
1304247166Sdim
1305247166Sdim  // FIXME: Need target hooks.
1306263508Sdim  if (Triple.isOSDarwin()) {
1307263508Sdim    if (Triple.getArchName() == "x86_64h")
1308263508Sdim      return "core-avx2";
1309247166Sdim    return Is64Bit ? "core2" : "yonah";
1310263508Sdim  }
1311247166Sdim
1312263508Sdim  // All x86 devices running Android have core2 as their common
1313263508Sdim  // denominator. This makes a better choice than pentium4.
1314263508Sdim  if (Triple.getEnvironment() == llvm::Triple::Android)
1315263508Sdim    return "core2";
1316263508Sdim
1317247166Sdim  // Everything else goes to x86-64 in 64-bit mode.
1318247166Sdim  if (Is64Bit)
1319247166Sdim    return "x86-64";
1320247166Sdim
1321263508Sdim  switch (Triple.getOS()) {
1322263508Sdim  case llvm::Triple::FreeBSD:
1323263508Sdim  case llvm::Triple::NetBSD:
1324263508Sdim  case llvm::Triple::OpenBSD:
1325263508Sdim    return "i486";
1326263508Sdim  case llvm::Triple::Haiku:
1327247166Sdim    return "i586";
1328263508Sdim  case llvm::Triple::Bitrig:
1329247166Sdim    return "i686";
1330263508Sdim  default:
1331263508Sdim    // Fallback to p4.
1332263508Sdim    return "pentium4";
1333263508Sdim  }
1334263508Sdim}
1335247166Sdim
1336263508Sdimstatic std::string getCPUName(const ArgList &Args, const llvm::Triple &T) {
1337263508Sdim  switch(T.getArch()) {
1338263508Sdim  default:
1339263508Sdim    return "";
1340263508Sdim
1341263508Sdim  case llvm::Triple::aarch64:
1342263508Sdim    return getAArch64TargetCPU(Args, T);
1343263508Sdim
1344263508Sdim  case llvm::Triple::arm:
1345263508Sdim  case llvm::Triple::thumb:
1346263508Sdim    return getARMTargetCPU(Args, T);
1347263508Sdim
1348263508Sdim  case llvm::Triple::mips:
1349263508Sdim  case llvm::Triple::mipsel:
1350263508Sdim  case llvm::Triple::mips64:
1351263508Sdim  case llvm::Triple::mips64el: {
1352263508Sdim    StringRef CPUName;
1353263508Sdim    StringRef ABIName;
1354263508Sdim    getMipsCPUAndABI(Args, T, CPUName, ABIName);
1355263508Sdim    return CPUName;
1356263508Sdim  }
1357263508Sdim
1358263508Sdim  case llvm::Triple::ppc:
1359263508Sdim  case llvm::Triple::ppc64:
1360263508Sdim  case llvm::Triple::ppc64le: {
1361263508Sdim    std::string TargetCPUName = getPPCTargetCPU(Args);
1362263508Sdim    // LLVM may default to generating code for the native CPU,
1363263508Sdim    // but, like gcc, we default to a more generic option for
1364263508Sdim    // each architecture. (except on Darwin)
1365263508Sdim    if (TargetCPUName.empty() && !T.isOSDarwin()) {
1366263508Sdim      if (T.getArch() == llvm::Triple::ppc64)
1367263508Sdim        TargetCPUName = "ppc64";
1368263508Sdim      else if (T.getArch() == llvm::Triple::ppc64le)
1369263508Sdim        TargetCPUName = "ppc64le";
1370263508Sdim      else
1371263508Sdim        TargetCPUName = "ppc";
1372263508Sdim    }
1373263508Sdim    return TargetCPUName;
1374263508Sdim  }
1375263508Sdim
1376263508Sdim  case llvm::Triple::sparc:
1377263763Sdim  case llvm::Triple::sparcv9:
1378263763Sdim    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
1379263508Sdim      return A->getValue();
1380263508Sdim    return "";
1381263508Sdim
1382263508Sdim  case llvm::Triple::x86:
1383263508Sdim  case llvm::Triple::x86_64:
1384263508Sdim    return getX86TargetCPU(Args, T);
1385263508Sdim
1386263508Sdim  case llvm::Triple::hexagon:
1387263508Sdim    return "hexagon" + toolchains::Hexagon_TC::GetTargetCPU(Args).str();
1388263508Sdim
1389263508Sdim  case llvm::Triple::systemz:
1390263508Sdim    return getSystemZTargetCPU(Args);
1391263508Sdim
1392263508Sdim  case llvm::Triple::r600:
1393263508Sdim    return getR600TargetGPU(Args);
1394263508Sdim  }
1395247166Sdim}
1396247166Sdim
1397263508Sdimstatic void getX86TargetFeatures(const llvm::Triple &Triple,
1398263508Sdim                                 const ArgList &Args,
1399263508Sdim                                 std::vector<const char *> &Features) {
1400263508Sdim  if (Triple.getArchName() == "x86_64h") {
1401263508Sdim    // x86_64h implies quite a few of the more modern subtarget features
1402263508Sdim    // for Haswell class CPUs, but not all of them. Opt-out of a few.
1403263508Sdim    Features.push_back("-rdrnd");
1404263508Sdim    Features.push_back("-aes");
1405263508Sdim    Features.push_back("-pclmul");
1406263508Sdim    Features.push_back("-rtm");
1407263508Sdim    Features.push_back("-hle");
1408263508Sdim    Features.push_back("-fsgsbase");
1409263508Sdim  }
1410263508Sdim
1411263508Sdim  // Now add any that the user explicitly requested on the command line,
1412263508Sdim  // which may override the defaults.
1413263508Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
1414263508Sdim                    ie = Args.filtered_end();
1415263508Sdim       it != ie; ++it) {
1416263508Sdim    StringRef Name = (*it)->getOption().getName();
1417263508Sdim    (*it)->claim();
1418263508Sdim
1419263508Sdim    // Skip over "-m".
1420263508Sdim    assert(Name.startswith("m") && "Invalid feature name.");
1421263508Sdim    Name = Name.substr(1);
1422263508Sdim
1423263508Sdim    bool IsNegative = Name.startswith("no-");
1424263508Sdim    if (IsNegative)
1425263508Sdim      Name = Name.substr(3);
1426263508Sdim
1427263508Sdim    Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
1428263508Sdim  }
1429263508Sdim}
1430263508Sdim
1431198092Srdivackyvoid Clang::AddX86TargetArgs(const ArgList &Args,
1432198092Srdivacky                             ArgStringList &CmdArgs) const {
1433198092Srdivacky  if (!Args.hasFlag(options::OPT_mred_zone,
1434198092Srdivacky                    options::OPT_mno_red_zone,
1435198092Srdivacky                    true) ||
1436198092Srdivacky      Args.hasArg(options::OPT_mkernel) ||
1437198092Srdivacky      Args.hasArg(options::OPT_fapple_kext))
1438199990Srdivacky    CmdArgs.push_back("-disable-red-zone");
1439198092Srdivacky
1440249423Sdim  // Default to avoid implicit floating-point for kernel/kext code, but allow
1441249423Sdim  // that to be overridden with -mno-soft-float.
1442249423Sdim  bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
1443249423Sdim                          Args.hasArg(options::OPT_fapple_kext));
1444249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1445249423Sdim                               options::OPT_mno_soft_float,
1446251662Sdim                               options::OPT_mimplicit_float,
1447249423Sdim                               options::OPT_mno_implicit_float)) {
1448249423Sdim    const Option &O = A->getOption();
1449249423Sdim    NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
1450249423Sdim                       O.matches(options::OPT_msoft_float));
1451249423Sdim  }
1452249423Sdim  if (NoImplicitFloat)
1453199990Srdivacky    CmdArgs.push_back("-no-implicit-float");
1454198092Srdivacky}
1455198092Srdivacky
1456249423Sdimstatic inline bool HasPICArg(const ArgList &Args) {
1457249423Sdim  return Args.hasArg(options::OPT_fPIC)
1458249423Sdim    || Args.hasArg(options::OPT_fpic);
1459249423Sdim}
1460234353Sdim
1461249423Sdimstatic Arg *GetLastSmallDataThresholdArg(const ArgList &Args) {
1462249423Sdim  return Args.getLastArg(options::OPT_G,
1463249423Sdim                         options::OPT_G_EQ,
1464249423Sdim                         options::OPT_msmall_data_threshold_EQ);
1465234353Sdim}
1466234353Sdim
1467249423Sdimstatic std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) {
1468249423Sdim  std::string value;
1469249423Sdim  if (HasPICArg(Args))
1470249423Sdim    value = "0";
1471249423Sdim  else if (Arg *A = GetLastSmallDataThresholdArg(Args)) {
1472249423Sdim    value = A->getValue();
1473249423Sdim    A->claim();
1474234353Sdim  }
1475249423Sdim  return value;
1476234353Sdim}
1477234353Sdim
1478234353Sdimvoid Clang::AddHexagonTargetArgs(const ArgList &Args,
1479234353Sdim                                 ArgStringList &CmdArgs) const {
1480234353Sdim  CmdArgs.push_back("-fno-signed-char");
1481249423Sdim  CmdArgs.push_back("-mqdsp6-compat");
1482249423Sdim  CmdArgs.push_back("-Wreturn-type");
1483234353Sdim
1484249423Sdim  std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
1485249423Sdim  if (!SmallDataThreshold.empty()) {
1486234353Sdim    CmdArgs.push_back ("-mllvm");
1487249423Sdim    CmdArgs.push_back(Args.MakeArgString(
1488249423Sdim                        "-hexagon-small-data-threshold=" + SmallDataThreshold));
1489234353Sdim  }
1490234353Sdim
1491239462Sdim  if (!Args.hasArg(options::OPT_fno_short_enums))
1492239462Sdim    CmdArgs.push_back("-fshort-enums");
1493239462Sdim  if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
1494239462Sdim    CmdArgs.push_back ("-mllvm");
1495239462Sdim    CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near");
1496239462Sdim  }
1497234353Sdim  CmdArgs.push_back ("-mllvm");
1498234353Sdim  CmdArgs.push_back ("-machine-sink-split=0");
1499234353Sdim}
1500234353Sdim
1501263508Sdimstatic void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
1502263508Sdim                                     std::vector<const char *> &Features) {
1503263508Sdim  // Honor -mfpu=.
1504263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
1505263508Sdim    getAArch64FPUFeatures(D, A, Args, Features);
1506263508Sdim}
1507263508Sdim
1508263508Sdimstatic void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
1509263508Sdim                              const ArgList &Args, ArgStringList &CmdArgs) {
1510263508Sdim  std::vector<const char *> Features;
1511263508Sdim  switch (Triple.getArch()) {
1512263508Sdim  default:
1513263508Sdim    break;
1514263508Sdim  case llvm::Triple::mips:
1515263508Sdim  case llvm::Triple::mipsel:
1516263508Sdim  case llvm::Triple::mips64:
1517263508Sdim  case llvm::Triple::mips64el:
1518263508Sdim    getMIPSTargetFeatures(D, Args, Features);
1519263508Sdim    break;
1520263508Sdim
1521263508Sdim  case llvm::Triple::arm:
1522263508Sdim  case llvm::Triple::thumb:
1523263508Sdim    getARMTargetFeatures(D, Triple, Args, Features);
1524263508Sdim    break;
1525263508Sdim
1526263508Sdim  case llvm::Triple::ppc:
1527263508Sdim  case llvm::Triple::ppc64:
1528263508Sdim  case llvm::Triple::ppc64le:
1529263508Sdim    getPPCTargetFeatures(Args, Features);
1530263508Sdim    break;
1531263508Sdim  case llvm::Triple::sparc:
1532263508Sdim    getSparcTargetFeatures(Args, Features);
1533263508Sdim    break;
1534263508Sdim  case llvm::Triple::aarch64:
1535263508Sdim    getAArch64TargetFeatures(D, Args, Features);
1536263508Sdim    break;
1537263508Sdim  case llvm::Triple::x86:
1538263508Sdim  case llvm::Triple::x86_64:
1539263508Sdim    getX86TargetFeatures(Triple, Args, Features);
1540263508Sdim    break;
1541263508Sdim  }
1542263508Sdim
1543263508Sdim  // Find the last of each feature.
1544263508Sdim  llvm::StringMap<unsigned> LastOpt;
1545263508Sdim  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
1546263508Sdim    const char *Name = Features[I];
1547263508Sdim    assert(Name[0] == '-' || Name[0] == '+');
1548263508Sdim    LastOpt[Name + 1] = I;
1549263508Sdim  }
1550263508Sdim
1551263508Sdim  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
1552263508Sdim    // If this feature was overridden, ignore it.
1553263508Sdim    const char *Name = Features[I];
1554263508Sdim    llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name + 1);
1555263508Sdim    assert(LastI != LastOpt.end());
1556263508Sdim    unsigned Last = LastI->second;
1557263508Sdim    if (Last != I)
1558263508Sdim      continue;
1559263508Sdim
1560263508Sdim    CmdArgs.push_back("-target-feature");
1561263508Sdim    CmdArgs.push_back(Name);
1562263508Sdim  }
1563263508Sdim}
1564263508Sdim
1565226633Sdimstatic bool
1566239462SdimshouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
1567221345Sdim                                          const llvm::Triple &Triple) {
1568221345Sdim  // We use the zero-cost exception tables for Objective-C if the non-fragile
1569221345Sdim  // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
1570221345Sdim  // later.
1571239462Sdim  if (runtime.isNonFragile())
1572221345Sdim    return true;
1573221345Sdim
1574226633Sdim  if (!Triple.isOSDarwin())
1575221345Sdim    return false;
1576221345Sdim
1577224145Sdim  return (!Triple.isMacOSXVersionLT(10,5) &&
1578221345Sdim          (Triple.getArch() == llvm::Triple::x86_64 ||
1579226633Sdim           Triple.getArch() == llvm::Triple::arm));
1580221345Sdim}
1581221345Sdim
1582221345Sdim/// addExceptionArgs - Adds exception related arguments to the driver command
1583221345Sdim/// arguments. There's a master flag, -fexceptions and also language specific
1584221345Sdim/// flags to enable/disable C++ and Objective-C exceptions.
1585221345Sdim/// This makes it possible to for example disable C++ exceptions but enable
1586221345Sdim/// Objective-C exceptions.
1587221345Sdimstatic void addExceptionArgs(const ArgList &Args, types::ID InputType,
1588221345Sdim                             const llvm::Triple &Triple,
1589234353Sdim                             bool KernelOrKext,
1590239462Sdim                             const ObjCRuntime &objcRuntime,
1591221345Sdim                             ArgStringList &CmdArgs) {
1592234353Sdim  if (KernelOrKext) {
1593234353Sdim    // -mkernel and -fapple-kext imply no exceptions, so claim exception related
1594234353Sdim    // arguments now to avoid warnings about unused arguments.
1595234353Sdim    Args.ClaimAllArgs(options::OPT_fexceptions);
1596234353Sdim    Args.ClaimAllArgs(options::OPT_fno_exceptions);
1597234353Sdim    Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
1598234353Sdim    Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
1599234353Sdim    Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
1600234353Sdim    Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
1601221345Sdim    return;
1602234353Sdim  }
1603221345Sdim
1604221345Sdim  // Exceptions are enabled by default.
1605221345Sdim  bool ExceptionsEnabled = true;
1606221345Sdim
1607221345Sdim  // This keeps track of whether exceptions were explicitly turned on or off.
1608221345Sdim  bool DidHaveExplicitExceptionFlag = false;
1609221345Sdim
1610198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
1611198092Srdivacky                               options::OPT_fno_exceptions)) {
1612198092Srdivacky    if (A->getOption().matches(options::OPT_fexceptions))
1613221345Sdim      ExceptionsEnabled = true;
1614226633Sdim    else
1615221345Sdim      ExceptionsEnabled = false;
1616221345Sdim
1617221345Sdim    DidHaveExplicitExceptionFlag = true;
1618198092Srdivacky  }
1619218893Sdim
1620221345Sdim  bool ShouldUseExceptionTables = false;
1621198092Srdivacky
1622221345Sdim  // Exception tables and cleanups can be enabled with -fexceptions even if the
1623221345Sdim  // language itself doesn't support exceptions.
1624221345Sdim  if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
1625221345Sdim    ShouldUseExceptionTables = true;
1626221345Sdim
1627221345Sdim  // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
1628221345Sdim  // is not necessarily sensible, but follows GCC.
1629221345Sdim  if (types::isObjC(InputType) &&
1630226633Sdim      Args.hasFlag(options::OPT_fobjc_exceptions,
1631221345Sdim                   options::OPT_fno_objc_exceptions,
1632221345Sdim                   true)) {
1633221345Sdim    CmdArgs.push_back("-fobjc-exceptions");
1634221345Sdim
1635226633Sdim    ShouldUseExceptionTables |=
1636239462Sdim      shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
1637218893Sdim  }
1638198092Srdivacky
1639221345Sdim  if (types::isCXX(InputType)) {
1640221345Sdim    bool CXXExceptionsEnabled = ExceptionsEnabled;
1641221345Sdim
1642226633Sdim    if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
1643226633Sdim                                 options::OPT_fno_cxx_exceptions,
1644221345Sdim                                 options::OPT_fexceptions,
1645221345Sdim                                 options::OPT_fno_exceptions)) {
1646221345Sdim      if (A->getOption().matches(options::OPT_fcxx_exceptions))
1647221345Sdim        CXXExceptionsEnabled = true;
1648221345Sdim      else if (A->getOption().matches(options::OPT_fno_cxx_exceptions))
1649221345Sdim        CXXExceptionsEnabled = false;
1650221345Sdim    }
1651221345Sdim
1652221345Sdim    if (CXXExceptionsEnabled) {
1653221345Sdim      CmdArgs.push_back("-fcxx-exceptions");
1654221345Sdim
1655221345Sdim      ShouldUseExceptionTables = true;
1656221345Sdim    }
1657221345Sdim  }
1658221345Sdim
1659221345Sdim  if (ShouldUseExceptionTables)
1660221345Sdim    CmdArgs.push_back("-fexceptions");
1661198092Srdivacky}
1662198092Srdivacky
1663251662Sdimstatic bool ShouldDisableAutolink(const ArgList &Args,
1664251662Sdim                             const ToolChain &TC) {
1665251662Sdim  bool Default = true;
1666251662Sdim  if (TC.getTriple().isOSDarwin()) {
1667251662Sdim    // The native darwin assembler doesn't support the linker_option directives,
1668251662Sdim    // so we disable them if we think the .s file will be passed to it.
1669251662Sdim    Default = TC.useIntegratedAs();
1670251662Sdim  }
1671251662Sdim  return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
1672251662Sdim                       Default);
1673251662Sdim}
1674251662Sdim
1675221345Sdimstatic bool ShouldDisableCFI(const ArgList &Args,
1676221345Sdim                             const ToolChain &TC) {
1677234353Sdim  bool Default = true;
1678226633Sdim  if (TC.getTriple().isOSDarwin()) {
1679223017Sdim    // The native darwin assembler doesn't support cfi directives, so
1680223017Sdim    // we disable them if we think the .s file will be passed to it.
1681249423Sdim    Default = TC.useIntegratedAs();
1682223017Sdim  }
1683234353Sdim  return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
1684249423Sdim                       options::OPT_fno_dwarf2_cfi_asm,
1685249423Sdim                       Default);
1686234353Sdim}
1687223017Sdim
1688234353Sdimstatic bool ShouldDisableDwarfDirectory(const ArgList &Args,
1689234353Sdim                                        const ToolChain &TC) {
1690234353Sdim  bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm,
1691234353Sdim                                        options::OPT_fno_dwarf_directory_asm,
1692249423Sdim                                        TC.useIntegratedAs());
1693234353Sdim  return !UseDwarfDirectory;
1694221345Sdim}
1695221345Sdim
1696223017Sdim/// \brief Check whether the given input tree contains any compilation actions.
1697223017Sdimstatic bool ContainsCompileAction(const Action *A) {
1698223017Sdim  if (isa<CompileJobAction>(A))
1699223017Sdim    return true;
1700223017Sdim
1701223017Sdim  for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
1702223017Sdim    if (ContainsCompileAction(*it))
1703223017Sdim      return true;
1704223017Sdim
1705223017Sdim  return false;
1706223017Sdim}
1707223017Sdim
1708223017Sdim/// \brief Check if -relax-all should be passed to the internal assembler.
1709223017Sdim/// This is done by default when compiling non-assembler source with -O0.
1710223017Sdimstatic bool UseRelaxAll(Compilation &C, const ArgList &Args) {
1711223017Sdim  bool RelaxDefault = true;
1712223017Sdim
1713223017Sdim  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1714223017Sdim    RelaxDefault = A->getOption().matches(options::OPT_O0);
1715223017Sdim
1716223017Sdim  if (RelaxDefault) {
1717223017Sdim    RelaxDefault = false;
1718223017Sdim    for (ActionList::const_iterator it = C.getActions().begin(),
1719223017Sdim           ie = C.getActions().end(); it != ie; ++it) {
1720223017Sdim      if (ContainsCompileAction(*it)) {
1721223017Sdim        RelaxDefault = true;
1722223017Sdim        break;
1723223017Sdim      }
1724223017Sdim    }
1725223017Sdim  }
1726223017Sdim
1727223017Sdim  return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
1728223017Sdim    RelaxDefault);
1729223017Sdim}
1730223017Sdim
1731263508Sdimstatic void CollectArgsForIntegratedAssembler(Compilation &C,
1732263508Sdim                                              const ArgList &Args,
1733263508Sdim                                              ArgStringList &CmdArgs,
1734263508Sdim                                              const Driver &D) {
1735263508Sdim    if (UseRelaxAll(C, Args))
1736263508Sdim      CmdArgs.push_back("-mrelax-all");
1737243830Sdim
1738263508Sdim    // When passing -I arguments to the assembler we sometimes need to
1739263508Sdim    // unconditionally take the next argument.  For example, when parsing
1740263508Sdim    // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
1741263508Sdim    // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
1742263508Sdim    // arg after parsing the '-I' arg.
1743263508Sdim    bool TakeNextArg = false;
1744243830Sdim
1745263508Sdim    // When using an integrated assembler, translate -Wa, and -Xassembler
1746263508Sdim    // options.
1747263508Sdim    for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA,
1748263508Sdim                                               options::OPT_Xassembler),
1749263508Sdim           ie = Args.filtered_end(); it != ie; ++it) {
1750263508Sdim      const Arg *A = *it;
1751263508Sdim      A->claim();
1752243830Sdim
1753263508Sdim      for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
1754263508Sdim        StringRef Value = A->getValue(i);
1755263508Sdim        if (TakeNextArg) {
1756263508Sdim          CmdArgs.push_back(Value.data());
1757263508Sdim          TakeNextArg = false;
1758263508Sdim          continue;
1759263508Sdim        }
1760249423Sdim
1761263508Sdim        if (Value == "-force_cpusubtype_ALL") {
1762263508Sdim          // Do nothing, this is the default and we don't support anything else.
1763263508Sdim        } else if (Value == "-L") {
1764263508Sdim          CmdArgs.push_back("-msave-temp-labels");
1765263508Sdim        } else if (Value == "--fatal-warnings") {
1766263508Sdim          CmdArgs.push_back("-mllvm");
1767263508Sdim          CmdArgs.push_back("-fatal-assembler-warnings");
1768263508Sdim        } else if (Value == "--noexecstack") {
1769263508Sdim          CmdArgs.push_back("-mnoexecstack");
1770263508Sdim        } else if (Value.startswith("-I")) {
1771263508Sdim          CmdArgs.push_back(Value.data());
1772263508Sdim          // We need to consume the next argument if the current arg is a plain
1773263508Sdim          // -I. The next arg will be the include directory.
1774263508Sdim          if (Value == "-I")
1775263508Sdim            TakeNextArg = true;
1776263508Sdim        } else {
1777263508Sdim          D.Diag(diag::err_drv_unsupported_option_argument)
1778263508Sdim            << A->getOption().getName() << Value;
1779263508Sdim        }
1780263508Sdim      }
1781263508Sdim    }
1782263508Sdim}
1783249423Sdim
1784263508Sdimstatic void addProfileRTLinux(
1785263508Sdim    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
1786263508Sdim  if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
1787263508Sdim        Args.hasArg(options::OPT_fprofile_generate) ||
1788263508Sdim        Args.hasArg(options::OPT_fcreate_profile) ||
1789263508Sdim        Args.hasArg(options::OPT_coverage)))
1790263508Sdim    return;
1791249423Sdim
1792263508Sdim  // The profile runtime is located in the Linux library directory and has name
1793263508Sdim  // "libclang_rt.profile-<ArchName>.a".
1794263508Sdim  SmallString<128> LibProfile(TC.getDriver().ResourceDir);
1795263508Sdim  llvm::sys::path::append(
1796263508Sdim      LibProfile, "lib", "linux",
1797263508Sdim      Twine("libclang_rt.profile-") + TC.getArchName() + ".a");
1798249423Sdim
1799263508Sdim  CmdArgs.push_back(Args.MakeArgString(LibProfile));
1800243830Sdim}
1801243830Sdim
1802249423Sdimstatic void addSanitizerRTLinkFlagsLinux(
1803249423Sdim    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
1804249423Sdim    const StringRef Sanitizer, bool BeforeLibStdCXX,
1805249423Sdim    bool ExportSymbols = true) {
1806249423Sdim  // Sanitizer runtime is located in the Linux library directory and
1807249423Sdim  // has name "libclang_rt.<Sanitizer>-<ArchName>.a".
1808249423Sdim  SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
1809249423Sdim  llvm::sys::path::append(
1810249423Sdim      LibSanitizer, "lib", "linux",
1811249423Sdim      (Twine("libclang_rt.") + Sanitizer + "-" + TC.getArchName() + ".a"));
1812249423Sdim
1813249423Sdim  // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
1814249423Sdim  // etc.) so that the linker picks custom versions of the global 'operator
1815249423Sdim  // new' and 'operator delete' symbols. We take the extreme (but simple)
1816249423Sdim  // strategy of inserting it at the front of the link command. It also
1817249423Sdim  // needs to be forced to end up in the executable, so wrap it in
1818249423Sdim  // whole-archive.
1819249423Sdim  SmallVector<const char *, 3> LibSanitizerArgs;
1820249423Sdim  LibSanitizerArgs.push_back("-whole-archive");
1821249423Sdim  LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
1822249423Sdim  LibSanitizerArgs.push_back("-no-whole-archive");
1823249423Sdim
1824249423Sdim  CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
1825249423Sdim                 LibSanitizerArgs.begin(), LibSanitizerArgs.end());
1826249423Sdim
1827249423Sdim  CmdArgs.push_back("-lpthread");
1828251662Sdim  CmdArgs.push_back("-lrt");
1829249423Sdim  CmdArgs.push_back("-ldl");
1830263508Sdim  CmdArgs.push_back("-lm");
1831249423Sdim
1832249423Sdim  // If possible, use a dynamic symbols file to export the symbols from the
1833249423Sdim  // runtime library. If we can't do so, use -export-dynamic instead to export
1834249423Sdim  // all symbols from the binary.
1835249423Sdim  if (ExportSymbols) {
1836249423Sdim    if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
1837249423Sdim      CmdArgs.push_back(
1838249423Sdim          Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
1839249423Sdim    else
1840249423Sdim      CmdArgs.push_back("-export-dynamic");
1841249423Sdim  }
1842249423Sdim}
1843249423Sdim
1844234353Sdim/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
1845234353Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1846234353Sdimstatic void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
1847234353Sdim                           ArgStringList &CmdArgs) {
1848263508Sdim  if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
1849243830Sdim    SmallString<128> LibAsan(TC.getDriver().ResourceDir);
1850243830Sdim    llvm::sys::path::append(LibAsan, "lib", "linux",
1851243830Sdim        (Twine("libclang_rt.asan-") +
1852243830Sdim            TC.getArchName() + "-android.so"));
1853249423Sdim    CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
1854239462Sdim  } else {
1855263508Sdim    if (!Args.hasArg(options::OPT_shared))
1856249423Sdim      addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
1857239462Sdim  }
1858234353Sdim}
1859234353Sdim
1860239462Sdim/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
1861239462Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1862239462Sdimstatic void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
1863239462Sdim                           ArgStringList &CmdArgs) {
1864263508Sdim  if (!Args.hasArg(options::OPT_shared))
1865249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
1866239462Sdim}
1867239462Sdim
1868249423Sdim/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
1869249423Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1870249423Sdimstatic void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
1871249423Sdim                           ArgStringList &CmdArgs) {
1872263508Sdim  if (!Args.hasArg(options::OPT_shared))
1873249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
1874249423Sdim}
1875249423Sdim
1876263508Sdim/// If LeakSanitizer is enabled, add appropriate linker flags (Linux).
1877263508Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1878263508Sdimstatic void addLsanRTLinux(const ToolChain &TC, const ArgList &Args,
1879263508Sdim                           ArgStringList &CmdArgs) {
1880263508Sdim  if (!Args.hasArg(options::OPT_shared))
1881263508Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true);
1882263508Sdim}
1883263508Sdim
1884243830Sdim/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
1885243830Sdim/// (Linux).
1886243830Sdimstatic void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
1887249423Sdim                            ArgStringList &CmdArgs, bool IsCXX,
1888249423Sdim                            bool HasOtherSanitizerRt) {
1889249423Sdim  // Need a copy of sanitizer_common. This could come from another sanitizer
1890249423Sdim  // runtime; if we're not including one, include our own copy.
1891249423Sdim  if (!HasOtherSanitizerRt)
1892249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false);
1893249423Sdim
1894249423Sdim  addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
1895249423Sdim
1896249423Sdim  // Only include the bits of the runtime which need a C++ ABI library if
1897249423Sdim  // we're linking in C++ mode.
1898249423Sdim  if (IsCXX)
1899249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false);
1900243830Sdim}
1901243830Sdim
1902263508Sdimstatic void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args,
1903263508Sdim                            ArgStringList &CmdArgs) {
1904263508Sdim  if (!Args.hasArg(options::OPT_shared))
1905263508Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true);
1906263508Sdim}
1907263508Sdim
1908263508Sdimstatic bool shouldUseFramePointerForTarget(const ArgList &Args,
1909263508Sdim                                           const llvm::Triple &Triple) {
1910263508Sdim  switch (Triple.getArch()) {
1911263508Sdim  // Don't use a frame pointer on linux if optimizing for certain targets.
1912263508Sdim  case llvm::Triple::mips64:
1913263508Sdim  case llvm::Triple::mips64el:
1914263508Sdim  case llvm::Triple::mips:
1915263508Sdim  case llvm::Triple::mipsel:
1916263508Sdim  case llvm::Triple::systemz:
1917263508Sdim  case llvm::Triple::x86:
1918263508Sdim  case llvm::Triple::x86_64:
1919263508Sdim    if (Triple.isOSLinux())
1920263508Sdim      if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1921263508Sdim        if (!A->getOption().matches(options::OPT_O0))
1922263508Sdim          return false;
1923263508Sdim    return true;
1924263508Sdim  case llvm::Triple::xcore:
1925263508Sdim    return false;
1926263508Sdim  default:
1927263508Sdim    return true;
1928263508Sdim  }
1929263508Sdim}
1930263508Sdim
1931234353Sdimstatic bool shouldUseFramePointer(const ArgList &Args,
1932234353Sdim                                  const llvm::Triple &Triple) {
1933234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
1934234353Sdim                               options::OPT_fomit_frame_pointer))
1935234353Sdim    return A->getOption().matches(options::OPT_fno_omit_frame_pointer);
1936234353Sdim
1937263508Sdim  return shouldUseFramePointerForTarget(Args, Triple);
1938234353Sdim}
1939234353Sdim
1940249423Sdimstatic bool shouldUseLeafFramePointer(const ArgList &Args,
1941249423Sdim                                      const llvm::Triple &Triple) {
1942249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
1943249423Sdim                               options::OPT_momit_leaf_frame_pointer))
1944249423Sdim    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
1945249423Sdim
1946263508Sdim  return shouldUseFramePointerForTarget(Args, Triple);
1947249423Sdim}
1948249423Sdim
1949263508Sdim/// Add a CC1 option to specify the debug compilation directory.
1950249423Sdimstatic void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
1951251662Sdim  SmallString<128> cwd;
1952251662Sdim  if (!llvm::sys::fs::current_path(cwd)) {
1953251662Sdim    CmdArgs.push_back("-fdebug-compilation-dir");
1954251662Sdim    CmdArgs.push_back(Args.MakeArgString(cwd));
1955251662Sdim  }
1956249423Sdim}
1957249423Sdim
1958249423Sdimstatic const char *SplitDebugName(const ArgList &Args,
1959249423Sdim                                  const InputInfoList &Inputs) {
1960249423Sdim  Arg *FinalOutput = Args.getLastArg(options::OPT_o);
1961249423Sdim  if (FinalOutput && Args.hasArg(options::OPT_c)) {
1962249423Sdim    SmallString<128> T(FinalOutput->getValue());
1963249423Sdim    llvm::sys::path::replace_extension(T, "dwo");
1964249423Sdim    return Args.MakeArgString(T);
1965249423Sdim  } else {
1966249423Sdim    // Use the compilation dir.
1967249423Sdim    SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
1968249423Sdim    SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput()));
1969249423Sdim    llvm::sys::path::replace_extension(F, "dwo");
1970249423Sdim    T += F;
1971249423Sdim    return Args.MakeArgString(F);
1972249423Sdim  }
1973249423Sdim}
1974249423Sdim
1975249423Sdimstatic void SplitDebugInfo(const ToolChain &TC, Compilation &C,
1976249423Sdim                           const Tool &T, const JobAction &JA,
1977249423Sdim                           const ArgList &Args, const InputInfo &Output,
1978249423Sdim                           const char *OutFile) {
1979249423Sdim  ArgStringList ExtractArgs;
1980249423Sdim  ExtractArgs.push_back("--extract-dwo");
1981249423Sdim
1982249423Sdim  ArgStringList StripArgs;
1983249423Sdim  StripArgs.push_back("--strip-dwo");
1984249423Sdim
1985249423Sdim  // Grabbing the output of the earlier compile step.
1986249423Sdim  StripArgs.push_back(Output.getFilename());
1987249423Sdim  ExtractArgs.push_back(Output.getFilename());
1988249423Sdim  ExtractArgs.push_back(OutFile);
1989249423Sdim
1990249423Sdim  const char *Exec =
1991249423Sdim    Args.MakeArgString(TC.GetProgramPath("objcopy"));
1992249423Sdim
1993249423Sdim  // First extract the dwo sections.
1994249423Sdim  C.addCommand(new Command(JA, T, Exec, ExtractArgs));
1995249423Sdim
1996249423Sdim  // Then remove them from the original .o file.
1997249423Sdim  C.addCommand(new Command(JA, T, Exec, StripArgs));
1998249423Sdim}
1999249423Sdim
2000263508Sdim/// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
2001263508Sdimstatic bool shouldEnableVectorizerAtOLevel(const ArgList &Args) {
2002263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
2003263508Sdim    if (A->getOption().matches(options::OPT_O4) ||
2004263508Sdim        A->getOption().matches(options::OPT_Ofast))
2005263508Sdim      return true;
2006263508Sdim
2007263508Sdim    if (A->getOption().matches(options::OPT_O0))
2008263508Sdim      return false;
2009263508Sdim
2010263508Sdim    assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
2011263508Sdim
2012263508Sdim    // Vectorize -Os.
2013263508Sdim    StringRef S(A->getValue());
2014263508Sdim    if (S == "s")
2015263508Sdim      return true;
2016263508Sdim
2017263508Sdim    // Don't vectorize -Oz.
2018263508Sdim    if (S == "z")
2019263508Sdim      return false;
2020263508Sdim
2021263508Sdim    unsigned OptLevel = 0;
2022263508Sdim    if (S.getAsInteger(10, OptLevel))
2023263508Sdim      return false;
2024263508Sdim
2025263508Sdim    return OptLevel > 1;
2026263508Sdim  }
2027263508Sdim
2028263508Sdim  return false;
2029263508Sdim}
2030263508Sdim
2031193326Sedvoid Clang::ConstructJob(Compilation &C, const JobAction &JA,
2032193326Sed                         const InputInfo &Output,
2033193326Sed                         const InputInfoList &Inputs,
2034193326Sed                         const ArgList &Args,
2035193326Sed                         const char *LinkingOutput) const {
2036205408Srdivacky  bool KernelOrKext = Args.hasArg(options::OPT_mkernel,
2037205408Srdivacky                                  options::OPT_fapple_kext);
2038201361Srdivacky  const Driver &D = getToolChain().getDriver();
2039193326Sed  ArgStringList CmdArgs;
2040193326Sed
2041193326Sed  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
2042193326Sed
2043200583Srdivacky  // Invoke ourselves in -cc1 mode.
2044200583Srdivacky  //
2045200583Srdivacky  // FIXME: Implement custom jobs for internal actions.
2046200583Srdivacky  CmdArgs.push_back("-cc1");
2047200583Srdivacky
2048198893Srdivacky  // Add the "effective" target triple.
2049193326Sed  CmdArgs.push_back("-triple");
2050212904Sdim  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
2051198893Srdivacky  CmdArgs.push_back(Args.MakeArgString(TripleStr));
2052198092Srdivacky
2053198893Srdivacky  // Select the appropriate action.
2054239462Sdim  RewriteKind rewriteKind = RK_None;
2055234353Sdim
2056193326Sed  if (isa<AnalyzeJobAction>(JA)) {
2057193326Sed    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
2058193326Sed    CmdArgs.push_back("-analyze");
2059234353Sdim  } else if (isa<MigrateJobAction>(JA)) {
2060234353Sdim    CmdArgs.push_back("-migrate");
2061193326Sed  } else if (isa<PreprocessJobAction>(JA)) {
2062193326Sed    if (Output.getType() == types::TY_Dependencies)
2063193326Sed      CmdArgs.push_back("-Eonly");
2064249423Sdim    else {
2065193326Sed      CmdArgs.push_back("-E");
2066249423Sdim      if (Args.hasArg(options::OPT_rewrite_objc) &&
2067249423Sdim          !Args.hasArg(options::OPT_g_Group))
2068249423Sdim        CmdArgs.push_back("-P");
2069249423Sdim    }
2070203955Srdivacky  } else if (isa<AssembleJobAction>(JA)) {
2071203955Srdivacky    CmdArgs.push_back("-emit-obj");
2072208600Srdivacky
2073263508Sdim    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
2074212904Sdim
2075218893Sdim    // Also ignore explicit -force_cpusubtype_ALL option.
2076218893Sdim    (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
2077193326Sed  } else if (isa<PrecompileJobAction>(JA)) {
2078212904Sdim    // Use PCH if the user requested it.
2079198398Srdivacky    bool UsePCH = D.CCCUsePCH;
2080198398Srdivacky
2081239462Sdim    if (JA.getType() == types::TY_Nothing)
2082239462Sdim      CmdArgs.push_back("-fsyntax-only");
2083239462Sdim    else if (UsePCH)
2084193326Sed      CmdArgs.push_back("-emit-pch");
2085193326Sed    else
2086193326Sed      CmdArgs.push_back("-emit-pth");
2087193326Sed  } else {
2088193326Sed    assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
2089193326Sed
2090193326Sed    if (JA.getType() == types::TY_Nothing) {
2091193326Sed      CmdArgs.push_back("-fsyntax-only");
2092210299Sed    } else if (JA.getType() == types::TY_LLVM_IR ||
2093210299Sed               JA.getType() == types::TY_LTO_IR) {
2094193326Sed      CmdArgs.push_back("-emit-llvm");
2095210299Sed    } else if (JA.getType() == types::TY_LLVM_BC ||
2096210299Sed               JA.getType() == types::TY_LTO_BC) {
2097193326Sed      CmdArgs.push_back("-emit-llvm-bc");
2098193326Sed    } else if (JA.getType() == types::TY_PP_Asm) {
2099193326Sed      CmdArgs.push_back("-S");
2100198092Srdivacky    } else if (JA.getType() == types::TY_AST) {
2101198092Srdivacky      CmdArgs.push_back("-emit-pch");
2102249423Sdim    } else if (JA.getType() == types::TY_ModuleFile) {
2103249423Sdim      CmdArgs.push_back("-module-file-info");
2104203955Srdivacky    } else if (JA.getType() == types::TY_RewrittenObjC) {
2105203955Srdivacky      CmdArgs.push_back("-rewrite-objc");
2106239462Sdim      rewriteKind = RK_NonFragile;
2107234353Sdim    } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
2108234353Sdim      CmdArgs.push_back("-rewrite-objc");
2109239462Sdim      rewriteKind = RK_Fragile;
2110203955Srdivacky    } else {
2111203955Srdivacky      assert(JA.getType() == types::TY_PP_Asm &&
2112203955Srdivacky             "Unexpected output type!");
2113193326Sed    }
2114193326Sed  }
2115193326Sed
2116193326Sed  // The make clang go fast button.
2117193326Sed  CmdArgs.push_back("-disable-free");
2118193326Sed
2119203955Srdivacky  // Disable the verification pass in -asserts builds.
2120203955Srdivacky#ifdef NDEBUG
2121203955Srdivacky  CmdArgs.push_back("-disable-llvm-verifier");
2122203955Srdivacky#endif
2123203955Srdivacky
2124193326Sed  // Set the main file name, so that debug info works even with
2125193326Sed  // -save-temps.
2126193326Sed  CmdArgs.push_back("-main-file-name");
2127249423Sdim  CmdArgs.push_back(getBaseInputName(Args, Inputs));
2128193326Sed
2129193326Sed  // Some flags which affect the language (via preprocessor
2130249423Sdim  // defines).
2131193326Sed  if (Args.hasArg(options::OPT_static))
2132193326Sed    CmdArgs.push_back("-static-define");
2133193326Sed
2134193326Sed  if (isa<AnalyzeJobAction>(JA)) {
2135198092Srdivacky    // Enable region store model by default.
2136198092Srdivacky    CmdArgs.push_back("-analyzer-store=region");
2137198092Srdivacky
2138200583Srdivacky    // Treat blocks as analysis entry points.
2139200583Srdivacky    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
2140200583Srdivacky
2141221345Sdim    CmdArgs.push_back("-analyzer-eagerly-assume");
2142221345Sdim
2143193326Sed    // Add default argument set.
2144193326Sed    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
2145221345Sdim      CmdArgs.push_back("-analyzer-checker=core");
2146218893Sdim
2147218893Sdim      if (getToolChain().getTriple().getOS() != llvm::Triple::Win32)
2148218893Sdim        CmdArgs.push_back("-analyzer-checker=unix");
2149221345Sdim
2150218893Sdim      if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
2151221345Sdim        CmdArgs.push_back("-analyzer-checker=osx");
2152234353Sdim
2153234353Sdim      CmdArgs.push_back("-analyzer-checker=deadcode");
2154234353Sdim
2155251662Sdim      if (types::isCXX(Inputs[0].getType()))
2156251662Sdim        CmdArgs.push_back("-analyzer-checker=cplusplus");
2157251662Sdim
2158234353Sdim      // Enable the following experimental checkers for testing.
2159234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
2160234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
2161234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
2162234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
2163234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
2164234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
2165193326Sed    }
2166193326Sed
2167193326Sed    // Set the output format. The default is plist, for (lame) historical
2168193326Sed    // reasons.
2169193326Sed    CmdArgs.push_back("-analyzer-output");
2170193326Sed    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
2171243830Sdim      CmdArgs.push_back(A->getValue());
2172193326Sed    else
2173193326Sed      CmdArgs.push_back("plist");
2174193326Sed
2175206084Srdivacky    // Disable the presentation of standard compiler warnings when
2176206084Srdivacky    // using --analyze.  We only want to show static analyzer diagnostics
2177206084Srdivacky    // or frontend errors.
2178206084Srdivacky    CmdArgs.push_back("-w");
2179206084Srdivacky
2180193326Sed    // Add -Xanalyzer arguments when running as analyzer.
2181193326Sed    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
2182198092Srdivacky  }
2183198092Srdivacky
2184198092Srdivacky  CheckCodeGenerationOptions(D, Args);
2185198092Srdivacky
2186251662Sdim  bool PIE = getToolChain().isPIEDefault();
2187251662Sdim  bool PIC = PIE || getToolChain().isPICDefault();
2188243830Sdim  bool IsPICLevelTwo = PIC;
2189251662Sdim
2190251662Sdim  // For the PIC and PIE flag options, this logic is different from the
2191251662Sdim  // legacy logic in very old versions of GCC, as that logic was just
2192251662Sdim  // a bug no one had ever fixed. This logic is both more rational and
2193251662Sdim  // consistent with GCC's new logic now that the bugs are fixed. The last
2194251662Sdim  // argument relating to either PIC or PIE wins, and no other argument is
2195251662Sdim  // used. If the last argument is any flavor of the '-fno-...' arguments,
2196251662Sdim  // both PIC and PIE are disabled. Any PIE option implicitly enables PIC
2197251662Sdim  // at the same level.
2198251662Sdim  Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
2199251662Sdim                                 options::OPT_fpic, options::OPT_fno_pic,
2200251662Sdim                                 options::OPT_fPIE, options::OPT_fno_PIE,
2201251662Sdim                                 options::OPT_fpie, options::OPT_fno_pie);
2202243830Sdim  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
2203243830Sdim  // is forced, then neither PIC nor PIE flags will have no effect.
2204251662Sdim  if (!getToolChain().isPICDefaultForced()) {
2205251662Sdim    if (LastPICArg) {
2206251662Sdim      Option O = LastPICArg->getOption();
2207251662Sdim      if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
2208251662Sdim          O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
2209251662Sdim        PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
2210251662Sdim        PIC = PIE || O.matches(options::OPT_fPIC) ||
2211251662Sdim              O.matches(options::OPT_fpic);
2212251662Sdim        IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
2213251662Sdim                        O.matches(options::OPT_fPIC);
2214251662Sdim      } else {
2215251662Sdim        PIE = PIC = false;
2216251662Sdim      }
2217251662Sdim    }
2218243830Sdim  }
2219193326Sed
2220263508Sdim  // Introduce a Darwin-specific hack. If the default is PIC but the flags
2221243830Sdim  // specified while enabling PIC enabled level 1 PIC, just force it back to
2222243830Sdim  // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my
2223243830Sdim  // informal testing).
2224243830Sdim  if (PIC && getToolChain().getTriple().isOSDarwin())
2225243830Sdim    IsPICLevelTwo |= getToolChain().isPICDefault();
2226239462Sdim
2227234353Sdim  // Note that these flags are trump-cards. Regardless of the order w.r.t. the
2228234353Sdim  // PIC or PIE options above, if these show up, PIC is disabled.
2229243830Sdim  llvm::Triple Triple(TripleStr);
2230249423Sdim  if (KernelOrKext &&
2231263508Sdim      (!Triple.isiOS() || Triple.isOSVersionLT(6)))
2232243830Sdim    PIC = PIE = false;
2233234353Sdim  if (Args.hasArg(options::OPT_static))
2234243830Sdim    PIC = PIE = false;
2235234353Sdim
2236243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
2237243830Sdim    // This is a very special mode. It trumps the other modes, almost no one
2238243830Sdim    // uses it, and it isn't even valid on any OS but Darwin.
2239243830Sdim    if (!getToolChain().getTriple().isOSDarwin())
2240243830Sdim      D.Diag(diag::err_drv_unsupported_opt_for_target)
2241243830Sdim        << A->getSpelling() << getToolChain().getTriple().str();
2242243830Sdim
2243243830Sdim    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
2244243830Sdim
2245199990Srdivacky    CmdArgs.push_back("-mrelocation-model");
2246243830Sdim    CmdArgs.push_back("dynamic-no-pic");
2247193326Sed
2248243830Sdim    // Only a forced PIC mode can cause the actual compile to have PIC defines
2249243830Sdim    // etc., no flags are sufficient. This behavior was selected to closely
2250243830Sdim    // match that of llvm-gcc and Apple GCC before that.
2251243830Sdim    if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) {
2252243830Sdim      CmdArgs.push_back("-pic-level");
2253243830Sdim      CmdArgs.push_back("2");
2254243830Sdim    }
2255243830Sdim  } else {
2256243830Sdim    // Currently, LLVM only knows about PIC vs. static; the PIE differences are
2257243830Sdim    // handled in Clang's IRGen by the -pie-level flag.
2258243830Sdim    CmdArgs.push_back("-mrelocation-model");
2259243830Sdim    CmdArgs.push_back(PIC ? "pic" : "static");
2260243830Sdim
2261243830Sdim    if (PIC) {
2262243830Sdim      CmdArgs.push_back("-pic-level");
2263243830Sdim      CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
2264243830Sdim      if (PIE) {
2265243830Sdim        CmdArgs.push_back("-pie-level");
2266243830Sdim        CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
2267243830Sdim      }
2268243830Sdim    }
2269193326Sed  }
2270234353Sdim
2271199990Srdivacky  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
2272199990Srdivacky                    options::OPT_fno_merge_all_constants))
2273221345Sdim    CmdArgs.push_back("-fno-merge-all-constants");
2274193326Sed
2275199990Srdivacky  // LLVM Code Generator Options.
2276199990Srdivacky
2277218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
2278218893Sdim    CmdArgs.push_back("-mregparm");
2279243830Sdim    CmdArgs.push_back(A->getValue());
2280218893Sdim  }
2281218893Sdim
2282263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
2283263508Sdim                               options::OPT_freg_struct_return)) {
2284263508Sdim    if (getToolChain().getArch() != llvm::Triple::x86) {
2285263508Sdim      D.Diag(diag::err_drv_unsupported_opt_for_target)
2286263508Sdim        << A->getSpelling() << getToolChain().getTriple().str();
2287263508Sdim    } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
2288263508Sdim      CmdArgs.push_back("-fpcc-struct-return");
2289263508Sdim    } else {
2290263508Sdim      assert(A->getOption().matches(options::OPT_freg_struct_return));
2291263508Sdim      CmdArgs.push_back("-freg-struct-return");
2292263508Sdim    }
2293263508Sdim  }
2294263508Sdim
2295221345Sdim  if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
2296221345Sdim    CmdArgs.push_back("-mrtd");
2297221345Sdim
2298234353Sdim  if (shouldUseFramePointer(Args, getToolChain().getTriple()))
2299199990Srdivacky    CmdArgs.push_back("-mdisable-fp-elim");
2300193326Sed  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
2301199990Srdivacky                    options::OPT_fno_zero_initialized_in_bss))
2302199990Srdivacky    CmdArgs.push_back("-mno-zero-initialized-in-bss");
2303251662Sdim
2304251662Sdim  bool OFastEnabled = isOptimizationLevelFast(Args);
2305251662Sdim  // If -Ofast is the optimization level, then -fstrict-aliasing should be
2306251662Sdim  // enabled.  This alias option is being used to simplify the hasFlag logic.
2307251662Sdim  OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast :
2308251662Sdim    options::OPT_fstrict_aliasing;
2309251662Sdim  if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
2310263508Sdim                    options::OPT_fno_strict_aliasing, true))
2311218893Sdim    CmdArgs.push_back("-relaxed-aliasing");
2312263508Sdim  if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
2313263508Sdim                    options::OPT_fno_struct_path_tbaa))
2314263508Sdim    CmdArgs.push_back("-no-struct-path-tbaa");
2315234353Sdim  if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
2316234353Sdim                   false))
2317234353Sdim    CmdArgs.push_back("-fstrict-enums");
2318234353Sdim  if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
2319234353Sdim                    options::OPT_fno_optimize_sibling_calls))
2320234353Sdim    CmdArgs.push_back("-mdisable-tail-calls");
2321208600Srdivacky
2322249423Sdim  // Handle segmented stacks.
2323249423Sdim  if (Args.hasArg(options::OPT_fsplit_stack))
2324249423Sdim    CmdArgs.push_back("-split-stacks");
2325251662Sdim
2326251662Sdim  // If -Ofast is the optimization level, then -ffast-math should be enabled.
2327251662Sdim  // This alias option is being used to simplify the getLastArg logic.
2328251662Sdim  OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast :
2329251662Sdim    options::OPT_ffast_math;
2330249423Sdim
2331234353Sdim  // Handle various floating point optimization flags, mapping them to the
2332234353Sdim  // appropriate LLVM code generation flags. The pattern for all of these is to
2333234353Sdim  // default off the codegen optimizations, and if any flag enables them and no
2334234353Sdim  // flag disables them after the flag enabling them, enable the codegen
2335234353Sdim  // optimization. This is complicated by several "umbrella" flags.
2336251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2337243830Sdim                               options::OPT_fno_fast_math,
2338234353Sdim                               options::OPT_ffinite_math_only,
2339234353Sdim                               options::OPT_fno_finite_math_only,
2340234353Sdim                               options::OPT_fhonor_infinities,
2341234353Sdim                               options::OPT_fno_honor_infinities))
2342243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2343243830Sdim        A->getOption().getID() != options::OPT_fno_finite_math_only &&
2344234353Sdim        A->getOption().getID() != options::OPT_fhonor_infinities)
2345234353Sdim      CmdArgs.push_back("-menable-no-infs");
2346251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2347243830Sdim                               options::OPT_fno_fast_math,
2348234353Sdim                               options::OPT_ffinite_math_only,
2349234353Sdim                               options::OPT_fno_finite_math_only,
2350234353Sdim                               options::OPT_fhonor_nans,
2351234353Sdim                               options::OPT_fno_honor_nans))
2352243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2353243830Sdim        A->getOption().getID() != options::OPT_fno_finite_math_only &&
2354234353Sdim        A->getOption().getID() != options::OPT_fhonor_nans)
2355234353Sdim      CmdArgs.push_back("-menable-no-nans");
2356234353Sdim
2357239462Sdim  // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
2358239462Sdim  bool MathErrno = getToolChain().IsMathErrnoDefault();
2359251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2360243830Sdim                               options::OPT_fno_fast_math,
2361234353Sdim                               options::OPT_fmath_errno,
2362263508Sdim                               options::OPT_fno_math_errno)) {
2363263508Sdim    // Turning on -ffast_math (with either flag) removes the need for MathErrno.
2364263508Sdim    // However, turning *off* -ffast_math merely restores the toolchain default
2365263508Sdim    // (which may be false).
2366263508Sdim    if (A->getOption().getID() == options::OPT_fno_math_errno ||
2367263508Sdim        A->getOption().getID() == options::OPT_ffast_math ||
2368263508Sdim        A->getOption().getID() == options::OPT_Ofast)
2369263508Sdim      MathErrno = false;
2370263508Sdim    else if (A->getOption().getID() == options::OPT_fmath_errno)
2371263508Sdim      MathErrno = true;
2372263508Sdim  }
2373239462Sdim  if (MathErrno)
2374239462Sdim    CmdArgs.push_back("-fmath-errno");
2375234353Sdim
2376234353Sdim  // There are several flags which require disabling very specific
2377234353Sdim  // optimizations. Any of these being disabled forces us to turn off the
2378234353Sdim  // entire set of LLVM optimizations, so collect them through all the flag
2379234353Sdim  // madness.
2380234353Sdim  bool AssociativeMath = false;
2381251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2382243830Sdim                               options::OPT_fno_fast_math,
2383234353Sdim                               options::OPT_funsafe_math_optimizations,
2384234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2385234353Sdim                               options::OPT_fassociative_math,
2386234353Sdim                               options::OPT_fno_associative_math))
2387243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2388243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2389234353Sdim        A->getOption().getID() != options::OPT_fno_associative_math)
2390234353Sdim      AssociativeMath = true;
2391234353Sdim  bool ReciprocalMath = false;
2392251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2393243830Sdim                               options::OPT_fno_fast_math,
2394234353Sdim                               options::OPT_funsafe_math_optimizations,
2395234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2396234353Sdim                               options::OPT_freciprocal_math,
2397234353Sdim                               options::OPT_fno_reciprocal_math))
2398243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2399243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2400234353Sdim        A->getOption().getID() != options::OPT_fno_reciprocal_math)
2401234353Sdim      ReciprocalMath = true;
2402234353Sdim  bool SignedZeros = true;
2403251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2404243830Sdim                               options::OPT_fno_fast_math,
2405234353Sdim                               options::OPT_funsafe_math_optimizations,
2406234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2407234353Sdim                               options::OPT_fsigned_zeros,
2408234353Sdim                               options::OPT_fno_signed_zeros))
2409243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2410243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2411234353Sdim        A->getOption().getID() != options::OPT_fsigned_zeros)
2412234353Sdim      SignedZeros = false;
2413234353Sdim  bool TrappingMath = true;
2414251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2415243830Sdim                               options::OPT_fno_fast_math,
2416234353Sdim                               options::OPT_funsafe_math_optimizations,
2417234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2418234353Sdim                               options::OPT_ftrapping_math,
2419234353Sdim                               options::OPT_fno_trapping_math))
2420243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2421243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2422234353Sdim        A->getOption().getID() != options::OPT_ftrapping_math)
2423234353Sdim      TrappingMath = false;
2424234353Sdim  if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
2425234353Sdim      !TrappingMath)
2426234353Sdim    CmdArgs.push_back("-menable-unsafe-fp-math");
2427234353Sdim
2428239462Sdim
2429239462Sdim  // Validate and pass through -fp-contract option.
2430251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2431243830Sdim                               options::OPT_fno_fast_math,
2432239462Sdim                               options::OPT_ffp_contract)) {
2433239462Sdim    if (A->getOption().getID() == options::OPT_ffp_contract) {
2434243830Sdim      StringRef Val = A->getValue();
2435239462Sdim      if (Val == "fast" || Val == "on" || Val == "off") {
2436239462Sdim        CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
2437239462Sdim      } else {
2438239462Sdim        D.Diag(diag::err_drv_unsupported_option_argument)
2439239462Sdim          << A->getOption().getName() << Val;
2440239462Sdim      }
2441251662Sdim    } else if (A->getOption().matches(options::OPT_ffast_math) ||
2442251662Sdim               (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
2443239462Sdim      // If fast-math is set then set the fp-contract mode to fast.
2444239462Sdim      CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
2445239462Sdim    }
2446239462Sdim  }
2447239462Sdim
2448239462Sdim  // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
2449239462Sdim  // and if we find them, tell the frontend to provide the appropriate
2450239462Sdim  // preprocessor macros. This is distinct from enabling any optimizations as
2451239462Sdim  // these options induce language changes which must survive serialization
2452239462Sdim  // and deserialization, etc.
2453251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2454251662Sdim                               options::OPT_fno_fast_math))
2455251662Sdim      if (!A->getOption().matches(options::OPT_fno_fast_math))
2456251662Sdim        CmdArgs.push_back("-ffast-math");
2457243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math))
2458243830Sdim    if (A->getOption().matches(options::OPT_ffinite_math_only))
2459243830Sdim      CmdArgs.push_back("-ffinite-math-only");
2460234353Sdim
2461208600Srdivacky  // Decide whether to use verbose asm. Verbose assembly is the default on
2462208600Srdivacky  // toolchains which have the integrated assembler on by default.
2463208600Srdivacky  bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
2464208600Srdivacky  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
2465218893Sdim                   IsVerboseAsmDefault) ||
2466208600Srdivacky      Args.hasArg(options::OPT_dA))
2467199990Srdivacky    CmdArgs.push_back("-masm-verbose");
2468208600Srdivacky
2469199990Srdivacky  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
2470199990Srdivacky    CmdArgs.push_back("-mdebug-pass");
2471199990Srdivacky    CmdArgs.push_back("Structure");
2472199990Srdivacky  }
2473199990Srdivacky  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
2474199990Srdivacky    CmdArgs.push_back("-mdebug-pass");
2475199990Srdivacky    CmdArgs.push_back("Arguments");
2476199990Srdivacky  }
2477198092Srdivacky
2478204643Srdivacky  // Enable -mconstructor-aliases except on darwin, where we have to
2479204643Srdivacky  // work around a linker bug;  see <rdar://problem/7651567>.
2480226633Sdim  if (!getToolChain().getTriple().isOSDarwin())
2481204643Srdivacky    CmdArgs.push_back("-mconstructor-aliases");
2482204643Srdivacky
2483221345Sdim  // Darwin's kernel doesn't support guard variables; just die if we
2484221345Sdim  // try to use them.
2485226633Sdim  if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
2486221345Sdim    CmdArgs.push_back("-fforbid-guard-variables");
2487221345Sdim
2488218893Sdim  if (Args.hasArg(options::OPT_mms_bitfields)) {
2489218893Sdim    CmdArgs.push_back("-mms-bitfields");
2490218893Sdim  }
2491218893Sdim
2492198092Srdivacky  // This is a coarse approximation of what llvm-gcc actually does, both
2493198092Srdivacky  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
2494198092Srdivacky  // complicated ways.
2495198092Srdivacky  bool AsynchronousUnwindTables =
2496198092Srdivacky    Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
2497198092Srdivacky                 options::OPT_fno_asynchronous_unwind_tables,
2498198092Srdivacky                 getToolChain().IsUnwindTablesDefault() &&
2499205408Srdivacky                 !KernelOrKext);
2500198092Srdivacky  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
2501198092Srdivacky                   AsynchronousUnwindTables))
2502199990Srdivacky    CmdArgs.push_back("-munwind-tables");
2503193326Sed
2504249423Sdim  getToolChain().addClangTargetOptions(Args, CmdArgs);
2505239462Sdim
2506199990Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
2507199990Srdivacky    CmdArgs.push_back("-mlimit-float-precision");
2508243830Sdim    CmdArgs.push_back(A->getValue());
2509199990Srdivacky  }
2510199990Srdivacky
2511193326Sed  // FIXME: Handle -mtune=.
2512193326Sed  (void) Args.hasArg(options::OPT_mtune_EQ);
2513193326Sed
2514198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
2515199990Srdivacky    CmdArgs.push_back("-mcode-model");
2516243830Sdim    CmdArgs.push_back(A->getValue());
2517193326Sed  }
2518193326Sed
2519263508Sdim  // Add the target cpu
2520263508Sdim  std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
2521263508Sdim  llvm::Triple ETriple(ETripleStr);
2522263508Sdim  std::string CPU = getCPUName(Args, ETriple);
2523263508Sdim  if (!CPU.empty()) {
2524263508Sdim    CmdArgs.push_back("-target-cpu");
2525263508Sdim    CmdArgs.push_back(Args.MakeArgString(CPU));
2526263508Sdim  }
2527263508Sdim
2528263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
2529263508Sdim    CmdArgs.push_back("-mfpmath");
2530263508Sdim    CmdArgs.push_back(A->getValue());
2531263508Sdim  }
2532263508Sdim
2533263508Sdim  // Add the target features
2534263508Sdim  getTargetFeatures(D, ETriple, Args, CmdArgs);
2535263508Sdim
2536263508Sdim  // Add target specific flags.
2537263508Sdim  switch(getToolChain().getArch()) {
2538198092Srdivacky  default:
2539198092Srdivacky    break;
2540193326Sed
2541198092Srdivacky  case llvm::Triple::arm:
2542198092Srdivacky  case llvm::Triple::thumb:
2543221345Sdim    AddARMTargetArgs(Args, CmdArgs, KernelOrKext);
2544198092Srdivacky    break;
2545193326Sed
2546204643Srdivacky  case llvm::Triple::mips:
2547204643Srdivacky  case llvm::Triple::mipsel:
2548226633Sdim  case llvm::Triple::mips64:
2549226633Sdim  case llvm::Triple::mips64el:
2550204643Srdivacky    AddMIPSTargetArgs(Args, CmdArgs);
2551204643Srdivacky    break;
2552204643Srdivacky
2553218893Sdim  case llvm::Triple::sparc:
2554218893Sdim    AddSparcTargetArgs(Args, CmdArgs);
2555218893Sdim    break;
2556218893Sdim
2557198092Srdivacky  case llvm::Triple::x86:
2558198092Srdivacky  case llvm::Triple::x86_64:
2559198092Srdivacky    AddX86TargetArgs(Args, CmdArgs);
2560198092Srdivacky    break;
2561234353Sdim
2562234353Sdim  case llvm::Triple::hexagon:
2563234353Sdim    AddHexagonTargetArgs(Args, CmdArgs);
2564234353Sdim    break;
2565193326Sed  }
2566193326Sed
2567263508Sdim  // Add clang-cl arguments.
2568263508Sdim  if (getToolChain().getDriver().IsCLMode())
2569263508Sdim    AddClangCLArgs(Args, CmdArgs);
2570234353Sdim
2571212904Sdim  // Pass the linker version in use.
2572212904Sdim  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
2573212904Sdim    CmdArgs.push_back("-target-linker-version");
2574243830Sdim    CmdArgs.push_back(A->getValue());
2575212904Sdim  }
2576212904Sdim
2577249423Sdim  if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
2578210299Sed    CmdArgs.push_back("-momit-leaf-frame-pointer");
2579210299Sed
2580208600Srdivacky  // Explicitly error on some things we know we don't support and can't just
2581208600Srdivacky  // ignore.
2582208600Srdivacky  types::ID InputType = Inputs[0].getType();
2583218893Sdim  if (!Args.hasArg(options::OPT_fallow_unsupported)) {
2584218893Sdim    Arg *Unsupported;
2585218893Sdim    if (types::isCXX(InputType) &&
2586226633Sdim        getToolChain().getTriple().isOSDarwin() &&
2587263508Sdim        getToolChain().getArch() == llvm::Triple::x86) {
2588226633Sdim      if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
2589226633Sdim          (Unsupported = Args.getLastArg(options::OPT_mkernel)))
2590226633Sdim        D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
2591218893Sdim          << Unsupported->getOption().getName();
2592218893Sdim    }
2593208600Srdivacky  }
2594208600Srdivacky
2595193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_v);
2596212904Sdim  Args.AddLastArg(CmdArgs, options::OPT_H);
2597226633Sdim  if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
2598218893Sdim    CmdArgs.push_back("-header-include-file");
2599218893Sdim    CmdArgs.push_back(D.CCPrintHeadersFilename ?
2600218893Sdim                      D.CCPrintHeadersFilename : "-");
2601218893Sdim  }
2602193326Sed  Args.AddLastArg(CmdArgs, options::OPT_P);
2603198092Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
2604193326Sed
2605226633Sdim  if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
2606221345Sdim    CmdArgs.push_back("-diagnostic-log-file");
2607221345Sdim    CmdArgs.push_back(D.CCLogDiagnosticsFilename ?
2608221345Sdim                      D.CCLogDiagnosticsFilename : "-");
2609221345Sdim  }
2610221345Sdim
2611249423Sdim  // Use the last option from "-g" group. "-gline-tables-only"
2612249423Sdim  // is preserved, all other debug options are substituted with "-g".
2613204962Srdivacky  Args.ClaimAllArgs(options::OPT_g_Group);
2614239462Sdim  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
2615249423Sdim    if (A->getOption().matches(options::OPT_gline_tables_only))
2616239462Sdim      CmdArgs.push_back("-gline-tables-only");
2617263508Sdim    else if (A->getOption().matches(options::OPT_gdwarf_2))
2618263508Sdim      CmdArgs.push_back("-gdwarf-2");
2619263508Sdim    else if (A->getOption().matches(options::OPT_gdwarf_3))
2620263508Sdim      CmdArgs.push_back("-gdwarf-3");
2621263508Sdim    else if (A->getOption().matches(options::OPT_gdwarf_4))
2622263508Sdim      CmdArgs.push_back("-gdwarf-4");
2623249423Sdim    else if (!A->getOption().matches(options::OPT_g0) &&
2624263508Sdim             !A->getOption().matches(options::OPT_ggdb0)) {
2625264464Sdim      // Default is dwarf-2 for darwin and FreeBSD.
2626263984Sdim      const llvm::Triple &Triple = getToolChain().getTriple();
2627264464Sdim      if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::FreeBSD)
2628263508Sdim        CmdArgs.push_back("-gdwarf-2");
2629263508Sdim      else
2630263508Sdim        CmdArgs.push_back("-g");
2631263508Sdim    }
2632239462Sdim  }
2633193326Sed
2634239462Sdim  // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
2635239462Sdim  Args.ClaimAllArgs(options::OPT_g_flags_Group);
2636243830Sdim  if (Args.hasArg(options::OPT_gcolumn_info))
2637243830Sdim    CmdArgs.push_back("-dwarf-column-info");
2638239462Sdim
2639263508Sdim  // FIXME: Move backend command line options to the module.
2640249423Sdim  // -gsplit-dwarf should turn on -g and enable the backend dwarf
2641249423Sdim  // splitting and extraction.
2642249423Sdim  // FIXME: Currently only works on Linux.
2643263508Sdim  if (getToolChain().getTriple().isOSLinux() &&
2644249423Sdim      Args.hasArg(options::OPT_gsplit_dwarf)) {
2645249423Sdim    CmdArgs.push_back("-g");
2646249423Sdim    CmdArgs.push_back("-backend-option");
2647249423Sdim    CmdArgs.push_back("-split-dwarf=Enable");
2648249423Sdim  }
2649249423Sdim
2650263508Sdim  // -ggnu-pubnames turns on gnu style pubnames in the backend.
2651263508Sdim  if (Args.hasArg(options::OPT_ggnu_pubnames)) {
2652263508Sdim    CmdArgs.push_back("-backend-option");
2653263508Sdim    CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
2654263508Sdim  }
2655263508Sdim
2656263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fdebug_types_section);
2657263508Sdim
2658208600Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
2659208600Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
2660208600Srdivacky
2661210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
2662210299Sed
2663221345Sdim  if (Args.hasArg(options::OPT_ftest_coverage) ||
2664221345Sdim      Args.hasArg(options::OPT_coverage))
2665221345Sdim    CmdArgs.push_back("-femit-coverage-notes");
2666221345Sdim  if (Args.hasArg(options::OPT_fprofile_arcs) ||
2667221345Sdim      Args.hasArg(options::OPT_coverage))
2668221345Sdim    CmdArgs.push_back("-femit-coverage-data");
2669221345Sdim
2670223017Sdim  if (C.getArgs().hasArg(options::OPT_c) ||
2671223017Sdim      C.getArgs().hasArg(options::OPT_S)) {
2672223017Sdim    if (Output.isFilename()) {
2673223017Sdim      CmdArgs.push_back("-coverage-file");
2674249423Sdim      SmallString<128> CoverageFilename(Output.getFilename());
2675249423Sdim      if (llvm::sys::path::is_relative(CoverageFilename.str())) {
2676263508Sdim        SmallString<128> Pwd;
2677263508Sdim        if (!llvm::sys::fs::current_path(Pwd)) {
2678263508Sdim          llvm::sys::path::append(Pwd, CoverageFilename.str());
2679263508Sdim          CoverageFilename.swap(Pwd);
2680249423Sdim        }
2681249423Sdim      }
2682249423Sdim      CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
2683223017Sdim    }
2684223017Sdim  }
2685223017Sdim
2686226633Sdim  // Pass options for controlling the default header search paths.
2687226633Sdim  if (Args.hasArg(options::OPT_nostdinc)) {
2688226633Sdim    CmdArgs.push_back("-nostdsysteminc");
2689226633Sdim    CmdArgs.push_back("-nobuiltininc");
2690226633Sdim  } else {
2691226633Sdim    if (Args.hasArg(options::OPT_nostdlibinc))
2692226633Sdim        CmdArgs.push_back("-nostdsysteminc");
2693226633Sdim    Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
2694226633Sdim    Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
2695226633Sdim  }
2696193326Sed
2697200583Srdivacky  // Pass the path to compiler resource files.
2698200583Srdivacky  CmdArgs.push_back("-resource-dir");
2699202879Srdivacky  CmdArgs.push_back(D.ResourceDir.c_str());
2700193326Sed
2701218893Sdim  Args.AddLastArg(CmdArgs, options::OPT_working_directory);
2702218893Sdim
2703234353Sdim  bool ARCMTEnabled = false;
2704263508Sdim  if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
2705224145Sdim    if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
2706224145Sdim                                       options::OPT_ccc_arcmt_modify,
2707224145Sdim                                       options::OPT_ccc_arcmt_migrate)) {
2708234353Sdim      ARCMTEnabled = true;
2709224145Sdim      switch (A->getOption().getID()) {
2710224145Sdim      default:
2711224145Sdim        llvm_unreachable("missed a case");
2712224145Sdim      case options::OPT_ccc_arcmt_check:
2713224145Sdim        CmdArgs.push_back("-arcmt-check");
2714224145Sdim        break;
2715224145Sdim      case options::OPT_ccc_arcmt_modify:
2716224145Sdim        CmdArgs.push_back("-arcmt-modify");
2717224145Sdim        break;
2718224145Sdim      case options::OPT_ccc_arcmt_migrate:
2719224145Sdim        CmdArgs.push_back("-arcmt-migrate");
2720234353Sdim        CmdArgs.push_back("-mt-migrate-directory");
2721243830Sdim        CmdArgs.push_back(A->getValue());
2722226633Sdim
2723226633Sdim        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
2724226633Sdim        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
2725224145Sdim        break;
2726224145Sdim      }
2727224145Sdim    }
2728263508Sdim  } else {
2729263508Sdim    Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
2730263508Sdim    Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
2731263508Sdim    Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
2732224145Sdim  }
2733226633Sdim
2734234353Sdim  if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
2735234353Sdim    if (ARCMTEnabled) {
2736234353Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
2737234353Sdim        << A->getAsString(Args) << "-ccc-arcmt-migrate";
2738234353Sdim    }
2739234353Sdim    CmdArgs.push_back("-mt-migrate-directory");
2740243830Sdim    CmdArgs.push_back(A->getValue());
2741234353Sdim
2742234353Sdim    if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
2743263508Sdim                     options::OPT_objcmt_migrate_subscripting,
2744263508Sdim                     options::OPT_objcmt_migrate_property)) {
2745234353Sdim      // None specified, means enable them all.
2746234353Sdim      CmdArgs.push_back("-objcmt-migrate-literals");
2747234353Sdim      CmdArgs.push_back("-objcmt-migrate-subscripting");
2748263508Sdim      CmdArgs.push_back("-objcmt-migrate-property");
2749234353Sdim    } else {
2750234353Sdim      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
2751234353Sdim      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
2752263508Sdim      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
2753234353Sdim    }
2754263508Sdim  } else {
2755263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
2756263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
2757263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
2758263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
2759263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
2760263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
2761263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
2762263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
2763263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
2764263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
2765263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
2766263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
2767263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
2768263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_white_list_dir_path);
2769234353Sdim  }
2770234353Sdim
2771193326Sed  // Add preprocessing options like -I, -D, etc. if we are using the
2772193326Sed  // preprocessor.
2773193326Sed  //
2774193326Sed  // FIXME: Support -fpreprocessed
2775193326Sed  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
2776249423Sdim    AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
2777193326Sed
2778226633Sdim  // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
2779226633Sdim  // that "The compiler can only warn and ignore the option if not recognized".
2780226633Sdim  // When building with ccache, it will pass -D options to clang even on
2781226633Sdim  // preprocessed inputs and configure concludes that -fPIC is not supported.
2782226633Sdim  Args.ClaimAllArgs(options::OPT_D);
2783226633Sdim
2784263508Sdim  // Manually translate -O4 to -O3; let clang reject others.
2785193326Sed  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
2786263508Sdim    if (A->getOption().matches(options::OPT_O4)) {
2787193326Sed      CmdArgs.push_back("-O3");
2788263508Sdim      D.Diag(diag::warn_O4_is_O3);
2789263508Sdim    } else {
2790193326Sed      A->render(Args, CmdArgs);
2791263508Sdim    }
2792193326Sed  }
2793193326Sed
2794249423Sdim  // Don't warn about unused -flto.  This can happen when we're preprocessing or
2795249423Sdim  // precompiling.
2796249423Sdim  Args.ClaimAllArgs(options::OPT_flto);
2797249423Sdim
2798198893Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
2799239462Sdim  if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
2800239462Sdim    CmdArgs.push_back("-pedantic");
2801198893Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
2802193326Sed  Args.AddLastArg(CmdArgs, options::OPT_w);
2803193326Sed
2804193326Sed  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
2805263508Sdim  // (-ansi is equivalent to -std=c89 or -std=c++98).
2806193326Sed  //
2807193326Sed  // If a std is supplied, only add -trigraphs if it follows the
2808193326Sed  // option.
2809193326Sed  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
2810193326Sed    if (Std->getOption().matches(options::OPT_ansi))
2811198398Srdivacky      if (types::isCXX(InputType))
2812198893Srdivacky        CmdArgs.push_back("-std=c++98");
2813198398Srdivacky      else
2814198893Srdivacky        CmdArgs.push_back("-std=c89");
2815193326Sed    else
2816193326Sed      Std->render(Args, CmdArgs);
2817193326Sed
2818210299Sed    if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
2819210299Sed                                 options::OPT_trigraphs))
2820210299Sed      if (A != Std)
2821193326Sed        A->render(Args, CmdArgs);
2822193326Sed  } else {
2823193326Sed    // Honor -std-default.
2824203955Srdivacky    //
2825203955Srdivacky    // FIXME: Clang doesn't correctly handle -std= when the input language
2826203955Srdivacky    // doesn't match. For the time being just ignore this for C++ inputs;
2827203955Srdivacky    // eventually we want to do all the standard defaulting here instead of
2828203955Srdivacky    // splitting it between the driver and clang -cc1.
2829203955Srdivacky    if (!types::isCXX(InputType))
2830243830Sdim      Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
2831243830Sdim                                "-std=", /*Joined=*/true);
2832243830Sdim    else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32)
2833243830Sdim      CmdArgs.push_back("-std=c++11");
2834243830Sdim
2835193326Sed    Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
2836193326Sed  }
2837193326Sed
2838263508Sdim  // GCC's behavior for -Wwrite-strings is a bit strange:
2839263508Sdim  //  * In C, this "warning flag" changes the types of string literals from
2840263508Sdim  //    'char[N]' to 'const char[N]', and thus triggers an unrelated warning
2841263508Sdim  //    for the discarded qualifier.
2842263508Sdim  //  * In C++, this is just a normal warning flag.
2843263508Sdim  //
2844263508Sdim  // Implementing this warning correctly in C is hard, so we follow GCC's
2845263508Sdim  // behavior for now. FIXME: Directly diagnose uses of a string literal as
2846263508Sdim  // a non-const char* in C, rather than using this crude hack.
2847263508Sdim  if (!types::isCXX(InputType)) {
2848263508Sdim    DiagnosticsEngine::Level DiagLevel = D.getDiags().getDiagnosticLevel(
2849263508Sdim        diag::warn_deprecated_string_literal_conversion_c, SourceLocation());
2850263508Sdim    if (DiagLevel > DiagnosticsEngine::Ignored)
2851263508Sdim      CmdArgs.push_back("-fconst-strings");
2852221345Sdim  }
2853221345Sdim
2854221345Sdim  // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
2855221345Sdim  // during C++ compilation, which it is by default. GCC keeps this define even
2856221345Sdim  // in the presence of '-w', match this behavior bug-for-bug.
2857221345Sdim  if (types::isCXX(InputType) &&
2858221345Sdim      Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
2859221345Sdim                   true)) {
2860221345Sdim    CmdArgs.push_back("-fdeprecated-macro");
2861221345Sdim  }
2862221345Sdim
2863208600Srdivacky  // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
2864208600Srdivacky  if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
2865208600Srdivacky    if (Asm->getOption().matches(options::OPT_fasm))
2866208600Srdivacky      CmdArgs.push_back("-fgnu-keywords");
2867208600Srdivacky    else
2868208600Srdivacky      CmdArgs.push_back("-fno-gnu-keywords");
2869208600Srdivacky  }
2870208600Srdivacky
2871221345Sdim  if (ShouldDisableCFI(Args, getToolChain()))
2872221345Sdim    CmdArgs.push_back("-fno-dwarf2-cfi-asm");
2873221345Sdim
2874234353Sdim  if (ShouldDisableDwarfDirectory(Args, getToolChain()))
2875234353Sdim    CmdArgs.push_back("-fno-dwarf-directory-asm");
2876234353Sdim
2877251662Sdim  if (ShouldDisableAutolink(Args, getToolChain()))
2878251662Sdim    CmdArgs.push_back("-fno-autolink");
2879251662Sdim
2880249423Sdim  // Add in -fdebug-compilation-dir if necessary.
2881249423Sdim  addDebugCompDirArg(Args, CmdArgs);
2882234353Sdim
2883234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
2884234353Sdim                               options::OPT_ftemplate_depth_EQ)) {
2885193326Sed    CmdArgs.push_back("-ftemplate-depth");
2886243830Sdim    CmdArgs.push_back(A->getValue());
2887193326Sed  }
2888193326Sed
2889263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
2890263508Sdim    CmdArgs.push_back("-foperator-arrow-depth");
2891263508Sdim    CmdArgs.push_back(A->getValue());
2892263508Sdim  }
2893263508Sdim
2894234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
2895234353Sdim    CmdArgs.push_back("-fconstexpr-depth");
2896243830Sdim    CmdArgs.push_back(A->getValue());
2897234353Sdim  }
2898234353Sdim
2899263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
2900263508Sdim    CmdArgs.push_back("-fconstexpr-steps");
2901263508Sdim    CmdArgs.push_back(A->getValue());
2902263508Sdim  }
2903263508Sdim
2904249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
2905249423Sdim    CmdArgs.push_back("-fbracket-depth");
2906249423Sdim    CmdArgs.push_back(A->getValue());
2907249423Sdim  }
2908249423Sdim
2909218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
2910218893Sdim                               options::OPT_Wlarge_by_value_copy_def)) {
2911239462Sdim    if (A->getNumValues()) {
2912243830Sdim      StringRef bytes = A->getValue();
2913239462Sdim      CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
2914239462Sdim    } else
2915239462Sdim      CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
2916218893Sdim  }
2917218893Sdim
2918239462Sdim
2919243830Sdim  if (Args.hasArg(options::OPT_relocatable_pch))
2920199990Srdivacky    CmdArgs.push_back("-relocatable-pch");
2921198092Srdivacky
2922198893Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
2923198893Srdivacky    CmdArgs.push_back("-fconstant-string-class");
2924243830Sdim    CmdArgs.push_back(A->getValue());
2925198893Srdivacky  }
2926198092Srdivacky
2927202379Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
2928202379Srdivacky    CmdArgs.push_back("-ftabstop");
2929243830Sdim    CmdArgs.push_back(A->getValue());
2930202379Srdivacky  }
2931202379Srdivacky
2932207619Srdivacky  CmdArgs.push_back("-ferror-limit");
2933207619Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
2934243830Sdim    CmdArgs.push_back(A->getValue());
2935207619Srdivacky  else
2936207619Srdivacky    CmdArgs.push_back("19");
2937207619Srdivacky
2938208600Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
2939208600Srdivacky    CmdArgs.push_back("-fmacro-backtrace-limit");
2940243830Sdim    CmdArgs.push_back(A->getValue());
2941208600Srdivacky  }
2942208600Srdivacky
2943208600Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
2944208600Srdivacky    CmdArgs.push_back("-ftemplate-backtrace-limit");
2945243830Sdim    CmdArgs.push_back(A->getValue());
2946208600Srdivacky  }
2947208600Srdivacky
2948234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
2949234353Sdim    CmdArgs.push_back("-fconstexpr-backtrace-limit");
2950243830Sdim    CmdArgs.push_back(A->getValue());
2951234353Sdim  }
2952234353Sdim
2953198893Srdivacky  // Pass -fmessage-length=.
2954199990Srdivacky  CmdArgs.push_back("-fmessage-length");
2955198893Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
2956243830Sdim    CmdArgs.push_back(A->getValue());
2957198893Srdivacky  } else {
2958198893Srdivacky    // If -fmessage-length=N was not specified, determine whether this is a
2959198893Srdivacky    // terminal and, if so, implicitly define -fmessage-length appropriately.
2960198893Srdivacky    unsigned N = llvm::sys::Process::StandardErrColumns();
2961226633Sdim    CmdArgs.push_back(Args.MakeArgString(Twine(N)));
2962198893Srdivacky  }
2963198893Srdivacky
2964249423Sdim  // -fvisibility= and -fvisibility-ms-compat are of a piece.
2965249423Sdim  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
2966249423Sdim                                     options::OPT_fvisibility_ms_compat)) {
2967249423Sdim    if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
2968249423Sdim      CmdArgs.push_back("-fvisibility");
2969249423Sdim      CmdArgs.push_back(A->getValue());
2970249423Sdim    } else {
2971249423Sdim      assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
2972249423Sdim      CmdArgs.push_back("-fvisibility");
2973249423Sdim      CmdArgs.push_back("hidden");
2974249423Sdim      CmdArgs.push_back("-ftype-visibility");
2975249423Sdim      CmdArgs.push_back("default");
2976249423Sdim    }
2977200583Srdivacky  }
2978200583Srdivacky
2979210299Sed  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
2980218893Sdim
2981239462Sdim  Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
2982239462Sdim
2983205408Srdivacky  // -fhosted is default.
2984234353Sdim  if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
2985234353Sdim      KernelOrKext)
2986205408Srdivacky    CmdArgs.push_back("-ffreestanding");
2987205408Srdivacky
2988200583Srdivacky  // Forward -f (flag) options which we can pass directly.
2989193326Sed  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
2990218893Sdim  Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
2991193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
2992269011Semaste  Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
2993269011Semaste  Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
2994234353Sdim  Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
2995263508Sdim  // AltiVec language extensions aren't relevant for assembling.
2996263508Sdim  if (!isa<PreprocessJobAction>(JA) ||
2997263508Sdim      Output.getType() != types::TY_PP_Asm)
2998263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_faltivec);
2999239462Sdim  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
3000239462Sdim  Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
3001234353Sdim
3002263508Sdim  const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
3003243830Sdim  Sanitize.addArgs(Args, CmdArgs);
3004243830Sdim
3005249423Sdim  if (!Args.hasFlag(options::OPT_fsanitize_recover,
3006249423Sdim                    options::OPT_fno_sanitize_recover,
3007249423Sdim                    true))
3008249423Sdim    CmdArgs.push_back("-fno-sanitize-recover");
3009249423Sdim
3010249423Sdim  if (Args.hasArg(options::OPT_fcatch_undefined_behavior) ||
3011249423Sdim      Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
3012249423Sdim                   options::OPT_fno_sanitize_undefined_trap_on_error, false))
3013249423Sdim    CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
3014249423Sdim
3015249423Sdim  // Report an error for -faltivec on anything other than PowerPC.
3016234353Sdim  if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
3017263508Sdim    if (!(getToolChain().getArch() == llvm::Triple::ppc ||
3018263508Sdim          getToolChain().getArch() == llvm::Triple::ppc64 ||
3019263508Sdim          getToolChain().getArch() == llvm::Triple::ppc64le))
3020234353Sdim      D.Diag(diag::err_drv_argument_only_allowed_with)
3021263508Sdim        << A->getAsString(Args) << "ppc/ppc64/ppc64le";
3022234353Sdim
3023221345Sdim  if (getToolChain().SupportsProfiling())
3024221345Sdim    Args.AddLastArg(CmdArgs, options::OPT_pg);
3025205408Srdivacky
3026205408Srdivacky  // -flax-vector-conversions is default.
3027205408Srdivacky  if (!Args.hasFlag(options::OPT_flax_vector_conversions,
3028205408Srdivacky                    options::OPT_fno_lax_vector_conversions))
3029205408Srdivacky    CmdArgs.push_back("-fno-lax-vector-conversions");
3030205408Srdivacky
3031218893Sdim  if (Args.getLastArg(options::OPT_fapple_kext))
3032218893Sdim    CmdArgs.push_back("-fapple-kext");
3033218893Sdim
3034239462Sdim  if (Args.hasFlag(options::OPT_frewrite_includes,
3035239462Sdim                   options::OPT_fno_rewrite_includes, false))
3036239462Sdim    CmdArgs.push_back("-frewrite-includes");
3037239462Sdim
3038193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
3039193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
3040212904Sdim  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
3041193326Sed  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
3042193326Sed  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
3043218893Sdim
3044218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
3045218893Sdim    CmdArgs.push_back("-ftrapv-handler");
3046243830Sdim    CmdArgs.push_back(A->getValue());
3047218893Sdim  }
3048218893Sdim
3049234353Sdim  Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
3050221345Sdim
3051221345Sdim  // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
3052221345Sdim  // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
3053221345Sdim  if (Arg *A = Args.getLastArg(options::OPT_fwrapv,
3054221345Sdim                               options::OPT_fno_wrapv)) {
3055221345Sdim    if (A->getOption().matches(options::OPT_fwrapv))
3056221345Sdim      CmdArgs.push_back("-fwrapv");
3057221345Sdim  } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
3058221345Sdim                                      options::OPT_fno_strict_overflow)) {
3059221345Sdim    if (A->getOption().matches(options::OPT_fno_strict_overflow))
3060221345Sdim      CmdArgs.push_back("-fwrapv");
3061221345Sdim  }
3062263508Sdim
3063263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
3064263508Sdim                               options::OPT_fno_reroll_loops))
3065263508Sdim    if (A->getOption().matches(options::OPT_freroll_loops))
3066263508Sdim      CmdArgs.push_back("-freroll-loops");
3067263508Sdim
3068193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
3069263508Sdim  Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
3070263508Sdim                  options::OPT_fno_unroll_loops);
3071193326Sed
3072198092Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_pthread);
3073198092Srdivacky
3074243830Sdim
3075199482Srdivacky  // -stack-protector=0 is default.
3076199482Srdivacky  unsigned StackProtectorLevel = 0;
3077195341Sed  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
3078195341Sed                               options::OPT_fstack_protector_all,
3079195341Sed                               options::OPT_fstack_protector)) {
3080199482Srdivacky    if (A->getOption().matches(options::OPT_fstack_protector))
3081199482Srdivacky      StackProtectorLevel = 1;
3082199482Srdivacky    else if (A->getOption().matches(options::OPT_fstack_protector_all))
3083199482Srdivacky      StackProtectorLevel = 2;
3084226633Sdim  } else {
3085226633Sdim    StackProtectorLevel =
3086226633Sdim      getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
3087226633Sdim  }
3088199482Srdivacky  if (StackProtectorLevel) {
3089199482Srdivacky    CmdArgs.push_back("-stack-protector");
3090226633Sdim    CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
3091195341Sed  }
3092195341Sed
3093243830Sdim  // --param ssp-buffer-size=
3094243830Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT__param),
3095243830Sdim       ie = Args.filtered_end(); it != ie; ++it) {
3096243830Sdim    StringRef Str((*it)->getValue());
3097243830Sdim    if (Str.startswith("ssp-buffer-size=")) {
3098243830Sdim      if (StackProtectorLevel) {
3099243830Sdim        CmdArgs.push_back("-stack-protector-buffer-size");
3100243830Sdim        // FIXME: Verify the argument is a valid integer.
3101243830Sdim        CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
3102243830Sdim      }
3103243830Sdim      (*it)->claim();
3104243830Sdim    }
3105243830Sdim  }
3106243830Sdim
3107223017Sdim  // Translate -mstackrealign
3108234353Sdim  if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
3109234353Sdim                   false)) {
3110223017Sdim    CmdArgs.push_back("-backend-option");
3111223017Sdim    CmdArgs.push_back("-force-align-stack");
3112223017Sdim  }
3113234353Sdim  if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign,
3114234353Sdim                   false)) {
3115234353Sdim    CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
3116234353Sdim  }
3117226633Sdim
3118234353Sdim  if (Args.hasArg(options::OPT_mstack_alignment)) {
3119234353Sdim    StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
3120234353Sdim    CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
3121234353Sdim  }
3122249423Sdim  // -mkernel implies -mstrict-align; don't add the redundant option.
3123263508Sdim  if (!KernelOrKext) {
3124263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
3125263508Sdim                                 options::OPT_munaligned_access)) {
3126263508Sdim      if (A->getOption().matches(options::OPT_mno_unaligned_access)) {
3127263508Sdim        CmdArgs.push_back("-backend-option");
3128263508Sdim        CmdArgs.push_back("-arm-strict-align");
3129263508Sdim      } else {
3130263508Sdim        CmdArgs.push_back("-backend-option");
3131263508Sdim        CmdArgs.push_back("-arm-no-strict-align");
3132263508Sdim      }
3133263508Sdim    }
3134243830Sdim  }
3135234353Sdim
3136263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
3137263508Sdim                               options::OPT_mno_restrict_it)) {
3138263508Sdim    if (A->getOption().matches(options::OPT_mrestrict_it)) {
3139263508Sdim      CmdArgs.push_back("-backend-option");
3140263508Sdim      CmdArgs.push_back("-arm-restrict-it");
3141263508Sdim    } else {
3142263508Sdim      CmdArgs.push_back("-backend-option");
3143263508Sdim      CmdArgs.push_back("-arm-no-restrict-it");
3144263508Sdim    }
3145263508Sdim  }
3146263508Sdim
3147193326Sed  // Forward -f options with positive and negative forms; we translate
3148193326Sed  // these by hand.
3149263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
3150263508Sdim    StringRef fname = A->getValue();
3151263508Sdim    if (!llvm::sys::fs::exists(fname))
3152263508Sdim      D.Diag(diag::err_drv_no_such_file) << fname;
3153263508Sdim    else
3154263508Sdim      A->render(Args, CmdArgs);
3155263508Sdim  }
3156193326Sed
3157218893Sdim  if (Args.hasArg(options::OPT_mkernel)) {
3158218893Sdim    if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
3159218893Sdim      CmdArgs.push_back("-fapple-kext");
3160218893Sdim    if (!Args.hasArg(options::OPT_fbuiltin))
3161218893Sdim      CmdArgs.push_back("-fno-builtin");
3162234353Sdim    Args.ClaimAllArgs(options::OPT_fno_builtin);
3163218893Sdim  }
3164199482Srdivacky  // -fbuiltin is default.
3165218893Sdim  else if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
3166199512Srdivacky    CmdArgs.push_back("-fno-builtin");
3167193326Sed
3168201361Srdivacky  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
3169201361Srdivacky                    options::OPT_fno_assume_sane_operator_new))
3170201361Srdivacky    CmdArgs.push_back("-fno-assume-sane-operator-new");
3171201361Srdivacky
3172199482Srdivacky  // -fblocks=0 is default.
3173199482Srdivacky  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
3174221345Sdim                   getToolChain().IsBlocksDefault()) ||
3175221345Sdim        (Args.hasArg(options::OPT_fgnu_runtime) &&
3176221345Sdim         Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
3177221345Sdim         !Args.hasArg(options::OPT_fno_blocks))) {
3178199482Srdivacky    CmdArgs.push_back("-fblocks");
3179226633Sdim
3180226633Sdim    if (!Args.hasArg(options::OPT_fgnu_runtime) &&
3181226633Sdim        !getToolChain().hasBlocksRuntime())
3182226633Sdim      CmdArgs.push_back("-fblocks-runtime-optional");
3183193326Sed  }
3184193326Sed
3185234353Sdim  // -fmodules enables modules (off by default). However, for C++/Objective-C++,
3186234353Sdim  // users must also pass -fcxx-modules. The latter flag will disappear once the
3187234353Sdim  // modules implementation is solid for C++/Objective-C++ programs as well.
3188249423Sdim  bool HaveModules = false;
3189234353Sdim  if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
3190234353Sdim    bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
3191234353Sdim                                     options::OPT_fno_cxx_modules,
3192234353Sdim                                     false);
3193249423Sdim    if (AllowedInCXX || !types::isCXX(InputType)) {
3194234353Sdim      CmdArgs.push_back("-fmodules");
3195249423Sdim      HaveModules = true;
3196249423Sdim    }
3197234353Sdim  }
3198234353Sdim
3199263508Sdim  // -fmodule-maps enables module map processing (off by default) for header
3200263508Sdim  // checking.  It is implied by -fmodules.
3201263508Sdim  if (Args.hasFlag(options::OPT_fmodule_maps, options::OPT_fno_module_maps,
3202263508Sdim                   false)) {
3203263508Sdim    CmdArgs.push_back("-fmodule-maps");
3204263508Sdim  }
3205263508Sdim
3206263508Sdim  // -fmodules-decluse checks that modules used are declared so (off by
3207263508Sdim  // default).
3208263508Sdim  if (Args.hasFlag(options::OPT_fmodules_decluse,
3209263508Sdim                   options::OPT_fno_modules_decluse,
3210263508Sdim                   false)) {
3211263508Sdim    CmdArgs.push_back("-fmodules-decluse");
3212263508Sdim  }
3213263508Sdim
3214263508Sdim  // -fmodule-name specifies the module that is currently being built (or
3215263508Sdim  // used for header checking by -fmodule-maps).
3216263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) {
3217263508Sdim    A->claim();
3218263508Sdim    A->render(Args, CmdArgs);
3219263508Sdim  }
3220263508Sdim
3221263508Sdim  // -fmodule-map-file can be used to specify a file containing module
3222263508Sdim  // definitions.
3223263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) {
3224263508Sdim    A->claim();
3225263508Sdim    A->render(Args, CmdArgs);
3226263508Sdim  }
3227263508Sdim
3228249423Sdim  // If a module path was provided, pass it along. Otherwise, use a temporary
3229249423Sdim  // directory.
3230249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) {
3231249423Sdim    A->claim();
3232249423Sdim    if (HaveModules) {
3233249423Sdim      A->render(Args, CmdArgs);
3234249423Sdim    }
3235249423Sdim  } else if (HaveModules) {
3236249423Sdim    SmallString<128> DefaultModuleCache;
3237249423Sdim    llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
3238249423Sdim                                           DefaultModuleCache);
3239249423Sdim    llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
3240249423Sdim    llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
3241249423Sdim    const char Arg[] = "-fmodules-cache-path=";
3242249423Sdim    DefaultModuleCache.insert(DefaultModuleCache.begin(),
3243249423Sdim                              Arg, Arg + strlen(Arg));
3244249423Sdim    CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
3245249423Sdim  }
3246249423Sdim
3247249423Sdim  // Pass through all -fmodules-ignore-macro arguments.
3248249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
3249249423Sdim  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
3250249423Sdim  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
3251249423Sdim
3252207619Srdivacky  // -faccess-control is default.
3253207619Srdivacky  if (Args.hasFlag(options::OPT_fno_access_control,
3254207619Srdivacky                   options::OPT_faccess_control,
3255205408Srdivacky                   false))
3256207619Srdivacky    CmdArgs.push_back("-fno-access-control");
3257205408Srdivacky
3258218893Sdim  // -felide-constructors is the default.
3259218893Sdim  if (Args.hasFlag(options::OPT_fno_elide_constructors,
3260218893Sdim                   options::OPT_felide_constructors,
3261218893Sdim                   false))
3262218893Sdim    CmdArgs.push_back("-fno-elide-constructors");
3263218893Sdim
3264199482Srdivacky  // -frtti is default.
3265234353Sdim  if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) ||
3266243830Sdim      KernelOrKext) {
3267199512Srdivacky    CmdArgs.push_back("-fno-rtti");
3268198092Srdivacky
3269243830Sdim    // -fno-rtti cannot usefully be combined with -fsanitize=vptr.
3270243830Sdim    if (Sanitize.sanitizesVptr()) {
3271243830Sdim      std::string NoRttiArg =
3272243830Sdim        Args.getLastArg(options::OPT_mkernel,
3273243830Sdim                        options::OPT_fapple_kext,
3274243830Sdim                        options::OPT_fno_rtti)->getAsString(Args);
3275243830Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
3276243830Sdim        << "-fsanitize=vptr" << NoRttiArg;
3277243830Sdim    }
3278243830Sdim  }
3279243830Sdim
3280234353Sdim  // -fshort-enums=0 is default for all architectures except Hexagon.
3281218893Sdim  if (Args.hasFlag(options::OPT_fshort_enums,
3282234353Sdim                   options::OPT_fno_short_enums,
3283263508Sdim                   getToolChain().getArch() ==
3284234353Sdim                   llvm::Triple::hexagon))
3285218893Sdim    CmdArgs.push_back("-fshort-enums");
3286218893Sdim
3287199482Srdivacky  // -fsigned-char is default.
3288199990Srdivacky  if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
3289199482Srdivacky                    isSignedCharDefault(getToolChain().getTriple())))
3290199990Srdivacky    CmdArgs.push_back("-fno-signed-char");
3291199482Srdivacky
3292203955Srdivacky  // -fthreadsafe-static is default.
3293218893Sdim  if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
3294203955Srdivacky                    options::OPT_fno_threadsafe_statics))
3295203955Srdivacky    CmdArgs.push_back("-fno-threadsafe-statics");
3296203955Srdivacky
3297205408Srdivacky  // -fuse-cxa-atexit is default.
3298263508Sdim  if (!Args.hasFlag(
3299263508Sdim           options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
3300263508Sdim           getToolChain().getTriple().getOS() != llvm::Triple::Cygwin &&
3301263508Sdim               getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 &&
3302263508Sdim               getToolChain().getArch() != llvm::Triple::hexagon &&
3303263508Sdim               getToolChain().getArch() != llvm::Triple::xcore) ||
3304234353Sdim      KernelOrKext)
3305205408Srdivacky    CmdArgs.push_back("-fno-use-cxa-atexit");
3306205408Srdivacky
3307199482Srdivacky  // -fms-extensions=0 is default.
3308199990Srdivacky  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
3309199482Srdivacky                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
3310199482Srdivacky    CmdArgs.push_back("-fms-extensions");
3311199482Srdivacky
3312226633Sdim  // -fms-compatibility=0 is default.
3313234353Sdim  if (Args.hasFlag(options::OPT_fms_compatibility,
3314234353Sdim                   options::OPT_fno_ms_compatibility,
3315234353Sdim                   (getToolChain().getTriple().getOS() == llvm::Triple::Win32 &&
3316234353Sdim                    Args.hasFlag(options::OPT_fms_extensions,
3317234353Sdim                                 options::OPT_fno_ms_extensions,
3318234353Sdim                                 true))))
3319226633Sdim    CmdArgs.push_back("-fms-compatibility");
3320226633Sdim
3321263508Sdim  // -fmsc-version=1700 is default.
3322218893Sdim  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
3323218893Sdim                   getToolChain().getTriple().getOS() == llvm::Triple::Win32) ||
3324218893Sdim      Args.hasArg(options::OPT_fmsc_version)) {
3325226633Sdim    StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version);
3326218893Sdim    if (msc_ver.empty())
3327263508Sdim      CmdArgs.push_back("-fmsc-version=1700");
3328218893Sdim    else
3329218893Sdim      CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver));
3330218893Sdim  }
3331218893Sdim
3332218893Sdim
3333249423Sdim  // -fno-borland-extensions is default.
3334212904Sdim  if (Args.hasFlag(options::OPT_fborland_extensions,
3335212904Sdim                   options::OPT_fno_borland_extensions, false))
3336212904Sdim    CmdArgs.push_back("-fborland-extensions");
3337212904Sdim
3338226633Sdim  // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
3339226633Sdim  // needs it.
3340221345Sdim  if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
3341221345Sdim                   options::OPT_fno_delayed_template_parsing,
3342226633Sdim                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
3343221345Sdim    CmdArgs.push_back("-fdelayed-template-parsing");
3344221345Sdim
3345207619Srdivacky  // -fgnu-keywords default varies depending on language; only pass if
3346207619Srdivacky  // specified.
3347207619Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
3348207619Srdivacky                               options::OPT_fno_gnu_keywords))
3349207619Srdivacky    A->render(Args, CmdArgs);
3350207619Srdivacky
3351223017Sdim  if (Args.hasFlag(options::OPT_fgnu89_inline,
3352223017Sdim                   options::OPT_fno_gnu89_inline,
3353223017Sdim                   false))
3354223017Sdim    CmdArgs.push_back("-fgnu89-inline");
3355223017Sdim
3356234353Sdim  if (Args.hasArg(options::OPT_fno_inline))
3357234353Sdim    CmdArgs.push_back("-fno-inline");
3358234353Sdim
3359234353Sdim  if (Args.hasArg(options::OPT_fno_inline_functions))
3360234353Sdim    CmdArgs.push_back("-fno-inline-functions");
3361234353Sdim
3362239462Sdim  ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
3363224145Sdim
3364239462Sdim  // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
3365263508Sdim  // legacy is the default. Next runtime is always legacy dispatch and
3366263508Sdim  // -fno-objc-legacy-dispatch gets ignored silently.
3367263508Sdim  if (objcRuntime.isNonFragile() && !objcRuntime.isNeXTFamily()) {
3368226633Sdim    if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
3369226633Sdim                      options::OPT_fno_objc_legacy_dispatch,
3370239462Sdim                      objcRuntime.isLegacyDispatchDefaultForArch(
3371263508Sdim                        getToolChain().getArch()))) {
3372226633Sdim      if (getToolChain().UseObjCMixedDispatch())
3373226633Sdim        CmdArgs.push_back("-fobjc-dispatch-method=mixed");
3374226633Sdim      else
3375226633Sdim        CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
3376218893Sdim    }
3377199482Srdivacky  }
3378199482Srdivacky
3379263508Sdim  // When ObjectiveC legacy runtime is in effect on MacOSX,
3380263508Sdim  // turn on the option to do Array/Dictionary subscripting
3381263508Sdim  // by default.
3382263508Sdim  if (getToolChain().getTriple().getArch() == llvm::Triple::x86 &&
3383263508Sdim      getToolChain().getTriple().isMacOSX() &&
3384263508Sdim      !getToolChain().getTriple().isMacOSXVersionLT(10, 7) &&
3385263508Sdim      objcRuntime.getKind() == ObjCRuntime::FragileMacOSX &&
3386263508Sdim      objcRuntime.isNeXTFamily())
3387263508Sdim    CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
3388263508Sdim
3389243830Sdim  // -fencode-extended-block-signature=1 is default.
3390243830Sdim  if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
3391243830Sdim    CmdArgs.push_back("-fencode-extended-block-signature");
3392243830Sdim  }
3393243830Sdim
3394224145Sdim  // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
3395224145Sdim  // NOTE: This logic is duplicated in ToolChains.cpp.
3396224145Sdim  bool ARC = isObjCAutoRefCount(Args);
3397224145Sdim  if (ARC) {
3398243830Sdim    getToolChain().CheckObjCARC();
3399234353Sdim
3400224145Sdim    CmdArgs.push_back("-fobjc-arc");
3401224145Sdim
3402228379Sdim    // FIXME: It seems like this entire block, and several around it should be
3403228379Sdim    // wrapped in isObjC, but for now we just use it here as this is where it
3404228379Sdim    // was being used previously.
3405228379Sdim    if (types::isCXX(InputType) && types::isObjC(InputType)) {
3406228379Sdim      if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
3407228379Sdim        CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
3408228379Sdim      else
3409228379Sdim        CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
3410228379Sdim    }
3411228379Sdim
3412224145Sdim    // Allow the user to enable full exceptions code emission.
3413224145Sdim    // We define off for Objective-CC, on for Objective-C++.
3414224145Sdim    if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
3415224145Sdim                     options::OPT_fno_objc_arc_exceptions,
3416224145Sdim                     /*default*/ types::isCXX(InputType)))
3417224145Sdim      CmdArgs.push_back("-fobjc-arc-exceptions");
3418224145Sdim  }
3419224145Sdim
3420224145Sdim  // -fobjc-infer-related-result-type is the default, except in the Objective-C
3421224145Sdim  // rewriter.
3422239462Sdim  if (rewriteKind != RK_None)
3423224145Sdim    CmdArgs.push_back("-fno-objc-infer-related-result-type");
3424226633Sdim
3425224145Sdim  // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
3426224145Sdim  // takes precedence.
3427224145Sdim  const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
3428224145Sdim  if (!GCArg)
3429224145Sdim    GCArg = Args.getLastArg(options::OPT_fobjc_gc);
3430224145Sdim  if (GCArg) {
3431224145Sdim    if (ARC) {
3432226633Sdim      D.Diag(diag::err_drv_objc_gc_arr)
3433224145Sdim        << GCArg->getAsString(Args);
3434224145Sdim    } else if (getToolChain().SupportsObjCGC()) {
3435224145Sdim      GCArg->render(Args, CmdArgs);
3436224145Sdim    } else {
3437224145Sdim      // FIXME: We should move this to a hard error.
3438226633Sdim      D.Diag(diag::warn_drv_objc_gc_unsupported)
3439224145Sdim        << GCArg->getAsString(Args);
3440224145Sdim    }
3441224145Sdim  }
3442224145Sdim
3443224145Sdim  // Add exception args.
3444224145Sdim  addExceptionArgs(Args, InputType, getToolChain().getTriple(),
3445239462Sdim                   KernelOrKext, objcRuntime, CmdArgs);
3446224145Sdim
3447224145Sdim  if (getToolChain().UseSjLjExceptions())
3448224145Sdim    CmdArgs.push_back("-fsjlj-exceptions");
3449224145Sdim
3450224145Sdim  // C++ "sane" operator new.
3451203955Srdivacky  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
3452203955Srdivacky                    options::OPT_fno_assume_sane_operator_new))
3453203955Srdivacky    CmdArgs.push_back("-fno-assume-sane-operator-new");
3454203955Srdivacky
3455207619Srdivacky  // -fconstant-cfstrings is default, and may be subject to argument translation
3456207619Srdivacky  // on Darwin.
3457207619Srdivacky  if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
3458207619Srdivacky                    options::OPT_fno_constant_cfstrings) ||
3459207619Srdivacky      !Args.hasFlag(options::OPT_mconstant_cfstrings,
3460207619Srdivacky                    options::OPT_mno_constant_cfstrings))
3461207619Srdivacky    CmdArgs.push_back("-fno-constant-cfstrings");
3462207619Srdivacky
3463199482Srdivacky  // -fshort-wchar default varies depending on platform; only
3464193576Sed  // pass if specified.
3465207619Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar))
3466207619Srdivacky    A->render(Args, CmdArgs);
3467193576Sed
3468263508Sdim  // -fno-pascal-strings is default, only pass non-default.
3469193326Sed  if (Args.hasFlag(options::OPT_fpascal_strings,
3470193326Sed                   options::OPT_fno_pascal_strings,
3471193326Sed                   false))
3472193326Sed    CmdArgs.push_back("-fpascal-strings");
3473193326Sed
3474226633Sdim  // Honor -fpack-struct= and -fpack-struct, if given. Note that
3475226633Sdim  // -fno-pack-struct doesn't apply to -fpack-struct=.
3476226633Sdim  if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
3477239462Sdim    std::string PackStructStr = "-fpack-struct=";
3478243830Sdim    PackStructStr += A->getValue();
3479239462Sdim    CmdArgs.push_back(Args.MakeArgString(PackStructStr));
3480226633Sdim  } else if (Args.hasFlag(options::OPT_fpack_struct,
3481226633Sdim                          options::OPT_fno_pack_struct, false)) {
3482239462Sdim    CmdArgs.push_back("-fpack-struct=1");
3483226633Sdim  }
3484226633Sdim
3485263508Sdim  if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) {
3486218893Sdim    if (!Args.hasArg(options::OPT_fcommon))
3487218893Sdim      CmdArgs.push_back("-fno-common");
3488234353Sdim    Args.ClaimAllArgs(options::OPT_fno_common);
3489218893Sdim  }
3490226633Sdim
3491193326Sed  // -fcommon is default, only pass non-default.
3492218893Sdim  else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
3493193326Sed    CmdArgs.push_back("-fno-common");
3494193326Sed
3495193326Sed  // -fsigned-bitfields is default, and clang doesn't yet support
3496218893Sdim  // -funsigned-bitfields.
3497198092Srdivacky  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
3498193326Sed                    options::OPT_funsigned_bitfields))
3499226633Sdim    D.Diag(diag::warn_drv_clang_unsupported)
3500193326Sed      << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
3501193326Sed
3502218893Sdim  // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
3503218893Sdim  if (!Args.hasFlag(options::OPT_ffor_scope,
3504218893Sdim                    options::OPT_fno_for_scope))
3505226633Sdim    D.Diag(diag::err_drv_clang_unsupported)
3506218893Sdim      << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
3507218893Sdim
3508210299Sed  // -fcaret-diagnostics is default.
3509210299Sed  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
3510210299Sed                    options::OPT_fno_caret_diagnostics, true))
3511210299Sed    CmdArgs.push_back("-fno-caret-diagnostics");
3512210299Sed
3513193326Sed  // -fdiagnostics-fixit-info is default, only pass non-default.
3514198092Srdivacky  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
3515193326Sed                    options::OPT_fno_diagnostics_fixit_info))
3516193326Sed    CmdArgs.push_back("-fno-diagnostics-fixit-info");
3517226633Sdim
3518193326Sed  // Enable -fdiagnostics-show-option by default.
3519198092Srdivacky  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
3520193326Sed                   options::OPT_fno_diagnostics_show_option))
3521193326Sed    CmdArgs.push_back("-fdiagnostics-show-option");
3522198893Srdivacky
3523208600Srdivacky  if (const Arg *A =
3524208600Srdivacky        Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
3525208600Srdivacky    CmdArgs.push_back("-fdiagnostics-show-category");
3526243830Sdim    CmdArgs.push_back(A->getValue());
3527208600Srdivacky  }
3528212904Sdim
3529223017Sdim  if (const Arg *A =
3530223017Sdim        Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
3531223017Sdim    CmdArgs.push_back("-fdiagnostics-format");
3532243830Sdim    CmdArgs.push_back(A->getValue());
3533223017Sdim  }
3534223017Sdim
3535221345Sdim  if (Arg *A = Args.getLastArg(
3536221345Sdim      options::OPT_fdiagnostics_show_note_include_stack,
3537221345Sdim      options::OPT_fno_diagnostics_show_note_include_stack)) {
3538221345Sdim    if (A->getOption().matches(
3539221345Sdim        options::OPT_fdiagnostics_show_note_include_stack))
3540221345Sdim      CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
3541221345Sdim    else
3542221345Sdim      CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
3543221345Sdim  }
3544221345Sdim
3545198893Srdivacky  // Color diagnostics are the default, unless the terminal doesn't support
3546198893Srdivacky  // them.
3547251662Sdim  // Support both clang's -f[no-]color-diagnostics and gcc's
3548251662Sdim  // -f[no-]diagnostics-colors[=never|always|auto].
3549251662Sdim  enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
3550251662Sdim  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
3551251662Sdim       it != ie; ++it) {
3552251662Sdim    const Option &O = (*it)->getOption();
3553251662Sdim    if (!O.matches(options::OPT_fcolor_diagnostics) &&
3554251662Sdim        !O.matches(options::OPT_fdiagnostics_color) &&
3555251662Sdim        !O.matches(options::OPT_fno_color_diagnostics) &&
3556251662Sdim        !O.matches(options::OPT_fno_diagnostics_color) &&
3557251662Sdim        !O.matches(options::OPT_fdiagnostics_color_EQ))
3558251662Sdim      continue;
3559251662Sdim
3560251662Sdim    (*it)->claim();
3561251662Sdim    if (O.matches(options::OPT_fcolor_diagnostics) ||
3562251662Sdim        O.matches(options::OPT_fdiagnostics_color)) {
3563251662Sdim      ShowColors = Colors_On;
3564251662Sdim    } else if (O.matches(options::OPT_fno_color_diagnostics) ||
3565251662Sdim               O.matches(options::OPT_fno_diagnostics_color)) {
3566251662Sdim      ShowColors = Colors_Off;
3567251662Sdim    } else {
3568251662Sdim      assert(O.matches(options::OPT_fdiagnostics_color_EQ));
3569251662Sdim      StringRef value((*it)->getValue());
3570251662Sdim      if (value == "always")
3571251662Sdim        ShowColors = Colors_On;
3572251662Sdim      else if (value == "never")
3573251662Sdim        ShowColors = Colors_Off;
3574251662Sdim      else if (value == "auto")
3575251662Sdim        ShowColors = Colors_Auto;
3576251662Sdim      else
3577251662Sdim        getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
3578251662Sdim          << ("-fdiagnostics-color=" + value).str();
3579251662Sdim    }
3580251662Sdim  }
3581251662Sdim  if (ShowColors == Colors_On ||
3582251662Sdim      (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors()))
3583198893Srdivacky    CmdArgs.push_back("-fcolor-diagnostics");
3584198893Srdivacky
3585263508Sdim  if (Args.hasArg(options::OPT_fansi_escape_codes))
3586263508Sdim    CmdArgs.push_back("-fansi-escape-codes");
3587263508Sdim
3588194179Sed  if (!Args.hasFlag(options::OPT_fshow_source_location,
3589194179Sed                    options::OPT_fno_show_source_location))
3590194179Sed    CmdArgs.push_back("-fno-show-source-location");
3591193326Sed
3592223017Sdim  if (!Args.hasFlag(options::OPT_fshow_column,
3593223017Sdim                    options::OPT_fno_show_column,
3594223017Sdim                    true))
3595223017Sdim    CmdArgs.push_back("-fno-show-column");
3596223017Sdim
3597210299Sed  if (!Args.hasFlag(options::OPT_fspell_checking,
3598210299Sed                    options::OPT_fno_spell_checking))
3599210299Sed    CmdArgs.push_back("-fno-spell-checking");
3600212904Sdim
3601218893Sdim
3602249423Sdim  // -fno-asm-blocks is default.
3603249423Sdim  if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
3604249423Sdim                   false))
3605249423Sdim    CmdArgs.push_back("-fasm-blocks");
3606218893Sdim
3607263508Sdim  // Enable vectorization per default according to the optimization level
3608263508Sdim  // selected. For optimization levels that want vectorization we use the alias
3609263508Sdim  // option to simplify the hasFlag logic.
3610263508Sdim  bool EnableVec = shouldEnableVectorizerAtOLevel(Args);
3611263508Sdim  OptSpecifier VectorizeAliasOption = EnableVec ? options::OPT_O_Group :
3612251662Sdim    options::OPT_fvectorize;
3613251662Sdim  if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
3614263508Sdim                   options::OPT_fno_vectorize, EnableVec))
3615249423Sdim    CmdArgs.push_back("-vectorize-loops");
3616249423Sdim
3617263508Sdim  // -fslp-vectorize is default.
3618249423Sdim  if (Args.hasFlag(options::OPT_fslp_vectorize,
3619263508Sdim                   options::OPT_fno_slp_vectorize, true))
3620251662Sdim    CmdArgs.push_back("-vectorize-slp");
3621249423Sdim
3622251662Sdim  // -fno-slp-vectorize-aggressive is default.
3623251662Sdim  if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
3624263508Sdim                   options::OPT_fno_slp_vectorize_aggressive, false))
3625251662Sdim    CmdArgs.push_back("-vectorize-slp-aggressive");
3626251662Sdim
3627210299Sed  if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
3628210299Sed    A->render(Args, CmdArgs);
3629210299Sed
3630193326Sed  // -fdollars-in-identifiers default varies depending on platform and
3631193326Sed  // language; only pass if specified.
3632198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
3633193326Sed                               options::OPT_fno_dollars_in_identifiers)) {
3634193326Sed    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
3635201361Srdivacky      CmdArgs.push_back("-fdollars-in-identifiers");
3636193326Sed    else
3637201361Srdivacky      CmdArgs.push_back("-fno-dollars-in-identifiers");
3638193326Sed  }
3639193326Sed
3640193326Sed  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
3641193326Sed  // practical purposes.
3642198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
3643193326Sed                               options::OPT_fno_unit_at_a_time)) {
3644193326Sed    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
3645226633Sdim      D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
3646193326Sed  }
3647198092Srdivacky
3648234353Sdim  if (Args.hasFlag(options::OPT_fapple_pragma_pack,
3649234353Sdim                   options::OPT_fno_apple_pragma_pack, false))
3650234353Sdim    CmdArgs.push_back("-fapple-pragma-pack");
3651234353Sdim
3652263508Sdim  // le32-specific flags:
3653263508Sdim  //  -fno-math-builtin: clang should not convert math builtins to intrinsics
3654263508Sdim  //                     by default.
3655263508Sdim  if (getToolChain().getArch() == llvm::Triple::le32) {
3656263508Sdim    CmdArgs.push_back("-fno-math-builtin");
3657263508Sdim  }
3658263508Sdim
3659198092Srdivacky  // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
3660198092Srdivacky  //
3661200583Srdivacky  // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
3662198092Srdivacky#if 0
3663226633Sdim  if (getToolChain().getTriple().isOSDarwin() &&
3664263508Sdim      (getToolChain().getArch() == llvm::Triple::arm ||
3665263508Sdim       getToolChain().getArch() == llvm::Triple::thumb)) {
3666198092Srdivacky    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
3667198092Srdivacky      CmdArgs.push_back("-fno-builtin-strcat");
3668198092Srdivacky    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
3669198092Srdivacky      CmdArgs.push_back("-fno-builtin-strcpy");
3670198092Srdivacky  }
3671198092Srdivacky#endif
3672198092Srdivacky
3673221345Sdim  // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
3674198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_traditional,
3675221345Sdim                               options::OPT_traditional_cpp)) {
3676221345Sdim    if (isa<PreprocessJobAction>(JA))
3677221345Sdim      CmdArgs.push_back("-traditional-cpp");
3678226633Sdim    else
3679226633Sdim      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
3680221345Sdim  }
3681198092Srdivacky
3682193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dM);
3683193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dD);
3684234353Sdim
3685234353Sdim  // Handle serialized diagnostics.
3686234353Sdim  if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
3687234353Sdim    CmdArgs.push_back("-serialize-diagnostic-file");
3688243830Sdim    CmdArgs.push_back(Args.MakeArgString(A->getValue()));
3689234353Sdim  }
3690193326Sed
3691243830Sdim  if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
3692243830Sdim    CmdArgs.push_back("-fretain-comments-from-system-headers");
3693243830Sdim
3694249423Sdim  // Forward -fcomment-block-commands to -cc1.
3695249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
3696251662Sdim  // Forward -fparse-all-comments to -cc1.
3697251662Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
3698249423Sdim
3699207619Srdivacky  // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
3700207619Srdivacky  // parser.
3701193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
3702207619Srdivacky  for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
3703207619Srdivacky         ie = Args.filtered_end(); it != ie; ++it) {
3704210299Sed    (*it)->claim();
3705193326Sed
3706207619Srdivacky    // We translate this by hand to the -cc1 argument, since nightly test uses
3707207619Srdivacky    // it and developers have been trained to spell it with -mllvm.
3708243830Sdim    if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns")
3709207619Srdivacky      CmdArgs.push_back("-disable-llvm-optzns");
3710207619Srdivacky    else
3711210299Sed      (*it)->render(Args, CmdArgs);
3712207619Srdivacky  }
3713207619Srdivacky
3714193326Sed  if (Output.getType() == types::TY_Dependencies) {
3715193326Sed    // Handled with other dependency code.
3716193326Sed  } else if (Output.isFilename()) {
3717193326Sed    CmdArgs.push_back("-o");
3718193326Sed    CmdArgs.push_back(Output.getFilename());
3719193326Sed  } else {
3720193326Sed    assert(Output.isNothing() && "Invalid output.");
3721193326Sed  }
3722193326Sed
3723193326Sed  for (InputInfoList::const_iterator
3724193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
3725193326Sed    const InputInfo &II = *it;
3726193326Sed    CmdArgs.push_back("-x");
3727243830Sdim    if (Args.hasArg(options::OPT_rewrite_objc))
3728243830Sdim      CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
3729243830Sdim    else
3730243830Sdim      CmdArgs.push_back(types::getTypeName(II.getType()));
3731212904Sdim    if (II.isFilename())
3732193326Sed      CmdArgs.push_back(II.getFilename());
3733193326Sed    else
3734193326Sed      II.getInputArg().renderAsInput(Args, CmdArgs);
3735193326Sed  }
3736193326Sed
3737198893Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_undef);
3738198893Srdivacky
3739212904Sdim  const char *Exec = getToolChain().getDriver().getClangProgramPath();
3740201361Srdivacky
3741201361Srdivacky  // Optionally embed the -cc1 level arguments into the debug info, for build
3742201361Srdivacky  // analysis.
3743201361Srdivacky  if (getToolChain().UseDwarfDebugFlags()) {
3744210299Sed    ArgStringList OriginalArgs;
3745210299Sed    for (ArgList::const_iterator it = Args.begin(),
3746210299Sed           ie = Args.end(); it != ie; ++it)
3747210299Sed      (*it)->render(Args, OriginalArgs);
3748212904Sdim
3749234353Sdim    SmallString<256> Flags;
3750201361Srdivacky    Flags += Exec;
3751210299Sed    for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
3752201361Srdivacky      Flags += " ";
3753210299Sed      Flags += OriginalArgs[i];
3754201361Srdivacky    }
3755201361Srdivacky    CmdArgs.push_back("-dwarf-debug-flags");
3756201361Srdivacky    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
3757201361Srdivacky  }
3758201361Srdivacky
3759249423Sdim  // Add the split debug info name to the command lines here so we
3760249423Sdim  // can propagate it to the backend.
3761249423Sdim  bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) &&
3762263508Sdim    getToolChain().getTriple().isOSLinux() &&
3763249423Sdim    (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA));
3764249423Sdim  const char *SplitDwarfOut;
3765249423Sdim  if (SplitDwarf) {
3766249423Sdim    CmdArgs.push_back("-split-dwarf-file");
3767249423Sdim    SplitDwarfOut = SplitDebugName(Args, Inputs);
3768249423Sdim    CmdArgs.push_back(SplitDwarfOut);
3769249423Sdim  }
3770249423Sdim
3771249423Sdim  // Finally add the compile command to the compilation.
3772263508Sdim  if (Args.hasArg(options::OPT__SLASH_fallback)) {
3773263508Sdim    tools::visualstudio::Compile CL(getToolChain());
3774263508Sdim    Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args,
3775263508Sdim                                       LinkingOutput);
3776263508Sdim    C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
3777263508Sdim  } else {
3778263508Sdim    C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3779263508Sdim  }
3780193326Sed
3781263508Sdim
3782249423Sdim  // Handle the debug info splitting at object creation time if we're
3783249423Sdim  // creating an object.
3784249423Sdim  // TODO: Currently only works on linux with newer objcopy.
3785249423Sdim  if (SplitDwarf && !isa<CompileJobAction>(JA))
3786249423Sdim    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
3787249423Sdim
3788218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_pg))
3789218893Sdim    if (Args.hasArg(options::OPT_fomit_frame_pointer))
3790226633Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
3791218893Sdim        << "-fomit-frame-pointer" << A->getAsString(Args);
3792193326Sed
3793193326Sed  // Claim some arguments which clang supports automatically.
3794193326Sed
3795207619Srdivacky  // -fpch-preprocess is used with gcc to add a special marker in the output to
3796207619Srdivacky  // include the PCH file. Clang's PTH solution is completely transparent, so we
3797207619Srdivacky  // do not need to deal with it at all.
3798193326Sed  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
3799193326Sed
3800193326Sed  // Claim some arguments which clang doesn't support, but we don't
3801193326Sed  // care to warn the user about.
3802199990Srdivacky  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
3803199990Srdivacky  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
3804221345Sdim
3805263508Sdim  // Disable warnings for clang -E -emit-llvm foo.c
3806221345Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
3807193326Sed}
3808193326Sed
3809239462Sdim/// Add options related to the Objective-C runtime/ABI.
3810239462Sdim///
3811239462Sdim/// Returns true if the runtime is non-fragile.
3812239462SdimObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
3813239462Sdim                                      ArgStringList &cmdArgs,
3814239462Sdim                                      RewriteKind rewriteKind) const {
3815239462Sdim  // Look for the controlling runtime option.
3816239462Sdim  Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime,
3817239462Sdim                                    options::OPT_fgnu_runtime,
3818239462Sdim                                    options::OPT_fobjc_runtime_EQ);
3819239462Sdim
3820239462Sdim  // Just forward -fobjc-runtime= to the frontend.  This supercedes
3821239462Sdim  // options about fragility.
3822239462Sdim  if (runtimeArg &&
3823239462Sdim      runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
3824239462Sdim    ObjCRuntime runtime;
3825243830Sdim    StringRef value = runtimeArg->getValue();
3826239462Sdim    if (runtime.tryParse(value)) {
3827239462Sdim      getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
3828239462Sdim        << value;
3829239462Sdim    }
3830239462Sdim
3831239462Sdim    runtimeArg->render(args, cmdArgs);
3832239462Sdim    return runtime;
3833239462Sdim  }
3834239462Sdim
3835239462Sdim  // Otherwise, we'll need the ABI "version".  Version numbers are
3836239462Sdim  // slightly confusing for historical reasons:
3837239462Sdim  //   1 - Traditional "fragile" ABI
3838239462Sdim  //   2 - Non-fragile ABI, version 1
3839239462Sdim  //   3 - Non-fragile ABI, version 2
3840239462Sdim  unsigned objcABIVersion = 1;
3841239462Sdim  // If -fobjc-abi-version= is present, use that to set the version.
3842239462Sdim  if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
3843243830Sdim    StringRef value = abiArg->getValue();
3844239462Sdim    if (value == "1")
3845239462Sdim      objcABIVersion = 1;
3846239462Sdim    else if (value == "2")
3847239462Sdim      objcABIVersion = 2;
3848239462Sdim    else if (value == "3")
3849239462Sdim      objcABIVersion = 3;
3850239462Sdim    else
3851239462Sdim      getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
3852239462Sdim        << value;
3853239462Sdim  } else {
3854239462Sdim    // Otherwise, determine if we are using the non-fragile ABI.
3855239462Sdim    bool nonFragileABIIsDefault =
3856239462Sdim      (rewriteKind == RK_NonFragile ||
3857239462Sdim       (rewriteKind == RK_None &&
3858239462Sdim        getToolChain().IsObjCNonFragileABIDefault()));
3859239462Sdim    if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
3860239462Sdim                     options::OPT_fno_objc_nonfragile_abi,
3861239462Sdim                     nonFragileABIIsDefault)) {
3862239462Sdim      // Determine the non-fragile ABI version to use.
3863239462Sdim#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
3864239462Sdim      unsigned nonFragileABIVersion = 1;
3865239462Sdim#else
3866239462Sdim      unsigned nonFragileABIVersion = 2;
3867239462Sdim#endif
3868239462Sdim
3869239462Sdim      if (Arg *abiArg = args.getLastArg(
3870239462Sdim            options::OPT_fobjc_nonfragile_abi_version_EQ)) {
3871243830Sdim        StringRef value = abiArg->getValue();
3872239462Sdim        if (value == "1")
3873239462Sdim          nonFragileABIVersion = 1;
3874239462Sdim        else if (value == "2")
3875239462Sdim          nonFragileABIVersion = 2;
3876239462Sdim        else
3877239462Sdim          getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
3878239462Sdim            << value;
3879239462Sdim      }
3880239462Sdim
3881239462Sdim      objcABIVersion = 1 + nonFragileABIVersion;
3882239462Sdim    } else {
3883239462Sdim      objcABIVersion = 1;
3884239462Sdim    }
3885239462Sdim  }
3886239462Sdim
3887239462Sdim  // We don't actually care about the ABI version other than whether
3888239462Sdim  // it's non-fragile.
3889239462Sdim  bool isNonFragile = objcABIVersion != 1;
3890239462Sdim
3891239462Sdim  // If we have no runtime argument, ask the toolchain for its default runtime.
3892239462Sdim  // However, the rewriter only really supports the Mac runtime, so assume that.
3893239462Sdim  ObjCRuntime runtime;
3894239462Sdim  if (!runtimeArg) {
3895239462Sdim    switch (rewriteKind) {
3896239462Sdim    case RK_None:
3897239462Sdim      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
3898239462Sdim      break;
3899239462Sdim    case RK_Fragile:
3900239462Sdim      runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
3901239462Sdim      break;
3902239462Sdim    case RK_NonFragile:
3903239462Sdim      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
3904239462Sdim      break;
3905239462Sdim    }
3906239462Sdim
3907239462Sdim  // -fnext-runtime
3908239462Sdim  } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
3909239462Sdim    // On Darwin, make this use the default behavior for the toolchain.
3910239462Sdim    if (getToolChain().getTriple().isOSDarwin()) {
3911239462Sdim      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
3912239462Sdim
3913239462Sdim    // Otherwise, build for a generic macosx port.
3914239462Sdim    } else {
3915239462Sdim      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
3916239462Sdim    }
3917239462Sdim
3918239462Sdim  // -fgnu-runtime
3919239462Sdim  } else {
3920239462Sdim    assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
3921239462Sdim    // Legacy behaviour is to target the gnustep runtime if we are i
3922239462Sdim    // non-fragile mode or the GCC runtime in fragile mode.
3923239462Sdim    if (isNonFragile)
3924243830Sdim      runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6));
3925239462Sdim    else
3926239462Sdim      runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
3927239462Sdim  }
3928239462Sdim
3929239462Sdim  cmdArgs.push_back(args.MakeArgString(
3930239462Sdim                                 "-fobjc-runtime=" + runtime.getAsString()));
3931239462Sdim  return runtime;
3932239462Sdim}
3933239462Sdim
3934263508Sdimvoid Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
3935263508Sdim  unsigned RTOptionID = options::OPT__SLASH_MT;
3936263508Sdim
3937263508Sdim  if (Args.hasArg(options::OPT__SLASH_LDd))
3938263508Sdim    // The /LDd option implies /MTd. The dependent lib part can be overridden,
3939263508Sdim    // but defining _DEBUG is sticky.
3940263508Sdim    RTOptionID = options::OPT__SLASH_MTd;
3941263508Sdim
3942263508Sdim  if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
3943263508Sdim    RTOptionID = A->getOption().getID();
3944263508Sdim
3945263508Sdim  switch(RTOptionID) {
3946263508Sdim    case options::OPT__SLASH_MD:
3947263508Sdim      if (Args.hasArg(options::OPT__SLASH_LDd))
3948263508Sdim        CmdArgs.push_back("-D_DEBUG");
3949263508Sdim      CmdArgs.push_back("-D_MT");
3950263508Sdim      CmdArgs.push_back("-D_DLL");
3951263508Sdim      CmdArgs.push_back("--dependent-lib=msvcrt");
3952263508Sdim      break;
3953263508Sdim    case options::OPT__SLASH_MDd:
3954263508Sdim      CmdArgs.push_back("-D_DEBUG");
3955263508Sdim      CmdArgs.push_back("-D_MT");
3956263508Sdim      CmdArgs.push_back("-D_DLL");
3957263508Sdim      CmdArgs.push_back("--dependent-lib=msvcrtd");
3958263508Sdim      break;
3959263508Sdim    case options::OPT__SLASH_MT:
3960263508Sdim      if (Args.hasArg(options::OPT__SLASH_LDd))
3961263508Sdim        CmdArgs.push_back("-D_DEBUG");
3962263508Sdim      CmdArgs.push_back("-D_MT");
3963263508Sdim      CmdArgs.push_back("--dependent-lib=libcmt");
3964263508Sdim      break;
3965263508Sdim    case options::OPT__SLASH_MTd:
3966263508Sdim      CmdArgs.push_back("-D_DEBUG");
3967263508Sdim      CmdArgs.push_back("-D_MT");
3968263508Sdim      CmdArgs.push_back("--dependent-lib=libcmtd");
3969263508Sdim      break;
3970263508Sdim    default:
3971263508Sdim      llvm_unreachable("Unexpected option ID.");
3972263508Sdim  }
3973263508Sdim
3974263508Sdim  // This provides POSIX compatibility (maps 'open' to '_open'), which most
3975263508Sdim  // users want.  The /Za flag to cl.exe turns this off, but it's not
3976263508Sdim  // implemented in clang.
3977263508Sdim  CmdArgs.push_back("--dependent-lib=oldnames");
3978263508Sdim
3979263508Sdim  // FIXME: Make this default for the win32 triple.
3980263508Sdim  CmdArgs.push_back("-cxx-abi");
3981263508Sdim  CmdArgs.push_back("microsoft");
3982263508Sdim
3983263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_show_includes))
3984263508Sdim    A->render(Args, CmdArgs);
3985263508Sdim
3986263508Sdim  if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
3987263508Sdim    CmdArgs.push_back("-fdiagnostics-format");
3988263508Sdim    if (Args.hasArg(options::OPT__SLASH_fallback))
3989263508Sdim      CmdArgs.push_back("msvc-fallback");
3990263508Sdim    else
3991263508Sdim      CmdArgs.push_back("msvc");
3992263508Sdim  }
3993263508Sdim}
3994263508Sdim
3995208600Srdivackyvoid ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
3996208600Srdivacky                           const InputInfo &Output,
3997208600Srdivacky                           const InputInfoList &Inputs,
3998208600Srdivacky                           const ArgList &Args,
3999208600Srdivacky                           const char *LinkingOutput) const {
4000208600Srdivacky  ArgStringList CmdArgs;
4001208600Srdivacky
4002208600Srdivacky  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
4003208600Srdivacky  const InputInfo &Input = Inputs[0];
4004208600Srdivacky
4005218893Sdim  // Don't warn about "clang -w -c foo.s"
4006218893Sdim  Args.ClaimAllArgs(options::OPT_w);
4007221345Sdim  // and "clang -emit-llvm -c foo.s"
4008221345Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
4009218893Sdim
4010208600Srdivacky  // Invoke ourselves in -cc1as mode.
4011208600Srdivacky  //
4012208600Srdivacky  // FIXME: Implement custom jobs for internal actions.
4013208600Srdivacky  CmdArgs.push_back("-cc1as");
4014208600Srdivacky
4015208600Srdivacky  // Add the "effective" target triple.
4016208600Srdivacky  CmdArgs.push_back("-triple");
4017226633Sdim  std::string TripleStr =
4018226633Sdim    getToolChain().ComputeEffectiveClangTriple(Args, Input.getType());
4019208600Srdivacky  CmdArgs.push_back(Args.MakeArgString(TripleStr));
4020208600Srdivacky
4021208600Srdivacky  // Set the output mode, we currently only expect to be used as a real
4022208600Srdivacky  // assembler.
4023208600Srdivacky  CmdArgs.push_back("-filetype");
4024208600Srdivacky  CmdArgs.push_back("obj");
4025208600Srdivacky
4026249423Sdim  // Set the main file name, so that debug info works even with
4027249423Sdim  // -save-temps or preprocessed assembly.
4028249423Sdim  CmdArgs.push_back("-main-file-name");
4029249423Sdim  CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs));
4030249423Sdim
4031263508Sdim  // Add the target cpu
4032263508Sdim  const llvm::Triple &Triple = getToolChain().getTriple();
4033263508Sdim  std::string CPU = getCPUName(Args, Triple);
4034263508Sdim  if (!CPU.empty()) {
4035263508Sdim    CmdArgs.push_back("-target-cpu");
4036263508Sdim    CmdArgs.push_back(Args.MakeArgString(CPU));
4037263508Sdim  }
4038208600Srdivacky
4039263508Sdim  // Add the target features
4040263508Sdim  const Driver &D = getToolChain().getDriver();
4041263508Sdim  getTargetFeatures(D, Triple, Args, CmdArgs);
4042234353Sdim
4043221345Sdim  // Ignore explicit -force_cpusubtype_ALL option.
4044221345Sdim  (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
4045208600Srdivacky
4046234353Sdim  // Determine the original source input.
4047234353Sdim  const Action *SourceAction = &JA;
4048234353Sdim  while (SourceAction->getKind() != Action::InputClass) {
4049234353Sdim    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
4050234353Sdim    SourceAction = SourceAction->getInputs()[0];
4051234353Sdim  }
4052208600Srdivacky
4053249423Sdim  // Forward -g and handle debug info related flags, assuming we are dealing
4054249423Sdim  // with an actual assembly file.
4055234353Sdim  if (SourceAction->getType() == types::TY_Asm ||
4056234353Sdim      SourceAction->getType() == types::TY_PP_Asm) {
4057234353Sdim    Args.ClaimAllArgs(options::OPT_g_Group);
4058234353Sdim    if (Arg *A = Args.getLastArg(options::OPT_g_Group))
4059234353Sdim      if (!A->getOption().matches(options::OPT_g0))
4060234353Sdim        CmdArgs.push_back("-g");
4061249423Sdim
4062249423Sdim    // Add the -fdebug-compilation-dir flag if needed.
4063249423Sdim    addDebugCompDirArg(Args, CmdArgs);
4064249423Sdim
4065249423Sdim    // Set the AT_producer to the clang version when using the integrated
4066249423Sdim    // assembler on assembly source files.
4067249423Sdim    CmdArgs.push_back("-dwarf-debug-producer");
4068249423Sdim    CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
4069234353Sdim  }
4070234353Sdim
4071234353Sdim  // Optionally embed the -cc1as level arguments into the debug info, for build
4072234353Sdim  // analysis.
4073234353Sdim  if (getToolChain().UseDwarfDebugFlags()) {
4074234353Sdim    ArgStringList OriginalArgs;
4075234353Sdim    for (ArgList::const_iterator it = Args.begin(),
4076234353Sdim           ie = Args.end(); it != ie; ++it)
4077234353Sdim      (*it)->render(Args, OriginalArgs);
4078234353Sdim
4079234353Sdim    SmallString<256> Flags;
4080234353Sdim    const char *Exec = getToolChain().getDriver().getClangProgramPath();
4081234353Sdim    Flags += Exec;
4082234353Sdim    for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
4083234353Sdim      Flags += " ";
4084234353Sdim      Flags += OriginalArgs[i];
4085234353Sdim    }
4086234353Sdim    CmdArgs.push_back("-dwarf-debug-flags");
4087234353Sdim    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
4088234353Sdim  }
4089234353Sdim
4090208600Srdivacky  // FIXME: Add -static support, once we have it.
4091208600Srdivacky
4092263508Sdim  CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
4093263508Sdim                                    getToolChain().getDriver());
4094263508Sdim
4095221345Sdim  Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
4096208600Srdivacky
4097208600Srdivacky  assert(Output.isFilename() && "Unexpected lipo output.");
4098208600Srdivacky  CmdArgs.push_back("-o");
4099208600Srdivacky  CmdArgs.push_back(Output.getFilename());
4100208600Srdivacky
4101212904Sdim  assert(Input.isFilename() && "Invalid input.");
4102212904Sdim  CmdArgs.push_back(Input.getFilename());
4103208600Srdivacky
4104212904Sdim  const char *Exec = getToolChain().getDriver().getClangProgramPath();
4105212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4106251662Sdim
4107251662Sdim  // Handle the debug info splitting at object creation time if we're
4108251662Sdim  // creating an object.
4109251662Sdim  // TODO: Currently only works on linux with newer objcopy.
4110251662Sdim  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
4111263508Sdim      getToolChain().getTriple().isOSLinux())
4112251662Sdim    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
4113251662Sdim                   SplitDebugName(Args, Inputs));
4114208600Srdivacky}
4115208600Srdivacky
4116193326Sedvoid gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
4117193326Sed                               const InputInfo &Output,
4118193326Sed                               const InputInfoList &Inputs,
4119193326Sed                               const ArgList &Args,
4120193326Sed                               const char *LinkingOutput) const {
4121201361Srdivacky  const Driver &D = getToolChain().getDriver();
4122193326Sed  ArgStringList CmdArgs;
4123193326Sed
4124193326Sed  for (ArgList::const_iterator
4125193326Sed         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
4126193326Sed    Arg *A = *it;
4127243830Sdim    if (forwardToGCC(A->getOption())) {
4128212904Sdim      // Don't forward any -g arguments to assembly steps.
4129212904Sdim      if (isa<AssembleJobAction>(JA) &&
4130212904Sdim          A->getOption().matches(options::OPT_g_Group))
4131212904Sdim        continue;
4132212904Sdim
4133263508Sdim      // Don't forward any -W arguments to assembly and link steps.
4134263508Sdim      if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
4135263508Sdim          A->getOption().matches(options::OPT_W_Group))
4136263508Sdim        continue;
4137263508Sdim
4138193326Sed      // It is unfortunate that we have to claim here, as this means
4139193326Sed      // we will basically never report anything interesting for
4140193326Sed      // platforms using a generic gcc, even if we are just using gcc
4141193326Sed      // to get to the assembler.
4142193326Sed      A->claim();
4143193326Sed      A->render(Args, CmdArgs);
4144193326Sed    }
4145193326Sed  }
4146193326Sed
4147203955Srdivacky  RenderExtraToolArgs(JA, CmdArgs);
4148193326Sed
4149193326Sed  // If using a driver driver, force the arch.
4150243830Sdim  llvm::Triple::ArchType Arch = getToolChain().getArch();
4151226633Sdim  if (getToolChain().getTriple().isOSDarwin()) {
4152193326Sed    CmdArgs.push_back("-arch");
4153193326Sed
4154193326Sed    // FIXME: Remove these special cases.
4155243830Sdim    if (Arch == llvm::Triple::ppc)
4156193326Sed      CmdArgs.push_back("ppc");
4157243830Sdim    else if (Arch == llvm::Triple::ppc64)
4158193326Sed      CmdArgs.push_back("ppc64");
4159263508Sdim    else if (Arch == llvm::Triple::ppc64le)
4160263508Sdim      CmdArgs.push_back("ppc64le");
4161193326Sed    else
4162243830Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
4163193326Sed  }
4164193326Sed
4165193326Sed  // Try to force gcc to match the tool chain we want, if we recognize
4166193326Sed  // the arch.
4167193326Sed  //
4168193326Sed  // FIXME: The triple class should directly provide the information we want
4169193326Sed  // here.
4170243830Sdim  if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
4171193326Sed    CmdArgs.push_back("-m32");
4172263508Sdim  else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 ||
4173263508Sdim           Arch == llvm::Triple::ppc64le)
4174193326Sed    CmdArgs.push_back("-m64");
4175193326Sed
4176212904Sdim  if (Output.isFilename()) {
4177193326Sed    CmdArgs.push_back("-o");
4178193326Sed    CmdArgs.push_back(Output.getFilename());
4179193326Sed  } else {
4180193326Sed    assert(Output.isNothing() && "Unexpected output");
4181193326Sed    CmdArgs.push_back("-fsyntax-only");
4182193326Sed  }
4183193326Sed
4184234353Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
4185234353Sdim                       options::OPT_Xassembler);
4186193326Sed
4187193326Sed  // Only pass -x if gcc will understand it; otherwise hope gcc
4188193326Sed  // understands the suffix correctly. The main use case this would go
4189193326Sed  // wrong in is for linker inputs if they happened to have an odd
4190193326Sed  // suffix; really the only way to get this to happen is a command
4191193326Sed  // like '-x foobar a.c' which will treat a.c like a linker input.
4192193326Sed  //
4193193326Sed  // FIXME: For the linker case specifically, can we safely convert
4194193326Sed  // inputs into '-Wl,' options?
4195193326Sed  for (InputInfoList::const_iterator
4196193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
4197193326Sed    const InputInfo &II = *it;
4198193326Sed
4199198092Srdivacky    // Don't try to pass LLVM or AST inputs to a generic gcc.
4200210299Sed    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
4201210299Sed        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
4202226633Sdim      D.Diag(diag::err_drv_no_linker_llvm_support)
4203198092Srdivacky        << getToolChain().getTripleString();
4204198092Srdivacky    else if (II.getType() == types::TY_AST)
4205226633Sdim      D.Diag(diag::err_drv_no_ast_support)
4206198092Srdivacky        << getToolChain().getTripleString();
4207249423Sdim    else if (II.getType() == types::TY_ModuleFile)
4208249423Sdim      D.Diag(diag::err_drv_no_module_support)
4209249423Sdim        << getToolChain().getTripleString();
4210193326Sed
4211193326Sed    if (types::canTypeBeUserSpecified(II.getType())) {
4212193326Sed      CmdArgs.push_back("-x");
4213193326Sed      CmdArgs.push_back(types::getTypeName(II.getType()));
4214193326Sed    }
4215193326Sed
4216212904Sdim    if (II.isFilename())
4217193326Sed      CmdArgs.push_back(II.getFilename());
4218218893Sdim    else {
4219218893Sdim      const Arg &A = II.getInputArg();
4220218893Sdim
4221218893Sdim      // Reverse translate some rewritten options.
4222218893Sdim      if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
4223218893Sdim        CmdArgs.push_back("-lstdc++");
4224218893Sdim        continue;
4225218893Sdim      }
4226218893Sdim
4227193326Sed      // Don't render as input, we need gcc to do the translations.
4228218893Sdim      A.render(Args, CmdArgs);
4229218893Sdim    }
4230193326Sed  }
4231193326Sed
4232221345Sdim  const std::string customGCCName = D.getCCCGenericGCCName();
4233221345Sdim  const char *GCCName;
4234221345Sdim  if (!customGCCName.empty())
4235221345Sdim    GCCName = customGCCName.c_str();
4236263508Sdim  else if (D.CCCIsCXX()) {
4237221345Sdim    GCCName = "g++";
4238221345Sdim  } else
4239221345Sdim    GCCName = "gcc";
4240221345Sdim
4241193326Sed  const char *Exec =
4242210299Sed    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
4243212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4244193326Sed}
4245193326Sed
4246203955Srdivackyvoid gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
4247203955Srdivacky                                          ArgStringList &CmdArgs) const {
4248193326Sed  CmdArgs.push_back("-E");
4249193326Sed}
4250193326Sed
4251203955Srdivackyvoid gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
4252203955Srdivacky                                          ArgStringList &CmdArgs) const {
4253193326Sed  // The type is good enough.
4254193326Sed}
4255193326Sed
4256203955Srdivackyvoid gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
4257203955Srdivacky                                       ArgStringList &CmdArgs) const {
4258203955Srdivacky  const Driver &D = getToolChain().getDriver();
4259203955Srdivacky
4260203955Srdivacky  // If -flto, etc. are present then make sure not to force assembly output.
4261210299Sed  if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
4262210299Sed      JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
4263203955Srdivacky    CmdArgs.push_back("-c");
4264203955Srdivacky  else {
4265203955Srdivacky    if (JA.getType() != types::TY_PP_Asm)
4266226633Sdim      D.Diag(diag::err_drv_invalid_gcc_output_type)
4267203955Srdivacky        << getTypeName(JA.getType());
4268218893Sdim
4269203955Srdivacky    CmdArgs.push_back("-S");
4270203955Srdivacky  }
4271193326Sed}
4272193326Sed
4273203955Srdivackyvoid gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
4274203955Srdivacky                                        ArgStringList &CmdArgs) const {
4275193326Sed  CmdArgs.push_back("-c");
4276193326Sed}
4277193326Sed
4278203955Srdivackyvoid gcc::Link::RenderExtraToolArgs(const JobAction &JA,
4279203955Srdivacky                                    ArgStringList &CmdArgs) const {
4280193326Sed  // The types are (hopefully) good enough.
4281193326Sed}
4282193326Sed
4283234353Sdim// Hexagon tools start.
4284234353Sdimvoid hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA,
4285234353Sdim                                        ArgStringList &CmdArgs) const {
4286234353Sdim
4287234353Sdim}
4288234353Sdimvoid hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
4289234353Sdim                               const InputInfo &Output,
4290234353Sdim                               const InputInfoList &Inputs,
4291234353Sdim                               const ArgList &Args,
4292234353Sdim                               const char *LinkingOutput) const {
4293234353Sdim
4294234353Sdim  const Driver &D = getToolChain().getDriver();
4295234353Sdim  ArgStringList CmdArgs;
4296234353Sdim
4297234353Sdim  std::string MarchString = "-march=";
4298249423Sdim  MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args);
4299234353Sdim  CmdArgs.push_back(Args.MakeArgString(MarchString));
4300234353Sdim
4301234353Sdim  RenderExtraToolArgs(JA, CmdArgs);
4302234353Sdim
4303234353Sdim  if (Output.isFilename()) {
4304234353Sdim    CmdArgs.push_back("-o");
4305234353Sdim    CmdArgs.push_back(Output.getFilename());
4306234353Sdim  } else {
4307234353Sdim    assert(Output.isNothing() && "Unexpected output");
4308234353Sdim    CmdArgs.push_back("-fsyntax-only");
4309234353Sdim  }
4310234353Sdim
4311249423Sdim  std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
4312249423Sdim  if (!SmallDataThreshold.empty())
4313249423Sdim    CmdArgs.push_back(
4314249423Sdim      Args.MakeArgString(std::string("-G") + SmallDataThreshold));
4315234353Sdim
4316249423Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
4317249423Sdim                       options::OPT_Xassembler);
4318249423Sdim
4319234353Sdim  // Only pass -x if gcc will understand it; otherwise hope gcc
4320234353Sdim  // understands the suffix correctly. The main use case this would go
4321234353Sdim  // wrong in is for linker inputs if they happened to have an odd
4322234353Sdim  // suffix; really the only way to get this to happen is a command
4323234353Sdim  // like '-x foobar a.c' which will treat a.c like a linker input.
4324234353Sdim  //
4325234353Sdim  // FIXME: For the linker case specifically, can we safely convert
4326234353Sdim  // inputs into '-Wl,' options?
4327234353Sdim  for (InputInfoList::const_iterator
4328234353Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
4329234353Sdim    const InputInfo &II = *it;
4330234353Sdim
4331234353Sdim    // Don't try to pass LLVM or AST inputs to a generic gcc.
4332234353Sdim    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
4333234353Sdim        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
4334234353Sdim      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
4335234353Sdim        << getToolChain().getTripleString();
4336234353Sdim    else if (II.getType() == types::TY_AST)
4337234353Sdim      D.Diag(clang::diag::err_drv_no_ast_support)
4338234353Sdim        << getToolChain().getTripleString();
4339249423Sdim    else if (II.getType() == types::TY_ModuleFile)
4340249423Sdim      D.Diag(diag::err_drv_no_module_support)
4341249423Sdim      << getToolChain().getTripleString();
4342234353Sdim
4343234353Sdim    if (II.isFilename())
4344234353Sdim      CmdArgs.push_back(II.getFilename());
4345234353Sdim    else
4346234353Sdim      // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ?
4347234353Sdim      II.getInputArg().render(Args, CmdArgs);
4348234353Sdim  }
4349234353Sdim
4350234353Sdim  const char *GCCName = "hexagon-as";
4351234353Sdim  const char *Exec =
4352234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
4353234353Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4354234353Sdim
4355234353Sdim}
4356234353Sdimvoid hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
4357234353Sdim                                    ArgStringList &CmdArgs) const {
4358234353Sdim  // The types are (hopefully) good enough.
4359234353Sdim}
4360234353Sdim
4361234353Sdimvoid hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
4362234353Sdim                               const InputInfo &Output,
4363234353Sdim                               const InputInfoList &Inputs,
4364234353Sdim                               const ArgList &Args,
4365234353Sdim                               const char *LinkingOutput) const {
4366234353Sdim
4367249423Sdim  const toolchains::Hexagon_TC& ToolChain =
4368249423Sdim    static_cast<const toolchains::Hexagon_TC&>(getToolChain());
4369249423Sdim  const Driver &D = ToolChain.getDriver();
4370249423Sdim
4371234353Sdim  ArgStringList CmdArgs;
4372234353Sdim
4373249423Sdim  //----------------------------------------------------------------------------
4374249423Sdim  //
4375249423Sdim  //----------------------------------------------------------------------------
4376249423Sdim  bool hasStaticArg = Args.hasArg(options::OPT_static);
4377249423Sdim  bool buildingLib = Args.hasArg(options::OPT_shared);
4378249423Sdim  bool buildPIE = Args.hasArg(options::OPT_pie);
4379249423Sdim  bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
4380249423Sdim  bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
4381249423Sdim  bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
4382249423Sdim  bool useShared = buildingLib && !hasStaticArg;
4383234353Sdim
4384249423Sdim  //----------------------------------------------------------------------------
4385249423Sdim  // Silence warnings for various options
4386249423Sdim  //----------------------------------------------------------------------------
4387249423Sdim
4388249423Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
4389249423Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
4390249423Sdim  Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
4391249423Sdim                                     // handled somewhere else.
4392249423Sdim  Args.ClaimAllArgs(options::OPT_static_libgcc);
4393249423Sdim
4394249423Sdim  //----------------------------------------------------------------------------
4395249423Sdim  //
4396249423Sdim  //----------------------------------------------------------------------------
4397249423Sdim  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
4398249423Sdim         e = ToolChain.ExtraOpts.end();
4399249423Sdim       i != e; ++i)
4400249423Sdim    CmdArgs.push_back(i->c_str());
4401249423Sdim
4402249423Sdim  std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
4403249423Sdim  CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
4404249423Sdim
4405249423Sdim  if (buildingLib) {
4406249423Sdim    CmdArgs.push_back("-shared");
4407249423Sdim    CmdArgs.push_back("-call_shared"); // should be the default, but doing as
4408249423Sdim                                       // hexagon-gcc does
4409234353Sdim  }
4410234353Sdim
4411249423Sdim  if (hasStaticArg)
4412249423Sdim    CmdArgs.push_back("-static");
4413234353Sdim
4414249423Sdim  if (buildPIE && !buildingLib)
4415249423Sdim    CmdArgs.push_back("-pie");
4416249423Sdim
4417249423Sdim  std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
4418249423Sdim  if (!SmallDataThreshold.empty()) {
4419249423Sdim    CmdArgs.push_back(
4420249423Sdim      Args.MakeArgString(std::string("-G") + SmallDataThreshold));
4421234353Sdim  }
4422234353Sdim
4423249423Sdim  //----------------------------------------------------------------------------
4424249423Sdim  //
4425249423Sdim  //----------------------------------------------------------------------------
4426249423Sdim  CmdArgs.push_back("-o");
4427249423Sdim  CmdArgs.push_back(Output.getFilename());
4428234353Sdim
4429249423Sdim  const std::string MarchSuffix = "/" + MarchString;
4430249423Sdim  const std::string G0Suffix = "/G0";
4431249423Sdim  const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
4432249423Sdim  const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir)
4433249423Sdim                              + "/";
4434249423Sdim  const std::string StartFilesDir = RootDir
4435249423Sdim                                    + "hexagon/lib"
4436249423Sdim                                    + (buildingLib
4437249423Sdim                                       ? MarchG0Suffix : MarchSuffix);
4438234353Sdim
4439249423Sdim  //----------------------------------------------------------------------------
4440249423Sdim  // moslib
4441249423Sdim  //----------------------------------------------------------------------------
4442249423Sdim  std::vector<std::string> oslibs;
4443249423Sdim  bool hasStandalone= false;
4444249423Sdim
4445249423Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ),
4446249423Sdim         ie = Args.filtered_end(); it != ie; ++it) {
4447249423Sdim    (*it)->claim();
4448249423Sdim    oslibs.push_back((*it)->getValue());
4449249423Sdim    hasStandalone = hasStandalone || (oslibs.back() == "standalone");
4450234353Sdim  }
4451249423Sdim  if (oslibs.empty()) {
4452249423Sdim    oslibs.push_back("standalone");
4453249423Sdim    hasStandalone = true;
4454249423Sdim  }
4455234353Sdim
4456249423Sdim  //----------------------------------------------------------------------------
4457249423Sdim  // Start Files
4458249423Sdim  //----------------------------------------------------------------------------
4459249423Sdim  if (incStdLib && incStartFiles) {
4460234353Sdim
4461249423Sdim    if (!buildingLib) {
4462249423Sdim      if (hasStandalone) {
4463249423Sdim        CmdArgs.push_back(
4464249423Sdim          Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
4465249423Sdim      }
4466249423Sdim      CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
4467249423Sdim    }
4468249423Sdim    std::string initObj = useShared ? "/initS.o" : "/init.o";
4469249423Sdim    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj));
4470249423Sdim  }
4471234353Sdim
4472249423Sdim  //----------------------------------------------------------------------------
4473249423Sdim  // Library Search Paths
4474249423Sdim  //----------------------------------------------------------------------------
4475249423Sdim  const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
4476249423Sdim  for (ToolChain::path_list::const_iterator
4477249423Sdim         i = LibPaths.begin(),
4478249423Sdim         e = LibPaths.end();
4479249423Sdim       i != e;
4480249423Sdim       ++i)
4481249423Sdim    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
4482249423Sdim
4483249423Sdim  //----------------------------------------------------------------------------
4484249423Sdim  //
4485249423Sdim  //----------------------------------------------------------------------------
4486249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
4487249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
4488249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
4489249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
4490249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
4491249423Sdim
4492249423Sdim  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
4493249423Sdim
4494249423Sdim  //----------------------------------------------------------------------------
4495249423Sdim  // Libraries
4496249423Sdim  //----------------------------------------------------------------------------
4497249423Sdim  if (incStdLib && incDefLibs) {
4498263508Sdim    if (D.CCCIsCXX()) {
4499249423Sdim      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
4500249423Sdim      CmdArgs.push_back("-lm");
4501249423Sdim    }
4502249423Sdim
4503249423Sdim    CmdArgs.push_back("--start-group");
4504249423Sdim
4505249423Sdim    if (!buildingLib) {
4506249423Sdim      for(std::vector<std::string>::iterator i = oslibs.begin(),
4507249423Sdim            e = oslibs.end(); i != e; ++i)
4508249423Sdim        CmdArgs.push_back(Args.MakeArgString("-l" + *i));
4509249423Sdim      CmdArgs.push_back("-lc");
4510249423Sdim    }
4511249423Sdim    CmdArgs.push_back("-lgcc");
4512249423Sdim
4513249423Sdim    CmdArgs.push_back("--end-group");
4514234353Sdim  }
4515234353Sdim
4516249423Sdim  //----------------------------------------------------------------------------
4517249423Sdim  // End files
4518249423Sdim  //----------------------------------------------------------------------------
4519249423Sdim  if (incStdLib && incStartFiles) {
4520249423Sdim    std::string finiObj = useShared ? "/finiS.o" : "/fini.o";
4521249423Sdim    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj));
4522249423Sdim  }
4523249423Sdim
4524249423Sdim  std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
4525263508Sdim  C.addCommand(new Command(JA, *this, Args.MakeArgString(Linker), CmdArgs));
4526234353Sdim}
4527234353Sdim// Hexagon tools end.
4528234353Sdim
4529243830Sdimllvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
4530243830Sdim  // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
4531243830Sdim  // archs which Darwin doesn't use.
4532234353Sdim
4533243830Sdim  // The matching this routine does is fairly pointless, since it is neither the
4534243830Sdim  // complete architecture list, nor a reasonable subset. The problem is that
4535243830Sdim  // historically the driver driver accepts this and also ties its -march=
4536243830Sdim  // handling to the architecture name, so we need to be careful before removing
4537243830Sdim  // support for it.
4538243830Sdim
4539243830Sdim  // This code must be kept in sync with Clang's Darwin specific argument
4540243830Sdim  // translation.
4541243830Sdim
4542243830Sdim  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
4543243830Sdim    .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
4544243830Sdim    .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
4545243830Sdim    .Case("ppc64", llvm::Triple::ppc64)
4546243830Sdim    .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
4547243830Sdim    .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
4548243830Sdim           llvm::Triple::x86)
4549263508Sdim    .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
4550243830Sdim    // This is derived from the driver driver.
4551249423Sdim    .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
4552249423Sdim    .Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm)
4553249423Sdim    .Cases("armv7s", "xscale", llvm::Triple::arm)
4554243830Sdim    .Case("r600", llvm::Triple::r600)
4555243830Sdim    .Case("nvptx", llvm::Triple::nvptx)
4556243830Sdim    .Case("nvptx64", llvm::Triple::nvptx64)
4557243830Sdim    .Case("amdil", llvm::Triple::amdil)
4558243830Sdim    .Case("spir", llvm::Triple::spir)
4559243830Sdim    .Default(llvm::Triple::UnknownArch);
4560243830Sdim}
4561243830Sdim
4562249423Sdimconst char *Clang::getBaseInputName(const ArgList &Args,
4563249423Sdim                                    const InputInfoList &Inputs) {
4564218893Sdim  return Args.MakeArgString(
4565218893Sdim    llvm::sys::path::filename(Inputs[0].getBaseInput()));
4566193326Sed}
4567193326Sed
4568249423Sdimconst char *Clang::getBaseInputStem(const ArgList &Args,
4569249423Sdim                                    const InputInfoList &Inputs) {
4570193326Sed  const char *Str = getBaseInputName(Args, Inputs);
4571193326Sed
4572218893Sdim  if (const char *End = strrchr(Str, '.'))
4573198092Srdivacky    return Args.MakeArgString(std::string(Str, End));
4574193326Sed
4575193326Sed  return Str;
4576193326Sed}
4577193326Sed
4578249423Sdimconst char *Clang::getDependencyFileName(const ArgList &Args,
4579249423Sdim                                         const InputInfoList &Inputs) {
4580193326Sed  // FIXME: Think about this more.
4581193326Sed  std::string Res;
4582193326Sed
4583193326Sed  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
4584243830Sdim    std::string Str(OutputOpt->getValue());
4585193326Sed    Res = Str.substr(0, Str.rfind('.'));
4586226633Sdim  } else {
4587249423Sdim    Res = getBaseInputStem(Args, Inputs);
4588226633Sdim  }
4589198092Srdivacky  return Args.MakeArgString(Res + ".d");
4590193326Sed}
4591193326Sed
4592193326Sedvoid darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
4593212904Sdim                                    const InputInfo &Output,
4594193326Sed                                    const InputInfoList &Inputs,
4595193326Sed                                    const ArgList &Args,
4596193326Sed                                    const char *LinkingOutput) const {
4597193326Sed  ArgStringList CmdArgs;
4598193326Sed
4599193326Sed  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
4600193326Sed  const InputInfo &Input = Inputs[0];
4601193326Sed
4602221345Sdim  // Determine the original source input.
4603221345Sdim  const Action *SourceAction = &JA;
4604221345Sdim  while (SourceAction->getKind() != Action::InputClass) {
4605221345Sdim    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
4606221345Sdim    SourceAction = SourceAction->getInputs()[0];
4607221345Sdim  }
4608221345Sdim
4609263508Sdim  // If -no_integrated_as is used add -Q to the darwin assember driver to make
4610263508Sdim  // sure it runs its system assembler not clang's integrated assembler.
4611266715Sdim  // Applicable to darwin11+ and Xcode 4+.  darwin<10 lacked integrated-as.
4612266715Sdim  // FIXME: at run-time detect assembler capabilities or rely on version
4613266715Sdim  // information forwarded by -target-assembler-version (future)
4614266715Sdim  if (Args.hasArg(options::OPT_no_integrated_as)) {
4615266715Sdim    const llvm::Triple& t(getToolChain().getTriple());
4616266715Sdim    if (!(t.isMacOSX() && t.isMacOSXVersionLT(10, 7)))
4617266715Sdim      CmdArgs.push_back("-Q");
4618266715Sdim  }
4619263508Sdim
4620221345Sdim  // Forward -g, assuming we are dealing with an actual assembly file.
4621226633Sdim  if (SourceAction->getType() == types::TY_Asm ||
4622221345Sdim      SourceAction->getType() == types::TY_PP_Asm) {
4623193326Sed    if (Args.hasArg(options::OPT_gstabs))
4624193326Sed      CmdArgs.push_back("--gstabs");
4625193326Sed    else if (Args.hasArg(options::OPT_g_Group))
4626234353Sdim      CmdArgs.push_back("-g");
4627193326Sed  }
4628193326Sed
4629193326Sed  // Derived from asm spec.
4630198092Srdivacky  AddDarwinArch(Args, CmdArgs);
4631193326Sed
4632212904Sdim  // Use -force_cpusubtype_ALL on x86 by default.
4633263508Sdim  if (getToolChain().getArch() == llvm::Triple::x86 ||
4634263508Sdim      getToolChain().getArch() == llvm::Triple::x86_64 ||
4635198092Srdivacky      Args.hasArg(options::OPT_force__cpusubtype__ALL))
4636198092Srdivacky    CmdArgs.push_back("-force_cpusubtype_ALL");
4637198092Srdivacky
4638263508Sdim  if (getToolChain().getArch() != llvm::Triple::x86_64 &&
4639243830Sdim      (((Args.hasArg(options::OPT_mkernel) ||
4640243830Sdim         Args.hasArg(options::OPT_fapple_kext)) &&
4641243830Sdim        (!getDarwinToolChain().isTargetIPhoneOS() ||
4642243830Sdim         getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) ||
4643243830Sdim       Args.hasArg(options::OPT_static)))
4644193326Sed    CmdArgs.push_back("-static");
4645193326Sed
4646193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
4647193326Sed                       options::OPT_Xassembler);
4648193326Sed
4649193326Sed  assert(Output.isFilename() && "Unexpected lipo output.");
4650193326Sed  CmdArgs.push_back("-o");
4651193326Sed  CmdArgs.push_back(Output.getFilename());
4652193326Sed
4653212904Sdim  assert(Input.isFilename() && "Invalid input.");
4654212904Sdim  CmdArgs.push_back(Input.getFilename());
4655193326Sed
4656193326Sed  // asm_final spec is empty.
4657193326Sed
4658193326Sed  const char *Exec =
4659210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
4660212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4661193326Sed}
4662193326Sed
4663234353Sdimvoid darwin::DarwinTool::anchor() {}
4664234353Sdim
4665198092Srdivackyvoid darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
4666198092Srdivacky                                       ArgStringList &CmdArgs) const {
4667226633Sdim  StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
4668202879Srdivacky
4669193326Sed  // Derived from darwin_arch spec.
4670193326Sed  CmdArgs.push_back("-arch");
4671202879Srdivacky  CmdArgs.push_back(Args.MakeArgString(ArchName));
4672198092Srdivacky
4673202879Srdivacky  // FIXME: Is this needed anymore?
4674202879Srdivacky  if (ArchName == "arm")
4675198092Srdivacky    CmdArgs.push_back("-force_cpusubtype_ALL");
4676193326Sed}
4677193326Sed
4678243830Sdimbool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const {
4679243830Sdim  // We only need to generate a temp path for LTO if we aren't compiling object
4680243830Sdim  // files. When compiling source files, we run 'dsymutil' after linking. We
4681243830Sdim  // don't run 'dsymutil' when compiling object files.
4682243830Sdim  for (InputInfoList::const_iterator
4683243830Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
4684243830Sdim    if (it->getType() != types::TY_Object)
4685243830Sdim      return true;
4686243830Sdim
4687243830Sdim  return false;
4688243830Sdim}
4689243830Sdim
4690218893Sdimvoid darwin::Link::AddLinkArgs(Compilation &C,
4691218893Sdim                               const ArgList &Args,
4692243830Sdim                               ArgStringList &CmdArgs,
4693243830Sdim                               const InputInfoList &Inputs) const {
4694201361Srdivacky  const Driver &D = getToolChain().getDriver();
4695221345Sdim  const toolchains::Darwin &DarwinTC = getDarwinToolChain();
4696193326Sed
4697212904Sdim  unsigned Version[3] = { 0, 0, 0 };
4698212904Sdim  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
4699212904Sdim    bool HadExtra;
4700243830Sdim    if (!Driver::GetReleaseVersion(A->getValue(), Version[0],
4701212904Sdim                                   Version[1], Version[2], HadExtra) ||
4702212904Sdim        HadExtra)
4703226633Sdim      D.Diag(diag::err_drv_invalid_version_number)
4704212904Sdim        << A->getAsString(Args);
4705212904Sdim  }
4706212904Sdim
4707212904Sdim  // Newer linkers support -demangle, pass it if supported and not disabled by
4708212904Sdim  // the user.
4709234353Sdim  if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) {
4710218893Sdim    // Don't pass -demangle to ld_classic.
4711218893Sdim    //
4712218893Sdim    // FIXME: This is a temporary workaround, ld should be handling this.
4713218893Sdim    bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 &&
4714218893Sdim                          Args.hasArg(options::OPT_static));
4715218893Sdim    if (getToolChain().getArch() == llvm::Triple::x86) {
4716218893Sdim      for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker,
4717218893Sdim                                                 options::OPT_Wl_COMMA),
4718218893Sdim             ie = Args.filtered_end(); it != ie; ++it) {
4719218893Sdim        const Arg *A = *it;
4720218893Sdim        for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
4721243830Sdim          if (StringRef(A->getValue(i)) == "-kext")
4722218893Sdim            UsesLdClassic = true;
4723218893Sdim      }
4724218893Sdim    }
4725218893Sdim    if (!UsesLdClassic)
4726218893Sdim      CmdArgs.push_back("-demangle");
4727212904Sdim  }
4728212904Sdim
4729263508Sdim  if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
4730263508Sdim    CmdArgs.push_back("-export_dynamic");
4731263508Sdim
4732224145Sdim  // If we are using LTO, then automatically create a temporary file path for
4733224145Sdim  // the linker to use, so that it's lifetime will extend past a possible
4734224145Sdim  // dsymutil step.
4735243830Sdim  if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
4736224145Sdim    const char *TmpPath = C.getArgs().MakeArgString(
4737226633Sdim      D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
4738224145Sdim    C.addTempFile(TmpPath);
4739224145Sdim    CmdArgs.push_back("-object_path_lto");
4740224145Sdim    CmdArgs.push_back(TmpPath);
4741224145Sdim  }
4742224145Sdim
4743193326Sed  // Derived from the "link" spec.
4744193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_static);
4745193326Sed  if (!Args.hasArg(options::OPT_static))
4746193326Sed    CmdArgs.push_back("-dynamic");
4747193326Sed  if (Args.hasArg(options::OPT_fgnu_runtime)) {
4748193326Sed    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
4749193326Sed    // here. How do we wish to handle such things?
4750193326Sed  }
4751193326Sed
4752193326Sed  if (!Args.hasArg(options::OPT_dynamiclib)) {
4753202879Srdivacky    AddDarwinArch(Args, CmdArgs);
4754202879Srdivacky    // FIXME: Why do this only on this path?
4755202879Srdivacky    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
4756193326Sed
4757193326Sed    Args.AddLastArg(CmdArgs, options::OPT_bundle);
4758193326Sed    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
4759193326Sed    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
4760193326Sed
4761193326Sed    Arg *A;
4762193326Sed    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
4763193326Sed        (A = Args.getLastArg(options::OPT_current__version)) ||
4764193326Sed        (A = Args.getLastArg(options::OPT_install__name)))
4765226633Sdim      D.Diag(diag::err_drv_argument_only_allowed_with)
4766193326Sed        << A->getAsString(Args) << "-dynamiclib";
4767193326Sed
4768193326Sed    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
4769193326Sed    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
4770193326Sed    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
4771193326Sed  } else {
4772193326Sed    CmdArgs.push_back("-dylib");
4773193326Sed
4774193326Sed    Arg *A;
4775193326Sed    if ((A = Args.getLastArg(options::OPT_bundle)) ||
4776193326Sed        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
4777193326Sed        (A = Args.getLastArg(options::OPT_client__name)) ||
4778193326Sed        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
4779193326Sed        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
4780193326Sed        (A = Args.getLastArg(options::OPT_private__bundle)))
4781226633Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
4782193326Sed        << A->getAsString(Args) << "-dynamiclib";
4783193326Sed
4784193326Sed    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
4785193326Sed                              "-dylib_compatibility_version");
4786193326Sed    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
4787193326Sed                              "-dylib_current_version");
4788193326Sed
4789202879Srdivacky    AddDarwinArch(Args, CmdArgs);
4790193326Sed
4791193326Sed    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
4792193326Sed                              "-dylib_install_name");
4793193326Sed  }
4794193326Sed
4795193326Sed  Args.AddLastArg(CmdArgs, options::OPT_all__load);
4796193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
4797193326Sed  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
4798221345Sdim  if (DarwinTC.isTargetIPhoneOS())
4799198092Srdivacky    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
4800193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
4801193326Sed  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
4802193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
4803193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
4804193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
4805193326Sed  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
4806224145Sdim  Args.AddAllArgs(CmdArgs, options::OPT_force__load);
4807193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
4808193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
4809193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_init);
4810193326Sed
4811221345Sdim  // Add the deployment target.
4812234353Sdim  VersionTuple TargetVersion = DarwinTC.getTargetVersion();
4813221345Sdim
4814221345Sdim  // If we had an explicit -mios-simulator-version-min argument, honor that,
4815221345Sdim  // otherwise use the traditional deployment targets. We can't just check the
4816221345Sdim  // is-sim attribute because existing code follows this path, and the linker
4817221345Sdim  // may not handle the argument.
4818221345Sdim  //
4819221345Sdim  // FIXME: We may be able to remove this, once we can verify no one depends on
4820221345Sdim  // it.
4821221345Sdim  if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
4822221345Sdim    CmdArgs.push_back("-ios_simulator_version_min");
4823221345Sdim  else if (DarwinTC.isTargetIPhoneOS())
4824221345Sdim    CmdArgs.push_back("-iphoneos_version_min");
4825221345Sdim  else
4826221345Sdim    CmdArgs.push_back("-macosx_version_min");
4827234353Sdim  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
4828221345Sdim
4829193326Sed  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
4830193326Sed  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
4831193326Sed  Args.AddLastArg(CmdArgs, options::OPT_single__module);
4832193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
4833193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
4834193326Sed
4835210299Sed  if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
4836210299Sed                                     options::OPT_fno_pie,
4837210299Sed                                     options::OPT_fno_PIE)) {
4838210299Sed    if (A->getOption().matches(options::OPT_fpie) ||
4839210299Sed        A->getOption().matches(options::OPT_fPIE))
4840210299Sed      CmdArgs.push_back("-pie");
4841210299Sed    else
4842210299Sed      CmdArgs.push_back("-no_pie");
4843210299Sed  }
4844193326Sed
4845193326Sed  Args.AddLastArg(CmdArgs, options::OPT_prebind);
4846193326Sed  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
4847193326Sed  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
4848193326Sed  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
4849193326Sed  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
4850193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
4851193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
4852193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
4853193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
4854193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
4855193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
4856193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
4857193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
4858193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
4859193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
4860193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
4861198092Srdivacky
4862223017Sdim  // Give --sysroot= preference, over the Apple specific behavior to also use
4863223017Sdim  // --isysroot as the syslibroot.
4864234982Sdim  StringRef sysroot = C.getSysRoot();
4865234982Sdim  if (sysroot != "") {
4866223017Sdim    CmdArgs.push_back("-syslibroot");
4867234982Sdim    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
4868223017Sdim  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
4869223017Sdim    CmdArgs.push_back("-syslibroot");
4870243830Sdim    CmdArgs.push_back(A->getValue());
4871198092Srdivacky  }
4872198092Srdivacky
4873193326Sed  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
4874193326Sed  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
4875193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
4876193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
4877193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
4878193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
4879193326Sed  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
4880193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_y);
4881193326Sed  Args.AddLastArg(CmdArgs, options::OPT_w);
4882193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
4883193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
4884193326Sed  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
4885193326Sed  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
4886193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
4887193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
4888193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
4889193326Sed  Args.AddLastArg(CmdArgs, options::OPT_whyload);
4890193326Sed  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
4891193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
4892193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
4893193326Sed  Args.AddLastArg(CmdArgs, options::OPT_Mach);
4894193326Sed}
4895193326Sed
4896193326Sedvoid darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
4897212904Sdim                                const InputInfo &Output,
4898193326Sed                                const InputInfoList &Inputs,
4899193326Sed                                const ArgList &Args,
4900193326Sed                                const char *LinkingOutput) const {
4901193326Sed  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
4902198092Srdivacky
4903193326Sed  // The logic here is derived from gcc's behavior; most of which
4904193326Sed  // comes from specs (starting with link_command). Consult gcc for
4905193326Sed  // more information.
4906193326Sed  ArgStringList CmdArgs;
4907193326Sed
4908226633Sdim  /// Hack(tm) to ignore linking errors when we are doing ARC migration.
4909226633Sdim  if (Args.hasArg(options::OPT_ccc_arcmt_check,
4910226633Sdim                  options::OPT_ccc_arcmt_migrate)) {
4911226633Sdim    for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I)
4912226633Sdim      (*I)->claim();
4913226633Sdim    const char *Exec =
4914226633Sdim      Args.MakeArgString(getToolChain().GetProgramPath("touch"));
4915226633Sdim    CmdArgs.push_back(Output.getFilename());
4916226633Sdim    C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4917226633Sdim    return;
4918226633Sdim  }
4919226633Sdim
4920193326Sed  // I'm not sure why this particular decomposition exists in gcc, but
4921193326Sed  // we follow suite for ease of comparison.
4922243830Sdim  AddLinkArgs(C, Args, CmdArgs, Inputs);
4923193326Sed
4924193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
4925193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_s);
4926193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_t);
4927193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
4928193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
4929193326Sed  Args.AddLastArg(CmdArgs, options::OPT_e);
4930193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_r);
4931193326Sed
4932218893Sdim  // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
4933218893Sdim  // members of static archive libraries which implement Objective-C classes or
4934218893Sdim  // categories.
4935218893Sdim  if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
4936218893Sdim    CmdArgs.push_back("-ObjC");
4937218893Sdim
4938193326Sed  CmdArgs.push_back("-o");
4939193326Sed  CmdArgs.push_back(Output.getFilename());
4940193326Sed
4941239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
4942193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
4943193326Sed    // Derived from startfile spec.
4944193326Sed    if (Args.hasArg(options::OPT_dynamiclib)) {
4945193326Sed      // Derived from darwin_dylib1 spec.
4946221345Sdim      if (getDarwinToolChain().isTargetIOSSimulator()) {
4947221345Sdim        // The simulator doesn't have a versioned crt1 file.
4948221345Sdim        CmdArgs.push_back("-ldylib1.o");
4949221345Sdim      } else if (getDarwinToolChain().isTargetIPhoneOS()) {
4950203955Srdivacky        if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
4951203955Srdivacky          CmdArgs.push_back("-ldylib1.o");
4952203955Srdivacky      } else {
4953203955Srdivacky        if (getDarwinToolChain().isMacosxVersionLT(10, 5))
4954203955Srdivacky          CmdArgs.push_back("-ldylib1.o");
4955203955Srdivacky        else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
4956203955Srdivacky          CmdArgs.push_back("-ldylib1.10.5.o");
4957203955Srdivacky      }
4958193326Sed    } else {
4959193326Sed      if (Args.hasArg(options::OPT_bundle)) {
4960193326Sed        if (!Args.hasArg(options::OPT_static)) {
4961193326Sed          // Derived from darwin_bundle1 spec.
4962221345Sdim          if (getDarwinToolChain().isTargetIOSSimulator()) {
4963221345Sdim            // The simulator doesn't have a versioned crt1 file.
4964221345Sdim            CmdArgs.push_back("-lbundle1.o");
4965221345Sdim          } else if (getDarwinToolChain().isTargetIPhoneOS()) {
4966203955Srdivacky            if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
4967203955Srdivacky              CmdArgs.push_back("-lbundle1.o");
4968203955Srdivacky          } else {
4969203955Srdivacky            if (getDarwinToolChain().isMacosxVersionLT(10, 6))
4970203955Srdivacky              CmdArgs.push_back("-lbundle1.o");
4971203955Srdivacky          }
4972193326Sed        }
4973193326Sed      } else {
4974221345Sdim        if (Args.hasArg(options::OPT_pg) &&
4975221345Sdim            getToolChain().SupportsProfiling()) {
4976193326Sed          if (Args.hasArg(options::OPT_static) ||
4977193326Sed              Args.hasArg(options::OPT_object) ||
4978193326Sed              Args.hasArg(options::OPT_preload)) {
4979193326Sed            CmdArgs.push_back("-lgcrt0.o");
4980193326Sed          } else {
4981193326Sed            CmdArgs.push_back("-lgcrt1.o");
4982193326Sed
4983193326Sed            // darwin_crt2 spec is empty.
4984193326Sed          }
4985239462Sdim          // By default on OS X 10.8 and later, we don't link with a crt1.o
4986239462Sdim          // file and the linker knows to use _main as the entry point.  But,
4987239462Sdim          // when compiling with -pg, we need to link with the gcrt1.o file,
4988239462Sdim          // so pass the -no_new_main option to tell the linker to use the
4989239462Sdim          // "start" symbol as the entry point.
4990239462Sdim          if (getDarwinToolChain().isTargetMacOS() &&
4991239462Sdim              !getDarwinToolChain().isMacosxVersionLT(10, 8))
4992239462Sdim            CmdArgs.push_back("-no_new_main");
4993193326Sed        } else {
4994193326Sed          if (Args.hasArg(options::OPT_static) ||
4995193326Sed              Args.hasArg(options::OPT_object) ||
4996193326Sed              Args.hasArg(options::OPT_preload)) {
4997193326Sed            CmdArgs.push_back("-lcrt0.o");
4998193326Sed          } else {
4999193326Sed            // Derived from darwin_crt1 spec.
5000221345Sdim            if (getDarwinToolChain().isTargetIOSSimulator()) {
5001221345Sdim              // The simulator doesn't have a versioned crt1 file.
5002221345Sdim              CmdArgs.push_back("-lcrt1.o");
5003221345Sdim            } else if (getDarwinToolChain().isTargetIPhoneOS()) {
5004203955Srdivacky              if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
5005203955Srdivacky                CmdArgs.push_back("-lcrt1.o");
5006243830Sdim              else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0))
5007203955Srdivacky                CmdArgs.push_back("-lcrt1.3.1.o");
5008203955Srdivacky            } else {
5009203955Srdivacky              if (getDarwinToolChain().isMacosxVersionLT(10, 5))
5010203955Srdivacky                CmdArgs.push_back("-lcrt1.o");
5011203955Srdivacky              else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
5012203955Srdivacky                CmdArgs.push_back("-lcrt1.10.5.o");
5013234353Sdim              else if (getDarwinToolChain().isMacosxVersionLT(10, 8))
5014203955Srdivacky                CmdArgs.push_back("-lcrt1.10.6.o");
5015193326Sed
5016203955Srdivacky              // darwin_crt2 spec is empty.
5017203955Srdivacky            }
5018193326Sed          }
5019193326Sed        }
5020193326Sed      }
5021193326Sed    }
5022193326Sed
5023203955Srdivacky    if (!getDarwinToolChain().isTargetIPhoneOS() &&
5024203955Srdivacky        Args.hasArg(options::OPT_shared_libgcc) &&
5025203955Srdivacky        getDarwinToolChain().isMacosxVersionLT(10, 5)) {
5026198092Srdivacky      const char *Str =
5027210299Sed        Args.MakeArgString(getToolChain().GetFilePath("crt3.o"));
5028198092Srdivacky      CmdArgs.push_back(Str);
5029193326Sed    }
5030193326Sed  }
5031193326Sed
5032193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
5033193326Sed
5034193326Sed  if (Args.hasArg(options::OPT_fopenmp))
5035193326Sed    // This is more complicated in gcc...
5036193326Sed    CmdArgs.push_back("-lgomp");
5037193326Sed
5038239462Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5039239462Sdim
5040239462Sdim  if (isObjCRuntimeLinked(Args) &&
5041239462Sdim      !Args.hasArg(options::OPT_nostdlib) &&
5042239462Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5043234353Sdim    // Avoid linking compatibility stubs on i386 mac.
5044234353Sdim    if (!getDarwinToolChain().isTargetMacOS() ||
5045243830Sdim        getDarwinToolChain().getArch() != llvm::Triple::x86) {
5046234353Sdim      // If we don't have ARC or subscripting runtime support, link in the
5047234353Sdim      // runtime stubs.  We have to do this *before* adding any of the normal
5048234353Sdim      // linker inputs so that its initializer gets run first.
5049239462Sdim      ObjCRuntime runtime =
5050239462Sdim        getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true);
5051234353Sdim      // We use arclite library for both ARC and subscripting support.
5052243830Sdim      if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) ||
5053239462Sdim          !runtime.hasSubscripting())
5054234353Sdim        getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
5055234353Sdim    }
5056239462Sdim    CmdArgs.push_back("-framework");
5057239462Sdim    CmdArgs.push_back("Foundation");
5058234353Sdim    // Link libobj.
5059234353Sdim    CmdArgs.push_back("-lobjc");
5060224145Sdim  }
5061224145Sdim
5062193326Sed  if (LinkingOutput) {
5063193326Sed    CmdArgs.push_back("-arch_multiple");
5064193326Sed    CmdArgs.push_back("-final_output");
5065193326Sed    CmdArgs.push_back(LinkingOutput);
5066193326Sed  }
5067193326Sed
5068193326Sed  if (Args.hasArg(options::OPT_fnested_functions))
5069193326Sed    CmdArgs.push_back("-allow_stack_execute");
5070193326Sed
5071193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5072193326Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
5073263508Sdim    if (getToolChain().getDriver().CCCIsCXX())
5074218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5075193326Sed
5076193326Sed    // link_ssp spec is empty.
5077193326Sed
5078198092Srdivacky    // Let the tool chain choose which runtime library to link.
5079198092Srdivacky    getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
5080193326Sed  }
5081193326Sed
5082239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5083193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5084193326Sed    // endfile_spec is empty.
5085193326Sed  }
5086193326Sed
5087193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5088193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_F);
5089193326Sed
5090193326Sed  const char *Exec =
5091210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5092212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5093193326Sed}
5094193326Sed
5095193326Sedvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
5096212904Sdim                                const InputInfo &Output,
5097193326Sed                                const InputInfoList &Inputs,
5098193326Sed                                const ArgList &Args,
5099193326Sed                                const char *LinkingOutput) const {
5100193326Sed  ArgStringList CmdArgs;
5101193326Sed
5102193326Sed  CmdArgs.push_back("-create");
5103193326Sed  assert(Output.isFilename() && "Unexpected lipo output.");
5104193326Sed
5105193326Sed  CmdArgs.push_back("-output");
5106193326Sed  CmdArgs.push_back(Output.getFilename());
5107193326Sed
5108193326Sed  for (InputInfoList::const_iterator
5109193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5110193326Sed    const InputInfo &II = *it;
5111193326Sed    assert(II.isFilename() && "Unexpected lipo input.");
5112193326Sed    CmdArgs.push_back(II.getFilename());
5113193326Sed  }
5114193326Sed  const char *Exec =
5115210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
5116212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5117193326Sed}
5118193326Sed
5119210299Sedvoid darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
5120212904Sdim                                    const InputInfo &Output,
5121210299Sed                                    const InputInfoList &Inputs,
5122210299Sed                                    const ArgList &Args,
5123210299Sed                                    const char *LinkingOutput) const {
5124210299Sed  ArgStringList CmdArgs;
5125210299Sed
5126223017Sdim  CmdArgs.push_back("-o");
5127223017Sdim  CmdArgs.push_back(Output.getFilename());
5128223017Sdim
5129210299Sed  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
5130210299Sed  const InputInfo &Input = Inputs[0];
5131210299Sed  assert(Input.isFilename() && "Unexpected dsymutil input.");
5132210299Sed  CmdArgs.push_back(Input.getFilename());
5133210299Sed
5134210299Sed  const char *Exec =
5135210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
5136212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5137210299Sed}
5138210299Sed
5139226633Sdimvoid darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
5140249423Sdim                                       const InputInfo &Output,
5141249423Sdim                                       const InputInfoList &Inputs,
5142249423Sdim                                       const ArgList &Args,
5143249423Sdim                                       const char *LinkingOutput) const {
5144226633Sdim  ArgStringList CmdArgs;
5145226633Sdim  CmdArgs.push_back("--verify");
5146234353Sdim  CmdArgs.push_back("--debug-info");
5147234353Sdim  CmdArgs.push_back("--eh-frame");
5148234353Sdim  CmdArgs.push_back("--quiet");
5149226633Sdim
5150226633Sdim  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
5151226633Sdim  const InputInfo &Input = Inputs[0];
5152226633Sdim  assert(Input.isFilename() && "Unexpected verify input");
5153226633Sdim
5154226633Sdim  // Grabbing the output of the earlier dsymutil run.
5155226633Sdim  CmdArgs.push_back(Input.getFilename());
5156226633Sdim
5157226633Sdim  const char *Exec =
5158226633Sdim    Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
5159226633Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5160226633Sdim}
5161226633Sdim
5162234353Sdimvoid solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5163234353Sdim                                      const InputInfo &Output,
5164234353Sdim                                      const InputInfoList &Inputs,
5165234353Sdim                                      const ArgList &Args,
5166234353Sdim                                      const char *LinkingOutput) const {
5167234353Sdim  ArgStringList CmdArgs;
5168234353Sdim
5169234353Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5170234353Sdim                       options::OPT_Xassembler);
5171234353Sdim
5172234353Sdim  CmdArgs.push_back("-o");
5173234353Sdim  CmdArgs.push_back(Output.getFilename());
5174234353Sdim
5175234353Sdim  for (InputInfoList::const_iterator
5176234353Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5177234353Sdim    const InputInfo &II = *it;
5178234353Sdim    CmdArgs.push_back(II.getFilename());
5179234353Sdim  }
5180234353Sdim
5181234353Sdim  const char *Exec =
5182234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5183234353Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5184234353Sdim}
5185234353Sdim
5186234353Sdim
5187234353Sdimvoid solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
5188234353Sdim                                  const InputInfo &Output,
5189234353Sdim                                  const InputInfoList &Inputs,
5190234353Sdim                                  const ArgList &Args,
5191234353Sdim                                  const char *LinkingOutput) const {
5192234353Sdim  // FIXME: Find a real GCC, don't hard-code versions here
5193234353Sdim  std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/";
5194234353Sdim  const llvm::Triple &T = getToolChain().getTriple();
5195234353Sdim  std::string LibPath = "/usr/lib/";
5196234353Sdim  llvm::Triple::ArchType Arch = T.getArch();
5197234353Sdim  switch (Arch) {
5198263508Sdim  case llvm::Triple::x86:
5199263508Sdim    GCCLibPath +=
5200263508Sdim        ("i386-" + T.getVendorName() + "-" + T.getOSName()).str() + "/4.5.2/";
5201263508Sdim    break;
5202263508Sdim  case llvm::Triple::x86_64:
5203263508Sdim    GCCLibPath += ("i386-" + T.getVendorName() + "-" + T.getOSName()).str();
5204263508Sdim    GCCLibPath += "/4.5.2/amd64/";
5205263508Sdim    LibPath += "amd64/";
5206263508Sdim    break;
5207263508Sdim  default:
5208263508Sdim    llvm_unreachable("Unsupported architecture");
5209234353Sdim  }
5210234353Sdim
5211234353Sdim  ArgStringList CmdArgs;
5212234353Sdim
5213234353Sdim  // Demangle C++ names in errors
5214234353Sdim  CmdArgs.push_back("-C");
5215234353Sdim
5216234353Sdim  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5217234353Sdim      (!Args.hasArg(options::OPT_shared))) {
5218234353Sdim    CmdArgs.push_back("-e");
5219234353Sdim    CmdArgs.push_back("_start");
5220234353Sdim  }
5221234353Sdim
5222234353Sdim  if (Args.hasArg(options::OPT_static)) {
5223234353Sdim    CmdArgs.push_back("-Bstatic");
5224234353Sdim    CmdArgs.push_back("-dn");
5225234353Sdim  } else {
5226234353Sdim    CmdArgs.push_back("-Bdynamic");
5227234353Sdim    if (Args.hasArg(options::OPT_shared)) {
5228234353Sdim      CmdArgs.push_back("-shared");
5229234353Sdim    } else {
5230234353Sdim      CmdArgs.push_back("--dynamic-linker");
5231234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
5232234353Sdim    }
5233234353Sdim  }
5234234353Sdim
5235234353Sdim  if (Output.isFilename()) {
5236234353Sdim    CmdArgs.push_back("-o");
5237234353Sdim    CmdArgs.push_back(Output.getFilename());
5238234353Sdim  } else {
5239234353Sdim    assert(Output.isNothing() && "Invalid output.");
5240234353Sdim  }
5241234353Sdim
5242234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5243234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5244234353Sdim    if (!Args.hasArg(options::OPT_shared)) {
5245234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o"));
5246234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
5247234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
5248234353Sdim      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
5249234353Sdim    } else {
5250234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
5251234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
5252234353Sdim      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
5253234353Sdim    }
5254263508Sdim    if (getToolChain().getDriver().CCCIsCXX())
5255234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
5256234353Sdim  }
5257234353Sdim
5258234353Sdim  CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath));
5259234353Sdim
5260234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
5261234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5262234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
5263234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
5264234353Sdim
5265234353Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5266234353Sdim
5267234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5268234353Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5269263508Sdim    if (getToolChain().getDriver().CCCIsCXX())
5270234353Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5271234353Sdim    CmdArgs.push_back("-lgcc_s");
5272234353Sdim    if (!Args.hasArg(options::OPT_shared)) {
5273234353Sdim      CmdArgs.push_back("-lgcc");
5274234353Sdim      CmdArgs.push_back("-lc");
5275234353Sdim      CmdArgs.push_back("-lm");
5276234353Sdim    }
5277234353Sdim  }
5278234353Sdim
5279234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5280234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5281234353Sdim    CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
5282234353Sdim  }
5283234353Sdim  CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
5284234353Sdim
5285234353Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
5286234353Sdim
5287234353Sdim  const char *Exec =
5288234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5289234353Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5290234353Sdim}
5291234353Sdim
5292198092Srdivackyvoid auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5293212904Sdim                                      const InputInfo &Output,
5294198893Srdivacky                                      const InputInfoList &Inputs,
5295198893Srdivacky                                      const ArgList &Args,
5296198893Srdivacky                                      const char *LinkingOutput) const {
5297198092Srdivacky  ArgStringList CmdArgs;
5298198092Srdivacky
5299198092Srdivacky  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5300198092Srdivacky                       options::OPT_Xassembler);
5301198092Srdivacky
5302198092Srdivacky  CmdArgs.push_back("-o");
5303212904Sdim  CmdArgs.push_back(Output.getFilename());
5304198092Srdivacky
5305198092Srdivacky  for (InputInfoList::const_iterator
5306198092Srdivacky         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5307198092Srdivacky    const InputInfo &II = *it;
5308212904Sdim    CmdArgs.push_back(II.getFilename());
5309198092Srdivacky  }
5310198092Srdivacky
5311198092Srdivacky  const char *Exec =
5312210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
5313212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5314198092Srdivacky}
5315198092Srdivacky
5316198092Srdivackyvoid auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
5317212904Sdim                                  const InputInfo &Output,
5318198893Srdivacky                                  const InputInfoList &Inputs,
5319198893Srdivacky                                  const ArgList &Args,
5320198893Srdivacky                                  const char *LinkingOutput) const {
5321198092Srdivacky  ArgStringList CmdArgs;
5322198092Srdivacky
5323198092Srdivacky  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5324198893Srdivacky      (!Args.hasArg(options::OPT_shared))) {
5325198092Srdivacky    CmdArgs.push_back("-e");
5326198398Srdivacky    CmdArgs.push_back("_start");
5327198092Srdivacky  }
5328198092Srdivacky
5329198092Srdivacky  if (Args.hasArg(options::OPT_static)) {
5330198092Srdivacky    CmdArgs.push_back("-Bstatic");
5331198398Srdivacky    CmdArgs.push_back("-dn");
5332198092Srdivacky  } else {
5333198398Srdivacky//    CmdArgs.push_back("--eh-frame-hdr");
5334198092Srdivacky    CmdArgs.push_back("-Bdynamic");
5335198092Srdivacky    if (Args.hasArg(options::OPT_shared)) {
5336198092Srdivacky      CmdArgs.push_back("-shared");
5337198092Srdivacky    } else {
5338198398Srdivacky      CmdArgs.push_back("--dynamic-linker");
5339198092Srdivacky      CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
5340198092Srdivacky    }
5341198092Srdivacky  }
5342198092Srdivacky
5343212904Sdim  if (Output.isFilename()) {
5344198092Srdivacky    CmdArgs.push_back("-o");
5345198092Srdivacky    CmdArgs.push_back(Output.getFilename());
5346198092Srdivacky  } else {
5347198092Srdivacky    assert(Output.isNothing() && "Invalid output.");
5348198092Srdivacky  }
5349198092Srdivacky
5350198092Srdivacky  if (!Args.hasArg(options::OPT_nostdlib) &&
5351198092Srdivacky      !Args.hasArg(options::OPT_nostartfiles)) {
5352198092Srdivacky    if (!Args.hasArg(options::OPT_shared)) {
5353210299Sed      CmdArgs.push_back(Args.MakeArgString(
5354210299Sed                                getToolChain().GetFilePath("crt1.o")));
5355210299Sed      CmdArgs.push_back(Args.MakeArgString(
5356210299Sed                                getToolChain().GetFilePath("crti.o")));
5357210299Sed      CmdArgs.push_back(Args.MakeArgString(
5358210299Sed                                getToolChain().GetFilePath("crtbegin.o")));
5359198092Srdivacky    } else {
5360210299Sed      CmdArgs.push_back(Args.MakeArgString(
5361210299Sed                                getToolChain().GetFilePath("crti.o")));
5362198092Srdivacky    }
5363210299Sed    CmdArgs.push_back(Args.MakeArgString(
5364210299Sed                                getToolChain().GetFilePath("crtn.o")));
5365198092Srdivacky  }
5366198092Srdivacky
5367198893Srdivacky  CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
5368198893Srdivacky                                       + getToolChain().getTripleString()
5369198893Srdivacky                                       + "/4.2.4"));
5370198092Srdivacky
5371198092Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_L);
5372198092Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5373198092Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_e);
5374198092Srdivacky
5375218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5376198092Srdivacky
5377198092Srdivacky  if (!Args.hasArg(options::OPT_nostdlib) &&
5378198092Srdivacky      !Args.hasArg(options::OPT_nodefaultlibs)) {
5379198092Srdivacky    // FIXME: For some reason GCC passes -lgcc before adding
5380198092Srdivacky    // the default system libraries. Just mimic this for now.
5381198092Srdivacky    CmdArgs.push_back("-lgcc");
5382198092Srdivacky
5383198092Srdivacky    if (Args.hasArg(options::OPT_pthread))
5384198092Srdivacky      CmdArgs.push_back("-pthread");
5385198092Srdivacky    if (!Args.hasArg(options::OPT_shared))
5386198092Srdivacky      CmdArgs.push_back("-lc");
5387198092Srdivacky    CmdArgs.push_back("-lgcc");
5388198092Srdivacky  }
5389198092Srdivacky
5390198092Srdivacky  if (!Args.hasArg(options::OPT_nostdlib) &&
5391198092Srdivacky      !Args.hasArg(options::OPT_nostartfiles)) {
5392198092Srdivacky    if (!Args.hasArg(options::OPT_shared))
5393210299Sed      CmdArgs.push_back(Args.MakeArgString(
5394210299Sed                                getToolChain().GetFilePath("crtend.o")));
5395198092Srdivacky  }
5396198092Srdivacky
5397224145Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
5398223017Sdim
5399198092Srdivacky  const char *Exec =
5400210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5401212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5402198092Srdivacky}
5403198092Srdivacky
5404195341Sedvoid openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5405212904Sdim                                     const InputInfo &Output,
5406195341Sed                                     const InputInfoList &Inputs,
5407195341Sed                                     const ArgList &Args,
5408198092Srdivacky                                     const char *LinkingOutput) const {
5409195341Sed  ArgStringList CmdArgs;
5410193326Sed
5411263508Sdim  // When building 32-bit code on OpenBSD/amd64, we have to explicitly
5412263508Sdim  // instruct as in the base system to assemble 32-bit code.
5413263508Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
5414263508Sdim    CmdArgs.push_back("--32");
5415263508Sdim  else if (getToolChain().getArch() == llvm::Triple::ppc) {
5416263508Sdim    CmdArgs.push_back("-mppc");
5417263508Sdim    CmdArgs.push_back("-many");
5418263508Sdim  } else if (getToolChain().getArch() == llvm::Triple::mips64 ||
5419263508Sdim             getToolChain().getArch() == llvm::Triple::mips64el) {
5420263508Sdim    StringRef CPUName;
5421263508Sdim    StringRef ABIName;
5422263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
5423263508Sdim
5424263508Sdim    CmdArgs.push_back("-mabi");
5425263508Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
5426263508Sdim
5427263508Sdim    if (getToolChain().getArch() == llvm::Triple::mips64)
5428263508Sdim      CmdArgs.push_back("-EB");
5429263508Sdim    else
5430263508Sdim      CmdArgs.push_back("-EL");
5431263508Sdim
5432263508Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
5433263508Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
5434263508Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
5435263508Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
5436263508Sdim    if (LastPICArg &&
5437263508Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
5438263508Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
5439263508Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
5440263508Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
5441263508Sdim      CmdArgs.push_back("-KPIC");
5442263508Sdim    }
5443263508Sdim  }
5444263508Sdim
5445195341Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5446195341Sed                       options::OPT_Xassembler);
5447195341Sed
5448195341Sed  CmdArgs.push_back("-o");
5449212904Sdim  CmdArgs.push_back(Output.getFilename());
5450195341Sed
5451195341Sed  for (InputInfoList::const_iterator
5452195341Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5453195341Sed    const InputInfo &II = *it;
5454212904Sdim    CmdArgs.push_back(II.getFilename());
5455195341Sed  }
5456195341Sed
5457195341Sed  const char *Exec =
5458210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5459212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5460195341Sed}
5461195341Sed
5462195341Sedvoid openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
5463212904Sdim                                 const InputInfo &Output,
5464195341Sed                                 const InputInfoList &Inputs,
5465195341Sed                                 const ArgList &Args,
5466195341Sed                                 const char *LinkingOutput) const {
5467201361Srdivacky  const Driver &D = getToolChain().getDriver();
5468195341Sed  ArgStringList CmdArgs;
5469195341Sed
5470249423Sdim  // Silence warning for "clang -g foo.o -o foo"
5471249423Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
5472249423Sdim  // and "clang -emit-llvm foo.o -o foo"
5473249423Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
5474249423Sdim  // and for "clang -w foo.o -o foo". Other warning options are already
5475249423Sdim  // handled somewhere else.
5476249423Sdim  Args.ClaimAllArgs(options::OPT_w);
5477249423Sdim
5478263508Sdim  if (getToolChain().getArch() == llvm::Triple::mips64)
5479263508Sdim    CmdArgs.push_back("-EB");
5480263508Sdim  else if (getToolChain().getArch() == llvm::Triple::mips64el)
5481263508Sdim    CmdArgs.push_back("-EL");
5482263508Sdim
5483198092Srdivacky  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5484198893Srdivacky      (!Args.hasArg(options::OPT_shared))) {
5485198092Srdivacky    CmdArgs.push_back("-e");
5486198092Srdivacky    CmdArgs.push_back("__start");
5487198092Srdivacky  }
5488198092Srdivacky
5489195341Sed  if (Args.hasArg(options::OPT_static)) {
5490195341Sed    CmdArgs.push_back("-Bstatic");
5491195341Sed  } else {
5492218893Sdim    if (Args.hasArg(options::OPT_rdynamic))
5493218893Sdim      CmdArgs.push_back("-export-dynamic");
5494195341Sed    CmdArgs.push_back("--eh-frame-hdr");
5495198092Srdivacky    CmdArgs.push_back("-Bdynamic");
5496195341Sed    if (Args.hasArg(options::OPT_shared)) {
5497198092Srdivacky      CmdArgs.push_back("-shared");
5498195341Sed    } else {
5499195341Sed      CmdArgs.push_back("-dynamic-linker");
5500195341Sed      CmdArgs.push_back("/usr/libexec/ld.so");
5501195341Sed    }
5502195341Sed  }
5503195341Sed
5504263508Sdim  if (Args.hasArg(options::OPT_nopie))
5505263508Sdim    CmdArgs.push_back("-nopie");
5506263508Sdim
5507212904Sdim  if (Output.isFilename()) {
5508195341Sed    CmdArgs.push_back("-o");
5509195341Sed    CmdArgs.push_back(Output.getFilename());
5510195341Sed  } else {
5511195341Sed    assert(Output.isNothing() && "Invalid output.");
5512195341Sed  }
5513195341Sed
5514195341Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5515195341Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5516195341Sed    if (!Args.hasArg(options::OPT_shared)) {
5517234353Sdim      if (Args.hasArg(options::OPT_pg))
5518234353Sdim        CmdArgs.push_back(Args.MakeArgString(
5519234353Sdim                                getToolChain().GetFilePath("gcrt0.o")));
5520234353Sdim      else
5521234353Sdim        CmdArgs.push_back(Args.MakeArgString(
5522234353Sdim                                getToolChain().GetFilePath("crt0.o")));
5523210299Sed      CmdArgs.push_back(Args.MakeArgString(
5524210299Sed                              getToolChain().GetFilePath("crtbegin.o")));
5525195341Sed    } else {
5526210299Sed      CmdArgs.push_back(Args.MakeArgString(
5527210299Sed                              getToolChain().GetFilePath("crtbeginS.o")));
5528195341Sed    }
5529195341Sed  }
5530195341Sed
5531198893Srdivacky  std::string Triple = getToolChain().getTripleString();
5532198893Srdivacky  if (Triple.substr(0, 6) == "x86_64")
5533198893Srdivacky    Triple.replace(0, 6, "amd64");
5534198893Srdivacky  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
5535212904Sdim                                       "/4.2.1"));
5536198092Srdivacky
5537195341Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
5538195341Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5539195341Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
5540249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
5541249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
5542249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
5543249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
5544195341Sed
5545218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5546195341Sed
5547195341Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5548195341Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
5549263508Sdim    if (D.CCCIsCXX()) {
5550218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5551234353Sdim      if (Args.hasArg(options::OPT_pg))
5552234353Sdim        CmdArgs.push_back("-lm_p");
5553234353Sdim      else
5554234353Sdim        CmdArgs.push_back("-lm");
5555212904Sdim    }
5556212904Sdim
5557198092Srdivacky    // FIXME: For some reason GCC passes -lgcc before adding
5558198092Srdivacky    // the default system libraries. Just mimic this for now.
5559198092Srdivacky    CmdArgs.push_back("-lgcc");
5560195341Sed
5561243830Sdim    if (Args.hasArg(options::OPT_pthread)) {
5562243830Sdim      if (!Args.hasArg(options::OPT_shared) &&
5563243830Sdim          Args.hasArg(options::OPT_pg))
5564243830Sdim         CmdArgs.push_back("-lpthread_p");
5565243830Sdim      else
5566243830Sdim         CmdArgs.push_back("-lpthread");
5567243830Sdim    }
5568243830Sdim
5569234353Sdim    if (!Args.hasArg(options::OPT_shared)) {
5570243830Sdim      if (Args.hasArg(options::OPT_pg))
5571234353Sdim         CmdArgs.push_back("-lc_p");
5572234353Sdim      else
5573234353Sdim         CmdArgs.push_back("-lc");
5574234353Sdim    }
5575243830Sdim
5576198092Srdivacky    CmdArgs.push_back("-lgcc");
5577195341Sed  }
5578195341Sed
5579195341Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5580195341Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5581195341Sed    if (!Args.hasArg(options::OPT_shared))
5582210299Sed      CmdArgs.push_back(Args.MakeArgString(
5583210299Sed                              getToolChain().GetFilePath("crtend.o")));
5584195341Sed    else
5585210299Sed      CmdArgs.push_back(Args.MakeArgString(
5586210299Sed                              getToolChain().GetFilePath("crtendS.o")));
5587195341Sed  }
5588195341Sed
5589195341Sed  const char *Exec =
5590210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5591212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5592195341Sed}
5593195341Sed
5594239462Sdimvoid bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5595239462Sdim                                    const InputInfo &Output,
5596239462Sdim                                    const InputInfoList &Inputs,
5597239462Sdim                                    const ArgList &Args,
5598239462Sdim                                    const char *LinkingOutput) const {
5599239462Sdim  ArgStringList CmdArgs;
5600239462Sdim
5601239462Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5602239462Sdim                       options::OPT_Xassembler);
5603239462Sdim
5604239462Sdim  CmdArgs.push_back("-o");
5605239462Sdim  CmdArgs.push_back(Output.getFilename());
5606239462Sdim
5607239462Sdim  for (InputInfoList::const_iterator
5608239462Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5609239462Sdim    const InputInfo &II = *it;
5610239462Sdim    CmdArgs.push_back(II.getFilename());
5611239462Sdim  }
5612239462Sdim
5613239462Sdim  const char *Exec =
5614239462Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5615239462Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5616239462Sdim}
5617239462Sdim
5618239462Sdimvoid bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
5619239462Sdim                                const InputInfo &Output,
5620239462Sdim                                const InputInfoList &Inputs,
5621239462Sdim                                const ArgList &Args,
5622239462Sdim                                const char *LinkingOutput) const {
5623239462Sdim  const Driver &D = getToolChain().getDriver();
5624239462Sdim  ArgStringList CmdArgs;
5625239462Sdim
5626239462Sdim  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5627239462Sdim      (!Args.hasArg(options::OPT_shared))) {
5628239462Sdim    CmdArgs.push_back("-e");
5629239462Sdim    CmdArgs.push_back("__start");
5630239462Sdim  }
5631239462Sdim
5632239462Sdim  if (Args.hasArg(options::OPT_static)) {
5633239462Sdim    CmdArgs.push_back("-Bstatic");
5634239462Sdim  } else {
5635239462Sdim    if (Args.hasArg(options::OPT_rdynamic))
5636239462Sdim      CmdArgs.push_back("-export-dynamic");
5637239462Sdim    CmdArgs.push_back("--eh-frame-hdr");
5638239462Sdim    CmdArgs.push_back("-Bdynamic");
5639239462Sdim    if (Args.hasArg(options::OPT_shared)) {
5640239462Sdim      CmdArgs.push_back("-shared");
5641239462Sdim    } else {
5642239462Sdim      CmdArgs.push_back("-dynamic-linker");
5643239462Sdim      CmdArgs.push_back("/usr/libexec/ld.so");
5644239462Sdim    }
5645239462Sdim  }
5646239462Sdim
5647239462Sdim  if (Output.isFilename()) {
5648239462Sdim    CmdArgs.push_back("-o");
5649239462Sdim    CmdArgs.push_back(Output.getFilename());
5650239462Sdim  } else {
5651239462Sdim    assert(Output.isNothing() && "Invalid output.");
5652239462Sdim  }
5653239462Sdim
5654239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5655239462Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5656239462Sdim    if (!Args.hasArg(options::OPT_shared)) {
5657239462Sdim      if (Args.hasArg(options::OPT_pg))
5658239462Sdim        CmdArgs.push_back(Args.MakeArgString(
5659239462Sdim                                getToolChain().GetFilePath("gcrt0.o")));
5660239462Sdim      else
5661239462Sdim        CmdArgs.push_back(Args.MakeArgString(
5662239462Sdim                                getToolChain().GetFilePath("crt0.o")));
5663239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5664239462Sdim                              getToolChain().GetFilePath("crtbegin.o")));
5665239462Sdim    } else {
5666239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5667239462Sdim                              getToolChain().GetFilePath("crtbeginS.o")));
5668239462Sdim    }
5669239462Sdim  }
5670239462Sdim
5671239462Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
5672239462Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5673239462Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
5674239462Sdim
5675239462Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5676239462Sdim
5677239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5678239462Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5679263508Sdim    if (D.CCCIsCXX()) {
5680239462Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5681239462Sdim      if (Args.hasArg(options::OPT_pg))
5682239462Sdim        CmdArgs.push_back("-lm_p");
5683239462Sdim      else
5684239462Sdim        CmdArgs.push_back("-lm");
5685239462Sdim    }
5686239462Sdim
5687243830Sdim    if (Args.hasArg(options::OPT_pthread)) {
5688243830Sdim      if (!Args.hasArg(options::OPT_shared) &&
5689243830Sdim          Args.hasArg(options::OPT_pg))
5690243830Sdim        CmdArgs.push_back("-lpthread_p");
5691243830Sdim      else
5692243830Sdim        CmdArgs.push_back("-lpthread");
5693243830Sdim    }
5694243830Sdim
5695239462Sdim    if (!Args.hasArg(options::OPT_shared)) {
5696239462Sdim      if (Args.hasArg(options::OPT_pg))
5697239462Sdim        CmdArgs.push_back("-lc_p");
5698239462Sdim      else
5699239462Sdim        CmdArgs.push_back("-lc");
5700239462Sdim    }
5701239462Sdim
5702263508Sdim    StringRef MyArch;
5703263508Sdim    switch (getToolChain().getTriple().getArch()) {
5704263508Sdim    case llvm::Triple::arm:
5705263508Sdim      MyArch = "arm";
5706263508Sdim      break;
5707263508Sdim    case llvm::Triple::x86:
5708263508Sdim      MyArch = "i386";
5709263508Sdim      break;
5710263508Sdim    case llvm::Triple::x86_64:
5711263508Sdim      MyArch = "amd64";
5712263508Sdim      break;
5713263508Sdim    default:
5714263508Sdim      llvm_unreachable("Unsupported architecture");
5715263508Sdim    }
5716263508Sdim    CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch));
5717239462Sdim  }
5718239462Sdim
5719239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5720239462Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5721239462Sdim    if (!Args.hasArg(options::OPT_shared))
5722239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5723239462Sdim                              getToolChain().GetFilePath("crtend.o")));
5724239462Sdim    else
5725239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5726239462Sdim                              getToolChain().GetFilePath("crtendS.o")));
5727239462Sdim  }
5728239462Sdim
5729239462Sdim  const char *Exec =
5730239462Sdim    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5731239462Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5732239462Sdim}
5733239462Sdim
5734193326Sedvoid freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5735212904Sdim                                     const InputInfo &Output,
5736193326Sed                                     const InputInfoList &Inputs,
5737193326Sed                                     const ArgList &Args,
5738198092Srdivacky                                     const char *LinkingOutput) const {
5739193326Sed  ArgStringList CmdArgs;
5740193326Sed
5741193326Sed  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
5742193326Sed  // instruct as in the base system to assemble 32-bit code.
5743243830Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
5744193326Sed    CmdArgs.push_back("--32");
5745243830Sdim  else if (getToolChain().getArch() == llvm::Triple::ppc)
5746223017Sdim    CmdArgs.push_back("-a32");
5747243830Sdim  else if (getToolChain().getArch() == llvm::Triple::mips ||
5748243830Sdim           getToolChain().getArch() == llvm::Triple::mipsel ||
5749243830Sdim           getToolChain().getArch() == llvm::Triple::mips64 ||
5750243830Sdim           getToolChain().getArch() == llvm::Triple::mips64el) {
5751243830Sdim    StringRef CPUName;
5752243830Sdim    StringRef ABIName;
5753263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
5754218893Sdim
5755243830Sdim    CmdArgs.push_back("-march");
5756243830Sdim    CmdArgs.push_back(CPUName.data());
5757204643Srdivacky
5758243830Sdim    CmdArgs.push_back("-mabi");
5759249423Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
5760243830Sdim
5761243830Sdim    if (getToolChain().getArch() == llvm::Triple::mips ||
5762243830Sdim        getToolChain().getArch() == llvm::Triple::mips64)
5763243830Sdim      CmdArgs.push_back("-EB");
5764243830Sdim    else
5765243830Sdim      CmdArgs.push_back("-EL");
5766243830Sdim
5767243830Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
5768243830Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
5769243830Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
5770243830Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
5771243830Sdim    if (LastPICArg &&
5772243830Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
5773243830Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
5774243830Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
5775243830Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
5776243830Sdim      CmdArgs.push_back("-KPIC");
5777243830Sdim    }
5778244640Sandrew  } else if (getToolChain().getArch() == llvm::Triple::arm ||
5779244640Sandrew             getToolChain().getArch() == llvm::Triple::thumb) {
5780244640Sandrew    CmdArgs.push_back("-mfpu=softvfp");
5781244640Sandrew    switch(getToolChain().getTriple().getEnvironment()) {
5782244640Sandrew    case llvm::Triple::GNUEABI:
5783244640Sandrew    case llvm::Triple::EABI:
5784248548Sandrew      CmdArgs.push_back("-meabi=5");
5785244640Sandrew      break;
5786244640Sandrew
5787244640Sandrew    default:
5788244640Sandrew      CmdArgs.push_back("-matpcs");
5789244640Sandrew    }
5790263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::sparc ||
5791263763Sdim             getToolChain().getArch() == llvm::Triple::sparcv9) {
5792263763Sdim    if (getToolChain().getArch() == llvm::Triple::sparc)
5793263763Sdim      CmdArgs.push_back("-Av8plusa");
5794263763Sdim    else
5795263763Sdim      CmdArgs.push_back("-Av9a");
5796263763Sdim
5797263763Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
5798263763Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
5799263763Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
5800263763Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
5801263763Sdim    if (LastPICArg &&
5802263763Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
5803263763Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
5804263763Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
5805263763Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
5806263763Sdim      CmdArgs.push_back("-KPIC");
5807263763Sdim    }
5808243830Sdim  }
5809243830Sdim
5810193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5811193326Sed                       options::OPT_Xassembler);
5812193326Sed
5813193326Sed  CmdArgs.push_back("-o");
5814212904Sdim  CmdArgs.push_back(Output.getFilename());
5815193326Sed
5816193326Sed  for (InputInfoList::const_iterator
5817193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5818193326Sed    const InputInfo &II = *it;
5819212904Sdim    CmdArgs.push_back(II.getFilename());
5820193326Sed  }
5821193326Sed
5822193326Sed  const char *Exec =
5823210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5824212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5825193326Sed}
5826193326Sed
5827193326Sedvoid freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
5828212904Sdim                                 const InputInfo &Output,
5829193326Sed                                 const InputInfoList &Inputs,
5830193326Sed                                 const ArgList &Args,
5831193326Sed                                 const char *LinkingOutput) const {
5832243830Sdim  const toolchains::FreeBSD& ToolChain =
5833243830Sdim    static_cast<const toolchains::FreeBSD&>(getToolChain());
5834243830Sdim  const Driver &D = ToolChain.getDriver();
5835193326Sed  ArgStringList CmdArgs;
5836193326Sed
5837238864Sdim  // Silence warning for "clang -g foo.o -o foo"
5838238864Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
5839238864Sdim  // and "clang -emit-llvm foo.o -o foo"
5840238864Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
5841238864Sdim  // and for "clang -w foo.o -o foo". Other warning options are already
5842238864Sdim  // handled somewhere else.
5843238864Sdim  Args.ClaimAllArgs(options::OPT_w);
5844238864Sdim
5845221345Sdim  if (!D.SysRoot.empty())
5846221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
5847221345Sdim
5848243830Sdim  if (Args.hasArg(options::OPT_pie))
5849243830Sdim    CmdArgs.push_back("-pie");
5850243830Sdim
5851193326Sed  if (Args.hasArg(options::OPT_static)) {
5852193326Sed    CmdArgs.push_back("-Bstatic");
5853193326Sed  } else {
5854218893Sdim    if (Args.hasArg(options::OPT_rdynamic))
5855218893Sdim      CmdArgs.push_back("-export-dynamic");
5856193326Sed    CmdArgs.push_back("--eh-frame-hdr");
5857193326Sed    if (Args.hasArg(options::OPT_shared)) {
5858193326Sed      CmdArgs.push_back("-Bshareable");
5859193326Sed    } else {
5860193326Sed      CmdArgs.push_back("-dynamic-linker");
5861193326Sed      CmdArgs.push_back("/libexec/ld-elf.so.1");
5862193326Sed    }
5863243830Sdim    if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
5864243830Sdim      llvm::Triple::ArchType Arch = ToolChain.getArch();
5865239462Sdim      if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
5866239462Sdim          Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
5867239462Sdim        CmdArgs.push_back("--hash-style=both");
5868239462Sdim      }
5869239462Sdim    }
5870238863Sdim    CmdArgs.push_back("--enable-new-dtags");
5871193326Sed  }
5872193326Sed
5873193326Sed  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
5874193326Sed  // instruct ld in the base system to link 32-bit code.
5875243830Sdim  if (ToolChain.getArch() == llvm::Triple::x86) {
5876193326Sed    CmdArgs.push_back("-m");
5877193326Sed    CmdArgs.push_back("elf_i386_fbsd");
5878193326Sed  }
5879193326Sed
5880243830Sdim  if (ToolChain.getArch() == llvm::Triple::ppc) {
5881223017Sdim    CmdArgs.push_back("-m");
5882227739Sandreast    CmdArgs.push_back("elf32ppc_fbsd");
5883223017Sdim  }
5884223017Sdim
5885212904Sdim  if (Output.isFilename()) {
5886193326Sed    CmdArgs.push_back("-o");
5887193326Sed    CmdArgs.push_back(Output.getFilename());
5888193326Sed  } else {
5889193326Sed    assert(Output.isNothing() && "Invalid output.");
5890193326Sed  }
5891193326Sed
5892193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5893193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5894243830Sdim    const char *crt1 = NULL;
5895193326Sed    if (!Args.hasArg(options::OPT_shared)) {
5896218893Sdim      if (Args.hasArg(options::OPT_pg))
5897243830Sdim        crt1 = "gcrt1.o";
5898243830Sdim      else if (Args.hasArg(options::OPT_pie))
5899243830Sdim        crt1 = "Scrt1.o";
5900243830Sdim      else
5901243830Sdim        crt1 = "crt1.o";
5902193326Sed    }
5903243830Sdim    if (crt1)
5904243830Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
5905243830Sdim
5906243830Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
5907243830Sdim
5908243830Sdim    const char *crtbegin = NULL;
5909243830Sdim    if (Args.hasArg(options::OPT_static))
5910243830Sdim      crtbegin = "crtbeginT.o";
5911243830Sdim    else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
5912243830Sdim      crtbegin = "crtbeginS.o";
5913243830Sdim    else
5914243830Sdim      crtbegin = "crtbegin.o";
5915243830Sdim
5916243830Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
5917193326Sed  }
5918193326Sed
5919193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
5920243830Sdim  const ToolChain::path_list Paths = ToolChain.getFilePaths();
5921219011Sdim  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
5922219011Sdim       i != e; ++i)
5923226633Sdim    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
5924193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5925193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
5926212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
5927212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
5928212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
5929212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
5930193326Sed
5931263508Sdim  // Tell the linker to load the plugin. This has to come before AddLinkerInputs
5932263508Sdim  // as gold requires -plugin to come before any -plugin-opt that -Wl might
5933263508Sdim  // forward.
5934263508Sdim  if (D.IsUsingLTO(Args)) {
5935263508Sdim    CmdArgs.push_back("-plugin");
5936263508Sdim    std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
5937263508Sdim    CmdArgs.push_back(Args.MakeArgString(Plugin));
5938263508Sdim
5939263508Sdim    // Try to pass driver level flags relevant to LTO code generation down to
5940263508Sdim    // the plugin.
5941263508Sdim
5942263508Sdim    // Handle flags for selecting CPU variants.
5943263508Sdim    std::string CPU = getCPUName(Args, ToolChain.getTriple());
5944263508Sdim    if (!CPU.empty()) {
5945263508Sdim      CmdArgs.push_back(
5946263508Sdim                        Args.MakeArgString(Twine("-plugin-opt=mcpu=") +
5947263508Sdim                                           CPU));
5948263508Sdim    }
5949263508Sdim  }
5950263508Sdim
5951243830Sdim  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
5952218893Sdim
5953218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5954218893Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5955263508Sdim    if (D.CCCIsCXX()) {
5956243830Sdim      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
5957218893Sdim      if (Args.hasArg(options::OPT_pg))
5958218893Sdim        CmdArgs.push_back("-lm_p");
5959218893Sdim      else
5960218893Sdim        CmdArgs.push_back("-lm");
5961218893Sdim    }
5962218893Sdim    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
5963218893Sdim    // the default system libraries. Just mimic this for now.
5964218893Sdim    if (Args.hasArg(options::OPT_pg))
5965218893Sdim      CmdArgs.push_back("-lgcc_p");
5966218893Sdim    else
5967218893Sdim      CmdArgs.push_back("-lgcc");
5968218893Sdim    if (Args.hasArg(options::OPT_static)) {
5969218893Sdim      CmdArgs.push_back("-lgcc_eh");
5970218893Sdim    } else if (Args.hasArg(options::OPT_pg)) {
5971218893Sdim      CmdArgs.push_back("-lgcc_eh_p");
5972218893Sdim    } else {
5973218893Sdim      CmdArgs.push_back("--as-needed");
5974218893Sdim      CmdArgs.push_back("-lgcc_s");
5975218893Sdim      CmdArgs.push_back("--no-as-needed");
5976218893Sdim    }
5977218893Sdim
5978218893Sdim    if (Args.hasArg(options::OPT_pthread)) {
5979218893Sdim      if (Args.hasArg(options::OPT_pg))
5980218893Sdim        CmdArgs.push_back("-lpthread_p");
5981218893Sdim      else
5982218893Sdim        CmdArgs.push_back("-lpthread");
5983218893Sdim    }
5984218893Sdim
5985218893Sdim    if (Args.hasArg(options::OPT_pg)) {
5986218893Sdim      if (Args.hasArg(options::OPT_shared))
5987218893Sdim        CmdArgs.push_back("-lc");
5988218893Sdim      else
5989218893Sdim        CmdArgs.push_back("-lc_p");
5990218893Sdim      CmdArgs.push_back("-lgcc_p");
5991218893Sdim    } else {
5992218893Sdim      CmdArgs.push_back("-lc");
5993218893Sdim      CmdArgs.push_back("-lgcc");
5994218893Sdim    }
5995218893Sdim
5996218893Sdim    if (Args.hasArg(options::OPT_static)) {
5997218893Sdim      CmdArgs.push_back("-lgcc_eh");
5998218893Sdim    } else if (Args.hasArg(options::OPT_pg)) {
5999218893Sdim      CmdArgs.push_back("-lgcc_eh_p");
6000218893Sdim    } else {
6001218893Sdim      CmdArgs.push_back("--as-needed");
6002218893Sdim      CmdArgs.push_back("-lgcc_s");
6003218893Sdim      CmdArgs.push_back("--no-as-needed");
6004218893Sdim    }
6005218893Sdim  }
6006218893Sdim
6007218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6008218893Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6009243830Sdim    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
6010243830Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
6011218893Sdim    else
6012243830Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
6013243830Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
6014218893Sdim  }
6015218893Sdim
6016243830Sdim  addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
6017223017Sdim
6018218893Sdim  const char *Exec =
6019243830Sdim    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
6020218893Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6021218893Sdim}
6022218893Sdim
6023218893Sdimvoid netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6024218893Sdim                                     const InputInfo &Output,
6025218893Sdim                                     const InputInfoList &Inputs,
6026218893Sdim                                     const ArgList &Args,
6027218893Sdim                                     const char *LinkingOutput) const {
6028218893Sdim  ArgStringList CmdArgs;
6029218893Sdim
6030218893Sdim  // When building 32-bit code on NetBSD/amd64, we have to explicitly
6031218893Sdim  // instruct as in the base system to assemble 32-bit code.
6032234353Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
6033218893Sdim    CmdArgs.push_back("--32");
6034218893Sdim
6035263508Sdim  // Pass the target CPU to GNU as for ARM, since the source code might
6036263508Sdim  // not have the correct .cpu annotation.
6037263508Sdim  if (getToolChain().getArch() == llvm::Triple::arm) {
6038263508Sdim    std::string MArch(getARMTargetCPU(Args, getToolChain().getTriple()));
6039263508Sdim    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
6040263508Sdim  }
6041218893Sdim
6042263508Sdim  if (getToolChain().getArch() == llvm::Triple::mips ||
6043263508Sdim      getToolChain().getArch() == llvm::Triple::mipsel ||
6044263508Sdim      getToolChain().getArch() == llvm::Triple::mips64 ||
6045263508Sdim      getToolChain().getArch() == llvm::Triple::mips64el) {
6046263508Sdim    StringRef CPUName;
6047263508Sdim    StringRef ABIName;
6048263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6049263508Sdim
6050263508Sdim    CmdArgs.push_back("-march");
6051263508Sdim    CmdArgs.push_back(CPUName.data());
6052263508Sdim
6053263508Sdim    CmdArgs.push_back("-mabi");
6054263508Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6055263508Sdim
6056263508Sdim    if (getToolChain().getArch() == llvm::Triple::mips ||
6057263508Sdim        getToolChain().getArch() == llvm::Triple::mips64)
6058263508Sdim      CmdArgs.push_back("-EB");
6059263508Sdim    else
6060263508Sdim      CmdArgs.push_back("-EL");
6061263508Sdim
6062263508Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
6063263508Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
6064263508Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
6065263508Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
6066263508Sdim    if (LastPICArg &&
6067263508Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
6068263508Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
6069263508Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
6070263508Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
6071263508Sdim      CmdArgs.push_back("-KPIC");
6072263508Sdim    }
6073263508Sdim  }
6074263508Sdim
6075218893Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6076218893Sdim                       options::OPT_Xassembler);
6077218893Sdim
6078218893Sdim  CmdArgs.push_back("-o");
6079218893Sdim  CmdArgs.push_back(Output.getFilename());
6080218893Sdim
6081193326Sed  for (InputInfoList::const_iterator
6082193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6083193326Sed    const InputInfo &II = *it;
6084218893Sdim    CmdArgs.push_back(II.getFilename());
6085218893Sdim  }
6086193326Sed
6087226633Sdim  const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
6088218893Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6089218893Sdim}
6090193326Sed
6091218893Sdimvoid netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
6092218893Sdim                                 const InputInfo &Output,
6093218893Sdim                                 const InputInfoList &Inputs,
6094218893Sdim                                 const ArgList &Args,
6095218893Sdim                                 const char *LinkingOutput) const {
6096218893Sdim  const Driver &D = getToolChain().getDriver();
6097218893Sdim  ArgStringList CmdArgs;
6098218893Sdim
6099221345Sdim  if (!D.SysRoot.empty())
6100221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6101221345Sdim
6102218893Sdim  if (Args.hasArg(options::OPT_static)) {
6103218893Sdim    CmdArgs.push_back("-Bstatic");
6104218893Sdim  } else {
6105218893Sdim    if (Args.hasArg(options::OPT_rdynamic))
6106218893Sdim      CmdArgs.push_back("-export-dynamic");
6107218893Sdim    CmdArgs.push_back("--eh-frame-hdr");
6108218893Sdim    if (Args.hasArg(options::OPT_shared)) {
6109218893Sdim      CmdArgs.push_back("-Bshareable");
6110218893Sdim    } else {
6111218893Sdim      CmdArgs.push_back("-dynamic-linker");
6112218893Sdim      CmdArgs.push_back("/libexec/ld.elf_so");
6113218893Sdim    }
6114193326Sed  }
6115193326Sed
6116218893Sdim  // When building 32-bit code on NetBSD/amd64, we have to explicitly
6117218893Sdim  // instruct ld in the base system to link 32-bit code.
6118234353Sdim  if (getToolChain().getArch() == llvm::Triple::x86) {
6119218893Sdim    CmdArgs.push_back("-m");
6120218893Sdim    CmdArgs.push_back("elf_i386");
6121218893Sdim  }
6122218893Sdim
6123218893Sdim  if (Output.isFilename()) {
6124218893Sdim    CmdArgs.push_back("-o");
6125218893Sdim    CmdArgs.push_back(Output.getFilename());
6126218893Sdim  } else {
6127218893Sdim    assert(Output.isNothing() && "Invalid output.");
6128218893Sdim  }
6129218893Sdim
6130193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6131218893Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6132218893Sdim    if (!Args.hasArg(options::OPT_shared)) {
6133218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6134218893Sdim                              getToolChain().GetFilePath("crt0.o")));
6135218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6136218893Sdim                              getToolChain().GetFilePath("crti.o")));
6137218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6138218893Sdim                              getToolChain().GetFilePath("crtbegin.o")));
6139218893Sdim    } else {
6140218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6141218893Sdim                              getToolChain().GetFilePath("crti.o")));
6142218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6143218893Sdim                              getToolChain().GetFilePath("crtbeginS.o")));
6144218893Sdim    }
6145218893Sdim  }
6146218893Sdim
6147218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
6148218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6149218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
6150218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
6151218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
6152218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
6153218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
6154218893Sdim
6155218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6156218893Sdim
6157263508Sdim  unsigned Major, Minor, Micro;
6158263508Sdim  getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
6159263508Sdim  bool useLibgcc = true;
6160263508Sdim  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
6161263508Sdim    if (getToolChain().getArch() == llvm::Triple::x86 ||
6162263508Sdim        getToolChain().getArch() == llvm::Triple::x86_64)
6163263508Sdim      useLibgcc = false;
6164263508Sdim  }
6165263508Sdim
6166218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6167193326Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
6168263508Sdim    if (D.CCCIsCXX()) {
6169218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6170204643Srdivacky      CmdArgs.push_back("-lm");
6171204643Srdivacky    }
6172193326Sed    if (Args.hasArg(options::OPT_pthread))
6173193326Sed      CmdArgs.push_back("-lpthread");
6174193326Sed    CmdArgs.push_back("-lc");
6175193326Sed
6176263508Sdim    if (useLibgcc) {
6177263508Sdim      if (Args.hasArg(options::OPT_static)) {
6178263508Sdim        // libgcc_eh depends on libc, so resolve as much as possible,
6179263508Sdim        // pull in any new requirements from libc and then get the rest
6180263508Sdim        // of libgcc.
6181263508Sdim        CmdArgs.push_back("-lgcc_eh");
6182263508Sdim        CmdArgs.push_back("-lc");
6183263508Sdim        CmdArgs.push_back("-lgcc");
6184263508Sdim      } else {
6185263508Sdim        CmdArgs.push_back("-lgcc");
6186263508Sdim        CmdArgs.push_back("--as-needed");
6187263508Sdim        CmdArgs.push_back("-lgcc_s");
6188263508Sdim        CmdArgs.push_back("--no-as-needed");
6189263508Sdim      }
6190193326Sed    }
6191193326Sed  }
6192193326Sed
6193193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6194193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
6195193326Sed    if (!Args.hasArg(options::OPT_shared))
6196210299Sed      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
6197210299Sed                                                                  "crtend.o")));
6198193326Sed    else
6199210299Sed      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
6200210299Sed                                                                 "crtendS.o")));
6201210299Sed    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
6202210299Sed                                                                    "crtn.o")));
6203193326Sed  }
6204193326Sed
6205224145Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
6206223017Sdim
6207226633Sdim  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
6208212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6209193326Sed}
6210193326Sed
6211249423Sdimvoid gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6212249423Sdim                                      const InputInfo &Output,
6213249423Sdim                                      const InputInfoList &Inputs,
6214249423Sdim                                      const ArgList &Args,
6215249423Sdim                                      const char *LinkingOutput) const {
6216212904Sdim  ArgStringList CmdArgs;
6217263763Sdim  bool NeedsKPIC = false;
6218212904Sdim
6219212904Sdim  // Add --32/--64 to make sure we get the format we want.
6220212904Sdim  // This is incomplete
6221212904Sdim  if (getToolChain().getArch() == llvm::Triple::x86) {
6222212904Sdim    CmdArgs.push_back("--32");
6223212904Sdim  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
6224212904Sdim    CmdArgs.push_back("--64");
6225234353Sdim  } else if (getToolChain().getArch() == llvm::Triple::ppc) {
6226234353Sdim    CmdArgs.push_back("-a32");
6227234353Sdim    CmdArgs.push_back("-mppc");
6228234353Sdim    CmdArgs.push_back("-many");
6229234353Sdim  } else if (getToolChain().getArch() == llvm::Triple::ppc64) {
6230234353Sdim    CmdArgs.push_back("-a64");
6231234353Sdim    CmdArgs.push_back("-mppc64");
6232234353Sdim    CmdArgs.push_back("-many");
6233263508Sdim  } else if (getToolChain().getArch() == llvm::Triple::ppc64le) {
6234263508Sdim    CmdArgs.push_back("-a64");
6235263508Sdim    CmdArgs.push_back("-mppc64le");
6236263508Sdim    CmdArgs.push_back("-many");
6237263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::sparc) {
6238263763Sdim    CmdArgs.push_back("-32");
6239263763Sdim    CmdArgs.push_back("-Av8plusa");
6240263763Sdim    NeedsKPIC = true;
6241263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
6242263763Sdim    CmdArgs.push_back("-64");
6243263763Sdim    CmdArgs.push_back("-Av9a");
6244263763Sdim    NeedsKPIC = true;
6245212904Sdim  } else if (getToolChain().getArch() == llvm::Triple::arm) {
6246226633Sdim    StringRef MArch = getToolChain().getArchName();
6247212904Sdim    if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
6248212904Sdim      CmdArgs.push_back("-mfpu=neon");
6249263508Sdim    if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a")
6250263508Sdim      CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
6251239462Sdim
6252239462Sdim    StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args,
6253239462Sdim                                           getToolChain().getTriple());
6254239462Sdim    CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
6255239462Sdim
6256239462Sdim    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
6257239462Sdim    Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
6258239462Sdim    Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
6259234353Sdim  } else if (getToolChain().getArch() == llvm::Triple::mips ||
6260234353Sdim             getToolChain().getArch() == llvm::Triple::mipsel ||
6261234353Sdim             getToolChain().getArch() == llvm::Triple::mips64 ||
6262234353Sdim             getToolChain().getArch() == llvm::Triple::mips64el) {
6263234353Sdim    StringRef CPUName;
6264234353Sdim    StringRef ABIName;
6265263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6266234353Sdim
6267234353Sdim    CmdArgs.push_back("-march");
6268234353Sdim    CmdArgs.push_back(CPUName.data());
6269234353Sdim
6270234353Sdim    CmdArgs.push_back("-mabi");
6271249423Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6272234353Sdim
6273234353Sdim    if (getToolChain().getArch() == llvm::Triple::mips ||
6274234353Sdim        getToolChain().getArch() == llvm::Triple::mips64)
6275234353Sdim      CmdArgs.push_back("-EB");
6276234353Sdim    else
6277234353Sdim      CmdArgs.push_back("-EL");
6278239462Sdim
6279263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
6280263508Sdim      if (StringRef(A->getValue()) == "2008")
6281263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
6282263508Sdim    }
6283263508Sdim
6284263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfp64)) {
6285263508Sdim      if (A->getOption().matches(options::OPT_mfp32))
6286263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mfp32"));
6287263508Sdim      else
6288263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mfp64"));
6289263508Sdim    }
6290263508Sdim
6291251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16);
6292251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
6293251662Sdim                    options::OPT_mno_micromips);
6294251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
6295251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
6296251662Sdim
6297263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
6298263508Sdim      // Do not use AddLastArg because not all versions of MIPS assembler
6299263508Sdim      // support -mmsa / -mno-msa options.
6300263508Sdim      if (A->getOption().matches(options::OPT_mmsa))
6301263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mmsa"));
6302263508Sdim    }
6303263508Sdim
6304263763Sdim    NeedsKPIC = true;
6305263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::systemz) {
6306263763Sdim    // Always pass an -march option, since our default of z10 is later
6307263763Sdim    // than the GNU assembler's default.
6308263763Sdim    StringRef CPUName = getSystemZTargetCPU(Args);
6309263763Sdim    CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
6310263763Sdim  }
6311263763Sdim
6312263763Sdim  if (NeedsKPIC) {
6313239462Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
6314239462Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
6315239462Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
6316239462Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
6317239462Sdim    if (LastPICArg &&
6318239462Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
6319239462Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
6320239462Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
6321239462Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
6322239462Sdim      CmdArgs.push_back("-KPIC");
6323239462Sdim    }
6324212904Sdim  }
6325212904Sdim
6326212904Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6327212904Sdim                       options::OPT_Xassembler);
6328212904Sdim
6329212904Sdim  CmdArgs.push_back("-o");
6330212904Sdim  CmdArgs.push_back(Output.getFilename());
6331212904Sdim
6332212904Sdim  for (InputInfoList::const_iterator
6333212904Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6334212904Sdim    const InputInfo &II = *it;
6335212904Sdim    CmdArgs.push_back(II.getFilename());
6336212904Sdim  }
6337212904Sdim
6338212904Sdim  const char *Exec =
6339212904Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
6340212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6341263508Sdim
6342263508Sdim  // Handle the debug info splitting at object creation time if we're
6343263508Sdim  // creating an object.
6344263508Sdim  // TODO: Currently only works on linux with newer objcopy.
6345263508Sdim  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
6346263508Sdim      getToolChain().getTriple().isOSLinux())
6347263508Sdim    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
6348263508Sdim                   SplitDebugName(Args, Inputs));
6349212904Sdim}
6350212904Sdim
6351239462Sdimstatic void AddLibgcc(llvm::Triple Triple, const Driver &D,
6352239462Sdim                      ArgStringList &CmdArgs, const ArgList &Args) {
6353243830Sdim  bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
6354249423Sdim  bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
6355249423Sdim                      Args.hasArg(options::OPT_static);
6356263508Sdim  if (!D.CCCIsCXX())
6357234353Sdim    CmdArgs.push_back("-lgcc");
6358234353Sdim
6359249423Sdim  if (StaticLibgcc || isAndroid) {
6360263508Sdim    if (D.CCCIsCXX())
6361234353Sdim      CmdArgs.push_back("-lgcc");
6362234353Sdim  } else {
6363263508Sdim    if (!D.CCCIsCXX())
6364234353Sdim      CmdArgs.push_back("--as-needed");
6365234353Sdim    CmdArgs.push_back("-lgcc_s");
6366263508Sdim    if (!D.CCCIsCXX())
6367234353Sdim      CmdArgs.push_back("--no-as-needed");
6368234353Sdim  }
6369234353Sdim
6370239462Sdim  if (StaticLibgcc && !isAndroid)
6371234353Sdim    CmdArgs.push_back("-lgcc_eh");
6372263508Sdim  else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
6373234353Sdim    CmdArgs.push_back("-lgcc");
6374249423Sdim
6375249423Sdim  // According to Android ABI, we have to link with libdl if we are
6376249423Sdim  // linking with non-static libgcc.
6377249423Sdim  //
6378249423Sdim  // NOTE: This fixes a link error on Android MIPS as well.  The non-static
6379249423Sdim  // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
6380249423Sdim  if (isAndroid && !StaticLibgcc)
6381249423Sdim    CmdArgs.push_back("-ldl");
6382234353Sdim}
6383234353Sdim
6384243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) {
6385243830Sdim  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
6386243830Sdim  return A && (A->getValue() == StringRef("n32"));
6387243830Sdim}
6388243830Sdim
6389263508Sdimstatic StringRef getLinuxDynamicLinker(const ArgList &Args,
6390263508Sdim                                       const toolchains::Linux &ToolChain) {
6391263508Sdim  if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android)
6392263508Sdim    return "/system/bin/linker";
6393263763Sdim  else if (ToolChain.getArch() == llvm::Triple::x86 ||
6394263763Sdim           ToolChain.getArch() == llvm::Triple::sparc)
6395263508Sdim    return "/lib/ld-linux.so.2";
6396263508Sdim  else if (ToolChain.getArch() == llvm::Triple::aarch64)
6397263508Sdim    return "/lib/ld-linux-aarch64.so.1";
6398263508Sdim  else if (ToolChain.getArch() == llvm::Triple::arm ||
6399263508Sdim           ToolChain.getArch() == llvm::Triple::thumb) {
6400263508Sdim    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
6401263508Sdim      return "/lib/ld-linux-armhf.so.3";
6402263508Sdim    else
6403263508Sdim      return "/lib/ld-linux.so.3";
6404263508Sdim  } else if (ToolChain.getArch() == llvm::Triple::mips ||
6405263508Sdim             ToolChain.getArch() == llvm::Triple::mipsel)
6406263508Sdim    return "/lib/ld.so.1";
6407263508Sdim  else if (ToolChain.getArch() == llvm::Triple::mips64 ||
6408263508Sdim           ToolChain.getArch() == llvm::Triple::mips64el) {
6409263508Sdim    if (hasMipsN32ABIArg(Args))
6410263508Sdim      return "/lib32/ld.so.1";
6411263508Sdim    else
6412263508Sdim      return "/lib64/ld.so.1";
6413263508Sdim  } else if (ToolChain.getArch() == llvm::Triple::ppc)
6414263508Sdim    return "/lib/ld.so.1";
6415263508Sdim  else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
6416263508Sdim           ToolChain.getArch() == llvm::Triple::ppc64le ||
6417263508Sdim           ToolChain.getArch() == llvm::Triple::systemz)
6418263508Sdim    return "/lib64/ld64.so.1";
6419263763Sdim  else if (ToolChain.getArch() == llvm::Triple::sparcv9)
6420263763Sdim    return "/lib64/ld-linux.so.2";
6421263508Sdim  else
6422263508Sdim    return "/lib64/ld-linux-x86-64.so.2";
6423263508Sdim}
6424263508Sdim
6425249423Sdimvoid gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
6426249423Sdim                                  const InputInfo &Output,
6427249423Sdim                                  const InputInfoList &Inputs,
6428249423Sdim                                  const ArgList &Args,
6429249423Sdim                                  const char *LinkingOutput) const {
6430218893Sdim  const toolchains::Linux& ToolChain =
6431218893Sdim    static_cast<const toolchains::Linux&>(getToolChain());
6432218893Sdim  const Driver &D = ToolChain.getDriver();
6433243830Sdim  const bool isAndroid =
6434243830Sdim    ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
6435263508Sdim  const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs();
6436251662Sdim  const bool IsPIE =
6437251662Sdim    !Args.hasArg(options::OPT_shared) &&
6438251662Sdim    (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow());
6439239462Sdim
6440218893Sdim  ArgStringList CmdArgs;
6441212904Sdim
6442218893Sdim  // Silence warning for "clang -g foo.o -o foo"
6443218893Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
6444221345Sdim  // and "clang -emit-llvm foo.o -o foo"
6445221345Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
6446239462Sdim  // and for "clang -w foo.o -o foo". Other warning options are already
6447218893Sdim  // handled somewhere else.
6448218893Sdim  Args.ClaimAllArgs(options::OPT_w);
6449218893Sdim
6450221345Sdim  if (!D.SysRoot.empty())
6451221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6452218893Sdim
6453251662Sdim  if (IsPIE)
6454218893Sdim    CmdArgs.push_back("-pie");
6455218893Sdim
6456218893Sdim  if (Args.hasArg(options::OPT_rdynamic))
6457218893Sdim    CmdArgs.push_back("-export-dynamic");
6458218893Sdim
6459218893Sdim  if (Args.hasArg(options::OPT_s))
6460218893Sdim    CmdArgs.push_back("-s");
6461218893Sdim
6462218893Sdim  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
6463218893Sdim         e = ToolChain.ExtraOpts.end();
6464218893Sdim       i != e; ++i)
6465218893Sdim    CmdArgs.push_back(i->c_str());
6466218893Sdim
6467218893Sdim  if (!Args.hasArg(options::OPT_static)) {
6468218893Sdim    CmdArgs.push_back("--eh-frame-hdr");
6469218893Sdim  }
6470218893Sdim
6471218893Sdim  CmdArgs.push_back("-m");
6472218893Sdim  if (ToolChain.getArch() == llvm::Triple::x86)
6473218893Sdim    CmdArgs.push_back("elf_i386");
6474249423Sdim  else if (ToolChain.getArch() == llvm::Triple::aarch64)
6475249423Sdim    CmdArgs.push_back("aarch64linux");
6476226633Sdim  else if (ToolChain.getArch() == llvm::Triple::arm
6477221345Sdim           ||  ToolChain.getArch() == llvm::Triple::thumb)
6478218893Sdim    CmdArgs.push_back("armelf_linux_eabi");
6479221345Sdim  else if (ToolChain.getArch() == llvm::Triple::ppc)
6480221345Sdim    CmdArgs.push_back("elf32ppclinux");
6481221345Sdim  else if (ToolChain.getArch() == llvm::Triple::ppc64)
6482221345Sdim    CmdArgs.push_back("elf64ppc");
6483263763Sdim  else if (ToolChain.getArch() == llvm::Triple::sparc)
6484263763Sdim    CmdArgs.push_back("elf32_sparc");
6485263763Sdim  else if (ToolChain.getArch() == llvm::Triple::sparcv9)
6486263763Sdim    CmdArgs.push_back("elf64_sparc");
6487234353Sdim  else if (ToolChain.getArch() == llvm::Triple::mips)
6488234353Sdim    CmdArgs.push_back("elf32btsmip");
6489234353Sdim  else if (ToolChain.getArch() == llvm::Triple::mipsel)
6490234353Sdim    CmdArgs.push_back("elf32ltsmip");
6491243830Sdim  else if (ToolChain.getArch() == llvm::Triple::mips64) {
6492243830Sdim    if (hasMipsN32ABIArg(Args))
6493243830Sdim      CmdArgs.push_back("elf32btsmipn32");
6494243830Sdim    else
6495243830Sdim      CmdArgs.push_back("elf64btsmip");
6496243830Sdim  }
6497243830Sdim  else if (ToolChain.getArch() == llvm::Triple::mips64el) {
6498243830Sdim    if (hasMipsN32ABIArg(Args))
6499243830Sdim      CmdArgs.push_back("elf32ltsmipn32");
6500243830Sdim    else
6501243830Sdim      CmdArgs.push_back("elf64ltsmip");
6502243830Sdim  }
6503251662Sdim  else if (ToolChain.getArch() == llvm::Triple::systemz)
6504251662Sdim    CmdArgs.push_back("elf64_s390");
6505218893Sdim  else
6506218893Sdim    CmdArgs.push_back("elf_x86_64");
6507218893Sdim
6508218893Sdim  if (Args.hasArg(options::OPT_static)) {
6509221345Sdim    if (ToolChain.getArch() == llvm::Triple::arm
6510221345Sdim        || ToolChain.getArch() == llvm::Triple::thumb)
6511218893Sdim      CmdArgs.push_back("-Bstatic");
6512218893Sdim    else
6513218893Sdim      CmdArgs.push_back("-static");
6514218893Sdim  } else if (Args.hasArg(options::OPT_shared)) {
6515218893Sdim    CmdArgs.push_back("-shared");
6516243830Sdim    if (isAndroid) {
6517239462Sdim      CmdArgs.push_back("-Bsymbolic");
6518239462Sdim    }
6519218893Sdim  }
6520218893Sdim
6521218893Sdim  if (ToolChain.getArch() == llvm::Triple::arm ||
6522221345Sdim      ToolChain.getArch() == llvm::Triple::thumb ||
6523218893Sdim      (!Args.hasArg(options::OPT_static) &&
6524218893Sdim       !Args.hasArg(options::OPT_shared))) {
6525218893Sdim    CmdArgs.push_back("-dynamic-linker");
6526263508Sdim    CmdArgs.push_back(Args.MakeArgString(
6527263508Sdim        D.DyldPrefix + getLinuxDynamicLinker(Args, ToolChain)));
6528218893Sdim  }
6529218893Sdim
6530218893Sdim  CmdArgs.push_back("-o");
6531218893Sdim  CmdArgs.push_back(Output.getFilename());
6532218893Sdim
6533218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6534218893Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6535239462Sdim    if (!isAndroid) {
6536239462Sdim      const char *crt1 = NULL;
6537239462Sdim      if (!Args.hasArg(options::OPT_shared)){
6538263508Sdim        if (Args.hasArg(options::OPT_pg))
6539263508Sdim          crt1 = "gcrt1.o";
6540263508Sdim        else if (IsPIE)
6541239462Sdim          crt1 = "Scrt1.o";
6542239462Sdim        else
6543239462Sdim          crt1 = "crt1.o";
6544239462Sdim      }
6545239462Sdim      if (crt1)
6546239462Sdim        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
6547239462Sdim
6548239462Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
6549218893Sdim    }
6550218893Sdim
6551218893Sdim    const char *crtbegin;
6552218893Sdim    if (Args.hasArg(options::OPT_static))
6553239462Sdim      crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
6554243830Sdim    else if (Args.hasArg(options::OPT_shared))
6555239462Sdim      crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
6556251662Sdim    else if (IsPIE)
6557243830Sdim      crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
6558218893Sdim    else
6559239462Sdim      crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
6560218893Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
6561243830Sdim
6562243830Sdim    // Add crtfastmath.o if available and fast math is enabled.
6563243830Sdim    ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
6564218893Sdim  }
6565218893Sdim
6566218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
6567218893Sdim
6568218893Sdim  const ToolChain::path_list Paths = ToolChain.getFilePaths();
6569221345Sdim
6570219011Sdim  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
6571219011Sdim       i != e; ++i)
6572226633Sdim    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
6573218893Sdim
6574234353Sdim  // Tell the linker to load the plugin. This has to come before AddLinkerInputs
6575234353Sdim  // as gold requires -plugin to come before any -plugin-opt that -Wl might
6576234353Sdim  // forward.
6577263508Sdim  if (D.IsUsingLTO(Args)) {
6578234353Sdim    CmdArgs.push_back("-plugin");
6579234353Sdim    std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
6580234353Sdim    CmdArgs.push_back(Args.MakeArgString(Plugin));
6581247166Sdim
6582247166Sdim    // Try to pass driver level flags relevant to LTO code generation down to
6583247166Sdim    // the plugin.
6584247166Sdim
6585263508Sdim    // Handle flags for selecting CPU variants.
6586263508Sdim    std::string CPU = getCPUName(Args, ToolChain.getTriple());
6587263508Sdim    if (!CPU.empty()) {
6588247166Sdim      CmdArgs.push_back(
6589263508Sdim                        Args.MakeArgString(Twine("-plugin-opt=mcpu=") +
6590263508Sdim                                           CPU));
6591263508Sdim    }
6592234353Sdim  }
6593234353Sdim
6594247166Sdim
6595239462Sdim  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
6596239462Sdim    CmdArgs.push_back("--no-demangle");
6597239462Sdim
6598218893Sdim  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
6599218893Sdim
6600249423Sdim  // Call these before we add the C++ ABI library.
6601243830Sdim  if (Sanitize.needsUbsanRt())
6602263508Sdim    addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(),
6603249423Sdim                    Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
6604263508Sdim                    Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
6605249423Sdim  if (Sanitize.needsAsanRt())
6606249423Sdim    addAsanRTLinux(getToolChain(), Args, CmdArgs);
6607249423Sdim  if (Sanitize.needsTsanRt())
6608249423Sdim    addTsanRTLinux(getToolChain(), Args, CmdArgs);
6609249423Sdim  if (Sanitize.needsMsanRt())
6610249423Sdim    addMsanRTLinux(getToolChain(), Args, CmdArgs);
6611263508Sdim  if (Sanitize.needsLsanRt())
6612263508Sdim    addLsanRTLinux(getToolChain(), Args, CmdArgs);
6613263508Sdim  if (Sanitize.needsDfsanRt())
6614263508Sdim    addDfsanRTLinux(getToolChain(), Args, CmdArgs);
6615243830Sdim
6616263508Sdim  // The profile runtime also needs access to system libraries.
6617263508Sdim  addProfileRTLinux(getToolChain(), Args, CmdArgs);
6618263508Sdim
6619263508Sdim  if (D.CCCIsCXX() &&
6620239462Sdim      !Args.hasArg(options::OPT_nostdlib) &&
6621239462Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
6622234353Sdim    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
6623234353Sdim      !Args.hasArg(options::OPT_static);
6624234353Sdim    if (OnlyLibstdcxxStatic)
6625234353Sdim      CmdArgs.push_back("-Bstatic");
6626218893Sdim    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
6627234353Sdim    if (OnlyLibstdcxxStatic)
6628234353Sdim      CmdArgs.push_back("-Bdynamic");
6629218893Sdim    CmdArgs.push_back("-lm");
6630218893Sdim  }
6631218893Sdim
6632223017Sdim  if (!Args.hasArg(options::OPT_nostdlib)) {
6633239462Sdim    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
6634239462Sdim      if (Args.hasArg(options::OPT_static))
6635239462Sdim        CmdArgs.push_back("--start-group");
6636218893Sdim
6637249423Sdim      bool OpenMP = Args.hasArg(options::OPT_fopenmp);
6638249423Sdim      if (OpenMP) {
6639249423Sdim        CmdArgs.push_back("-lgomp");
6640249423Sdim
6641249423Sdim        // FIXME: Exclude this for platforms whith libgomp that doesn't require
6642249423Sdim        // librt. Most modern Linux platfroms require it, but some may not.
6643249423Sdim        CmdArgs.push_back("-lrt");
6644249423Sdim      }
6645249423Sdim
6646239462Sdim      AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
6647218893Sdim
6648239462Sdim      if (Args.hasArg(options::OPT_pthread) ||
6649249423Sdim          Args.hasArg(options::OPT_pthreads) || OpenMP)
6650239462Sdim        CmdArgs.push_back("-lpthread");
6651218893Sdim
6652239462Sdim      CmdArgs.push_back("-lc");
6653218893Sdim
6654239462Sdim      if (Args.hasArg(options::OPT_static))
6655239462Sdim        CmdArgs.push_back("--end-group");
6656239462Sdim      else
6657239462Sdim        AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
6658239462Sdim    }
6659218893Sdim
6660218893Sdim    if (!Args.hasArg(options::OPT_nostartfiles)) {
6661218893Sdim      const char *crtend;
6662243830Sdim      if (Args.hasArg(options::OPT_shared))
6663239462Sdim        crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
6664251662Sdim      else if (IsPIE)
6665243830Sdim        crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
6666218893Sdim      else
6667239462Sdim        crtend = isAndroid ? "crtend_android.o" : "crtend.o";
6668218893Sdim
6669218893Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
6670239462Sdim      if (!isAndroid)
6671239462Sdim        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
6672218893Sdim    }
6673218893Sdim  }
6674218893Sdim
6675218893Sdim  C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
6676218893Sdim}
6677218893Sdim
6678210299Sedvoid minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6679212904Sdim                                   const InputInfo &Output,
6680212904Sdim                                   const InputInfoList &Inputs,
6681212904Sdim                                   const ArgList &Args,
6682212904Sdim                                   const char *LinkingOutput) const {
6683210299Sed  ArgStringList CmdArgs;
6684210299Sed
6685210299Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6686210299Sed                       options::OPT_Xassembler);
6687210299Sed
6688210299Sed  CmdArgs.push_back("-o");
6689212904Sdim  CmdArgs.push_back(Output.getFilename());
6690210299Sed
6691210299Sed  for (InputInfoList::const_iterator
6692210299Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6693210299Sed    const InputInfo &II = *it;
6694212904Sdim    CmdArgs.push_back(II.getFilename());
6695210299Sed  }
6696210299Sed
6697210299Sed  const char *Exec =
6698234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
6699212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6700210299Sed}
6701210299Sed
6702210299Sedvoid minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
6703212904Sdim                               const InputInfo &Output,
6704212904Sdim                               const InputInfoList &Inputs,
6705212904Sdim                               const ArgList &Args,
6706212904Sdim                               const char *LinkingOutput) const {
6707210299Sed  const Driver &D = getToolChain().getDriver();
6708210299Sed  ArgStringList CmdArgs;
6709210299Sed
6710212904Sdim  if (Output.isFilename()) {
6711210299Sed    CmdArgs.push_back("-o");
6712210299Sed    CmdArgs.push_back(Output.getFilename());
6713210299Sed  } else {
6714210299Sed    assert(Output.isNothing() && "Invalid output.");
6715210299Sed  }
6716210299Sed
6717210299Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6718234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6719234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
6720234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
6721234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
6722234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
6723234353Sdim  }
6724210299Sed
6725210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
6726210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6727210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
6728210299Sed
6729218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6730210299Sed
6731234353Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
6732234353Sdim
6733210299Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6734210299Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
6735263508Sdim    if (D.CCCIsCXX()) {
6736218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6737210299Sed      CmdArgs.push_back("-lm");
6738210299Sed    }
6739234353Sdim  }
6740210299Sed
6741234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6742234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6743210299Sed    if (Args.hasArg(options::OPT_pthread))
6744210299Sed      CmdArgs.push_back("-lpthread");
6745210299Sed    CmdArgs.push_back("-lc");
6746234353Sdim    CmdArgs.push_back("-lCompilerRT-Generic");
6747234353Sdim    CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
6748234353Sdim    CmdArgs.push_back(
6749249423Sdim         Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
6750210299Sed  }
6751210299Sed
6752234353Sdim  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
6753212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6754210299Sed}
6755210299Sed
6756193326Sed/// DragonFly Tools
6757193326Sed
6758193326Sed// For now, DragonFly Assemble does just about the same as for
6759193326Sed// FreeBSD, but this may change soon.
6760193326Sedvoid dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6761212904Sdim                                       const InputInfo &Output,
6762198893Srdivacky                                       const InputInfoList &Inputs,
6763198893Srdivacky                                       const ArgList &Args,
6764198893Srdivacky                                       const char *LinkingOutput) const {
6765193326Sed  ArgStringList CmdArgs;
6766193326Sed
6767193326Sed  // When building 32-bit code on DragonFly/pc64, we have to explicitly
6768193326Sed  // instruct as in the base system to assemble 32-bit code.
6769243830Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
6770193326Sed    CmdArgs.push_back("--32");
6771193326Sed
6772193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6773193326Sed                       options::OPT_Xassembler);
6774193326Sed
6775193326Sed  CmdArgs.push_back("-o");
6776212904Sdim  CmdArgs.push_back(Output.getFilename());
6777193326Sed
6778193326Sed  for (InputInfoList::const_iterator
6779193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6780193326Sed    const InputInfo &II = *it;
6781212904Sdim    CmdArgs.push_back(II.getFilename());
6782193326Sed  }
6783193326Sed
6784193326Sed  const char *Exec =
6785210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
6786212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6787193326Sed}
6788193326Sed
6789193326Sedvoid dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
6790212904Sdim                                   const InputInfo &Output,
6791212904Sdim                                   const InputInfoList &Inputs,
6792212904Sdim                                   const ArgList &Args,
6793212904Sdim                                   const char *LinkingOutput) const {
6794251662Sdim  bool UseGCC47 = false;
6795201361Srdivacky  const Driver &D = getToolChain().getDriver();
6796193326Sed  ArgStringList CmdArgs;
6797193326Sed
6798251662Sdim  if (llvm::sys::fs::exists("/usr/lib/gcc47", UseGCC47))
6799251662Sdim    UseGCC47 = false;
6800251662Sdim
6801221345Sdim  if (!D.SysRoot.empty())
6802221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6803221345Sdim
6804251662Sdim  CmdArgs.push_back("--eh-frame-hdr");
6805193326Sed  if (Args.hasArg(options::OPT_static)) {
6806193326Sed    CmdArgs.push_back("-Bstatic");
6807193326Sed  } else {
6808251662Sdim    if (Args.hasArg(options::OPT_rdynamic))
6809251662Sdim      CmdArgs.push_back("-export-dynamic");
6810193326Sed    if (Args.hasArg(options::OPT_shared))
6811193326Sed      CmdArgs.push_back("-Bshareable");
6812193326Sed    else {
6813193326Sed      CmdArgs.push_back("-dynamic-linker");
6814193326Sed      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
6815193326Sed    }
6816251662Sdim    CmdArgs.push_back("--hash-style=both");
6817193326Sed  }
6818193326Sed
6819193326Sed  // When building 32-bit code on DragonFly/pc64, we have to explicitly
6820193326Sed  // instruct ld in the base system to link 32-bit code.
6821243830Sdim  if (getToolChain().getArch() == llvm::Triple::x86) {
6822193326Sed    CmdArgs.push_back("-m");
6823193326Sed    CmdArgs.push_back("elf_i386");
6824193326Sed  }
6825193326Sed
6826212904Sdim  if (Output.isFilename()) {
6827193326Sed    CmdArgs.push_back("-o");
6828193326Sed    CmdArgs.push_back(Output.getFilename());
6829193326Sed  } else {
6830193326Sed    assert(Output.isNothing() && "Invalid output.");
6831193326Sed  }
6832193326Sed
6833193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6834193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
6835193326Sed    if (!Args.hasArg(options::OPT_shared)) {
6836251662Sdim      if (Args.hasArg(options::OPT_pg))
6837251662Sdim        CmdArgs.push_back(Args.MakeArgString(
6838251662Sdim                                getToolChain().GetFilePath("gcrt1.o")));
6839251662Sdim      else {
6840251662Sdim        if (Args.hasArg(options::OPT_pie))
6841251662Sdim          CmdArgs.push_back(Args.MakeArgString(
6842251662Sdim                                  getToolChain().GetFilePath("Scrt1.o")));
6843251662Sdim        else
6844251662Sdim          CmdArgs.push_back(Args.MakeArgString(
6845251662Sdim                                  getToolChain().GetFilePath("crt1.o")));
6846251662Sdim      }
6847193326Sed    }
6848251662Sdim    CmdArgs.push_back(Args.MakeArgString(
6849251662Sdim                            getToolChain().GetFilePath("crti.o")));
6850251662Sdim    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
6851251662Sdim      CmdArgs.push_back(Args.MakeArgString(
6852251662Sdim                              getToolChain().GetFilePath("crtbeginS.o")));
6853251662Sdim    else
6854251662Sdim      CmdArgs.push_back(Args.MakeArgString(
6855251662Sdim                              getToolChain().GetFilePath("crtbegin.o")));
6856193326Sed  }
6857193326Sed
6858193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
6859193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6860193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
6861193326Sed
6862218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6863193326Sed
6864193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6865193326Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
6866193326Sed    // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
6867193326Sed    //         rpaths
6868251662Sdim    if (UseGCC47)
6869251662Sdim      CmdArgs.push_back("-L/usr/lib/gcc47");
6870251662Sdim    else
6871251662Sdim      CmdArgs.push_back("-L/usr/lib/gcc44");
6872193326Sed
6873193326Sed    if (!Args.hasArg(options::OPT_static)) {
6874251662Sdim      if (UseGCC47) {
6875251662Sdim        CmdArgs.push_back("-rpath");
6876251662Sdim        CmdArgs.push_back("/usr/lib/gcc47");
6877251662Sdim      } else {
6878251662Sdim        CmdArgs.push_back("-rpath");
6879251662Sdim        CmdArgs.push_back("/usr/lib/gcc44");
6880251662Sdim      }
6881193326Sed    }
6882193326Sed
6883263508Sdim    if (D.CCCIsCXX()) {
6884218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6885212904Sdim      CmdArgs.push_back("-lm");
6886212904Sdim    }
6887212904Sdim
6888193326Sed    if (Args.hasArg(options::OPT_pthread))
6889198893Srdivacky      CmdArgs.push_back("-lpthread");
6890193326Sed
6891193326Sed    if (!Args.hasArg(options::OPT_nolibc)) {
6892193326Sed      CmdArgs.push_back("-lc");
6893193326Sed    }
6894193326Sed
6895251662Sdim    if (UseGCC47) {
6896251662Sdim      if (Args.hasArg(options::OPT_static) ||
6897251662Sdim          Args.hasArg(options::OPT_static_libgcc)) {
6898251662Sdim        CmdArgs.push_back("-lgcc");
6899251662Sdim        CmdArgs.push_back("-lgcc_eh");
6900251662Sdim      } else {
6901251662Sdim        if (Args.hasArg(options::OPT_shared_libgcc)) {
6902251662Sdim          CmdArgs.push_back("-lgcc_pic");
6903251662Sdim          if (!Args.hasArg(options::OPT_shared))
6904251662Sdim            CmdArgs.push_back("-lgcc");
6905251662Sdim        } else {
6906251662Sdim          CmdArgs.push_back("-lgcc");
6907251662Sdim          CmdArgs.push_back("--as-needed");
6908251662Sdim          CmdArgs.push_back("-lgcc_pic");
6909251662Sdim          CmdArgs.push_back("--no-as-needed");
6910251662Sdim        }
6911251662Sdim      }
6912193326Sed    } else {
6913251662Sdim      if (Args.hasArg(options::OPT_shared)) {
6914251662Sdim        CmdArgs.push_back("-lgcc_pic");
6915251662Sdim      } else {
6916251662Sdim        CmdArgs.push_back("-lgcc");
6917251662Sdim      }
6918193326Sed    }
6919193326Sed  }
6920193326Sed
6921193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6922193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
6923251662Sdim    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
6924210299Sed      CmdArgs.push_back(Args.MakeArgString(
6925251662Sdim                              getToolChain().GetFilePath("crtendS.o")));
6926193326Sed    else
6927210299Sed      CmdArgs.push_back(Args.MakeArgString(
6928251662Sdim                              getToolChain().GetFilePath("crtend.o")));
6929210299Sed    CmdArgs.push_back(Args.MakeArgString(
6930251662Sdim                            getToolChain().GetFilePath("crtn.o")));
6931193326Sed  }
6932193326Sed
6933224145Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
6934223017Sdim
6935193326Sed  const char *Exec =
6936210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
6937212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6938193326Sed}
6939212904Sdim
6940212904Sdimvoid visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
6941212904Sdim                                      const InputInfo &Output,
6942212904Sdim                                      const InputInfoList &Inputs,
6943212904Sdim                                      const ArgList &Args,
6944212904Sdim                                      const char *LinkingOutput) const {
6945212904Sdim  ArgStringList CmdArgs;
6946212904Sdim
6947212904Sdim  if (Output.isFilename()) {
6948218893Sdim    CmdArgs.push_back(Args.MakeArgString(std::string("-out:") +
6949218893Sdim                                         Output.getFilename()));
6950212904Sdim  } else {
6951212904Sdim    assert(Output.isNothing() && "Invalid output.");
6952212904Sdim  }
6953212904Sdim
6954212904Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6955263508Sdim      !Args.hasArg(options::OPT_nostartfiles) &&
6956263508Sdim      !C.getDriver().IsCLMode()) {
6957212904Sdim    CmdArgs.push_back("-defaultlib:libcmt");
6958212904Sdim  }
6959212904Sdim
6960212904Sdim  CmdArgs.push_back("-nologo");
6961212904Sdim
6962263508Sdim  bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd);
6963263508Sdim
6964263508Sdim  if (DLL) {
6965263508Sdim    CmdArgs.push_back(Args.MakeArgString("-dll"));
6966263508Sdim
6967263508Sdim    SmallString<128> ImplibName(Output.getFilename());
6968263508Sdim    llvm::sys::path::replace_extension(ImplibName, "lib");
6969263508Sdim    CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") +
6970263508Sdim                                         ImplibName.str()));
6971263508Sdim  }
6972263508Sdim
6973263508Sdim  if (getToolChain().getSanitizerArgs().needsAsanRt()) {
6974263508Sdim    CmdArgs.push_back(Args.MakeArgString("-debug"));
6975263508Sdim    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
6976263508Sdim    SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir);
6977263508Sdim    llvm::sys::path::append(LibSanitizer, "lib", "windows");
6978263508Sdim    if (DLL) {
6979263508Sdim      llvm::sys::path::append(LibSanitizer, "clang_rt.asan_dll_thunk-i386.lib");
6980263508Sdim    } else {
6981263508Sdim      llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386.lib");
6982263508Sdim    }
6983263508Sdim    // FIXME: Handle 64-bit.
6984263508Sdim    CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
6985263508Sdim  }
6986263508Sdim
6987239462Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_l);
6988263508Sdim  Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
6989212904Sdim
6990239462Sdim  // Add filenames immediately.
6991239462Sdim  for (InputInfoList::const_iterator
6992239462Sdim       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6993239462Sdim    if (it->isFilename())
6994239462Sdim      CmdArgs.push_back(it->getFilename());
6995263508Sdim    else
6996263508Sdim      it->getInputArg().renderAsInput(Args, CmdArgs);
6997239462Sdim  }
6998239462Sdim
6999212904Sdim  const char *Exec =
7000218893Sdim    Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
7001212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
7002212904Sdim}
7003263508Sdim
7004263508Sdimvoid visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA,
7005263508Sdim                                         const InputInfo &Output,
7006263508Sdim                                         const InputInfoList &Inputs,
7007263508Sdim                                         const ArgList &Args,
7008263508Sdim                                         const char *LinkingOutput) const {
7009263508Sdim  C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
7010263508Sdim}
7011263508Sdim
7012263508Sdim// Try to find FallbackName on PATH that is not identical to ClangProgramPath.
7013263508Sdim// If one cannot be found, return FallbackName.
7014263508Sdim// We do this special search to prevent clang-cl from falling back onto itself
7015263508Sdim// if it's available as cl.exe on the path.
7016263508Sdimstatic std::string FindFallback(const char *FallbackName,
7017263508Sdim                                const char *ClangProgramPath) {
7018263508Sdim  llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
7019263508Sdim  if (!OptPath.hasValue())
7020263508Sdim    return FallbackName;
7021263508Sdim
7022263508Sdim#ifdef LLVM_ON_WIN32
7023263508Sdim  const StringRef PathSeparators = ";";
7024263508Sdim#else
7025263508Sdim  const StringRef PathSeparators = ":";
7026263508Sdim#endif
7027263508Sdim
7028263508Sdim  SmallVector<StringRef, 8> PathSegments;
7029263508Sdim  llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators);
7030263508Sdim
7031263508Sdim  for (size_t i = 0, e = PathSegments.size(); i != e; ++i) {
7032263508Sdim    const StringRef &PathSegment = PathSegments[i];
7033263508Sdim    if (PathSegment.empty())
7034263508Sdim      continue;
7035263508Sdim
7036263508Sdim    SmallString<128> FilePath(PathSegment);
7037263508Sdim    llvm::sys::path::append(FilePath, FallbackName);
7038263508Sdim    if (llvm::sys::fs::can_execute(Twine(FilePath)) &&
7039263508Sdim        !llvm::sys::fs::equivalent(Twine(FilePath), ClangProgramPath))
7040263508Sdim      return FilePath.str();
7041263508Sdim  }
7042263508Sdim
7043263508Sdim  return FallbackName;
7044263508Sdim}
7045263508Sdim
7046263508SdimCommand *visualstudio::Compile::GetCommand(Compilation &C, const JobAction &JA,
7047263508Sdim                                           const InputInfo &Output,
7048263508Sdim                                           const InputInfoList &Inputs,
7049263508Sdim                                           const ArgList &Args,
7050263508Sdim                                           const char *LinkingOutput) const {
7051263508Sdim  ArgStringList CmdArgs;
7052263508Sdim  CmdArgs.push_back("/nologo");
7053263508Sdim  CmdArgs.push_back("/c"); // Compile only.
7054263508Sdim  CmdArgs.push_back("/W0"); // No warnings.
7055263508Sdim
7056263508Sdim  // The goal is to be able to invoke this tool correctly based on
7057263508Sdim  // any flag accepted by clang-cl.
7058263508Sdim
7059263508Sdim  // These are spelled the same way in clang and cl.exe,.
7060263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
7061263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT_I);
7062263508Sdim
7063263508Sdim  // Optimization level.
7064263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
7065263508Sdim    if (A->getOption().getID() == options::OPT_O0) {
7066263508Sdim      CmdArgs.push_back("/Od");
7067263508Sdim    } else {
7068263508Sdim      StringRef OptLevel = A->getValue();
7069263508Sdim      if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s")
7070263508Sdim        A->render(Args, CmdArgs);
7071263508Sdim      else if (OptLevel == "3")
7072263508Sdim        CmdArgs.push_back("/Ox");
7073263508Sdim    }
7074263508Sdim  }
7075263508Sdim
7076263508Sdim  // Flags for which clang-cl have an alias.
7077263508Sdim  // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
7078263508Sdim
7079263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti))
7080263508Sdim    CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR"
7081263508Sdim                                                                   : "/GR-");
7082263508Sdim  if (Args.hasArg(options::OPT_fsyntax_only))
7083263508Sdim    CmdArgs.push_back("/Zs");
7084263508Sdim
7085263508Sdim  std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include);
7086263508Sdim  for (size_t I = 0, E = Includes.size(); I != E; ++I)
7087263508Sdim    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I]));
7088263508Sdim
7089263508Sdim  // Flags that can simply be passed through.
7090263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
7091263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
7092263508Sdim
7093263508Sdim  // The order of these flags is relevant, so pick the last one.
7094263508Sdim  if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
7095263508Sdim                               options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
7096263508Sdim    A->render(Args, CmdArgs);
7097263508Sdim
7098263508Sdim
7099263508Sdim  // Input filename.
7100263508Sdim  assert(Inputs.size() == 1);
7101263508Sdim  const InputInfo &II = Inputs[0];
7102263508Sdim  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
7103263508Sdim  CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
7104263508Sdim  if (II.isFilename())
7105263508Sdim    CmdArgs.push_back(II.getFilename());
7106263508Sdim  else
7107263508Sdim    II.getInputArg().renderAsInput(Args, CmdArgs);
7108263508Sdim
7109263508Sdim  // Output filename.
7110263508Sdim  assert(Output.getType() == types::TY_Object);
7111263508Sdim  const char *Fo = Args.MakeArgString(std::string("/Fo") +
7112263508Sdim                                      Output.getFilename());
7113263508Sdim  CmdArgs.push_back(Fo);
7114263508Sdim
7115263508Sdim  const Driver &D = getToolChain().getDriver();
7116263508Sdim  std::string Exec = FindFallback("cl.exe", D.getClangProgramPath());
7117263508Sdim
7118263508Sdim  return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs);
7119263508Sdim}
7120263508Sdim
7121263508Sdim
7122263508Sdim/// XCore Tools
7123263508Sdim// We pass assemble and link construction to the xcc tool.
7124263508Sdim
7125263508Sdimvoid XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
7126263508Sdim                                       const InputInfo &Output,
7127263508Sdim                                       const InputInfoList &Inputs,
7128263508Sdim                                       const ArgList &Args,
7129263508Sdim                                       const char *LinkingOutput) const {
7130263508Sdim  ArgStringList CmdArgs;
7131263508Sdim
7132263508Sdim  CmdArgs.push_back("-o");
7133263508Sdim  CmdArgs.push_back(Output.getFilename());
7134263508Sdim
7135263508Sdim  CmdArgs.push_back("-c");
7136263508Sdim
7137263508Sdim  if (Args.hasArg(options::OPT_g_Group)) {
7138263508Sdim    CmdArgs.push_back("-g");
7139263508Sdim  }
7140263508Sdim
7141263508Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
7142263508Sdim                       options::OPT_Xassembler);
7143263508Sdim
7144263508Sdim  for (InputInfoList::const_iterator
7145263508Sdim       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
7146263508Sdim    const InputInfo &II = *it;
7147263508Sdim    CmdArgs.push_back(II.getFilename());
7148263508Sdim  }
7149263508Sdim
7150263508Sdim  const char *Exec =
7151263508Sdim    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
7152263508Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
7153263508Sdim}
7154263508Sdim
7155263508Sdimvoid XCore::Link::ConstructJob(Compilation &C, const JobAction &JA,
7156263508Sdim                                   const InputInfo &Output,
7157263508Sdim                                   const InputInfoList &Inputs,
7158263508Sdim                                   const ArgList &Args,
7159263508Sdim                                   const char *LinkingOutput) const {
7160263508Sdim  ArgStringList CmdArgs;
7161263508Sdim
7162263508Sdim  if (Output.isFilename()) {
7163263508Sdim    CmdArgs.push_back("-o");
7164263508Sdim    CmdArgs.push_back(Output.getFilename());
7165263508Sdim  } else {
7166263508Sdim    assert(Output.isNothing() && "Invalid output.");
7167263508Sdim  }
7168263508Sdim
7169263508Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
7170263508Sdim
7171263508Sdim  const char *Exec =
7172263508Sdim    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
7173263508Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
7174263508Sdim}
7175