Tools.cpp revision 269011
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
502263508Sdim  if (Triple.getOS() == llvm::Triple::NetBSD) {
503263508Sdim    if (MArch == "armv6")
504263508Sdim      return "arm1176jzf-s";
505263508Sdim  }
506263508Sdim
507239462Sdim  // Handle -march=native.
508239462Sdim  std::string NativeMArch;
509239462Sdim  if (MArch == "native") {
510239462Sdim    std::string CPU = llvm::sys::getHostCPUName();
511239462Sdim    if (CPU != "generic") {
512239462Sdim      // Translate the native cpu into the architecture. The switch below will
513239462Sdim      // then chose the minimum cpu for that arch.
514239462Sdim      NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU);
515239462Sdim      MArch = NativeMArch;
516239462Sdim    }
517239462Sdim  }
518239462Sdim
519226633Sdim  return llvm::StringSwitch<const char *>(MArch)
520226633Sdim    .Cases("armv2", "armv2a","arm2")
521226633Sdim    .Case("armv3", "arm6")
522226633Sdim    .Case("armv3m", "arm7m")
523263508Sdim    .Case("armv4", "strongarm")
524263508Sdim    .Case("armv4t", "arm7tdmi")
525226633Sdim    .Cases("armv5", "armv5t", "arm10tdmi")
526239462Sdim    .Cases("armv5e", "armv5te", "arm1022e")
527226633Sdim    .Case("armv5tej", "arm926ej-s")
528226633Sdim    .Cases("armv6", "armv6k", "arm1136jf-s")
529226633Sdim    .Case("armv6j", "arm1136j-s")
530226633Sdim    .Cases("armv6z", "armv6zk", "arm1176jzf-s")
531226633Sdim    .Case("armv6t2", "arm1156t2-s")
532249423Sdim    .Cases("armv6m", "armv6-m", "cortex-m0")
533226633Sdim    .Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
534249423Sdim    .Cases("armv7em", "armv7e-m", "cortex-m4")
535243830Sdim    .Cases("armv7f", "armv7-f", "cortex-a9-mp")
536243830Sdim    .Cases("armv7s", "armv7-s", "swift")
537226633Sdim    .Cases("armv7r", "armv7-r", "cortex-r4")
538226633Sdim    .Cases("armv7m", "armv7-m", "cortex-m3")
539263508Sdim    .Cases("armv8", "armv8a", "armv8-a", "cortex-a53")
540226633Sdim    .Case("ep9312", "ep9312")
541226633Sdim    .Case("iwmmxt", "iwmmxt")
542226633Sdim    .Case("xscale", "xscale")
543263508Sdim    // If all else failed, return the most base CPU with thumb interworking
544263508Sdim    // supported by LLVM.
545226633Sdim    .Default("arm7tdmi");
546198092Srdivacky}
547198092Srdivacky
548263508Sdim/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are targeting.
549263508Sdim//
550263508Sdim// FIXME: tblgen this.
551263508Sdimstatic std::string getAArch64TargetCPU(const ArgList &Args,
552263508Sdim                                       const llvm::Triple &Triple) {
553263508Sdim  // FIXME: Warn on inconsistent use of -mcpu and -march.
554263508Sdim
555263508Sdim  // If we have -mcpu=, use that.
556263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
557263508Sdim    StringRef MCPU = A->getValue();
558263508Sdim    // Handle -mcpu=native.
559263508Sdim    if (MCPU == "native")
560263508Sdim      return llvm::sys::getHostCPUName();
561263508Sdim    else
562263508Sdim      return MCPU;
563263508Sdim  }
564263508Sdim
565263508Sdim  return "generic";
566263508Sdim}
567263508Sdim
568199482Srdivacky// FIXME: Move to target hook.
569199482Srdivackystatic bool isSignedCharDefault(const llvm::Triple &Triple) {
570199482Srdivacky  switch (Triple.getArch()) {
571199482Srdivacky  default:
572199482Srdivacky    return true;
573199482Srdivacky
574249423Sdim  case llvm::Triple::aarch64:
575223017Sdim  case llvm::Triple::arm:
576199482Srdivacky  case llvm::Triple::ppc:
577199482Srdivacky  case llvm::Triple::ppc64:
578226633Sdim    if (Triple.isOSDarwin())
579199482Srdivacky      return true;
580199482Srdivacky    return false;
581251662Sdim
582263508Sdim  case llvm::Triple::ppc64le:
583251662Sdim  case llvm::Triple::systemz:
584263508Sdim  case llvm::Triple::xcore:
585251662Sdim    return false;
586199482Srdivacky  }
587199482Srdivacky}
588199482Srdivacky
589263508Sdimstatic bool isNoCommonDefault(const llvm::Triple &Triple) {
590263508Sdim  switch (Triple.getArch()) {
591263508Sdim  default:
592263508Sdim    return false;
593263508Sdim
594263508Sdim  case llvm::Triple::xcore:
595263508Sdim    return true;
596263508Sdim  }
597263508Sdim}
598263508Sdim
599234353Sdim// Handle -mfpu=.
600234353Sdim//
601234353Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the
602234353Sdim// frontend target.
603263508Sdimstatic void getAArch64FPUFeatures(const Driver &D, const Arg *A,
604263508Sdim                                  const ArgList &Args,
605263508Sdim                                  std::vector<const char *> &Features) {
606243830Sdim  StringRef FPU = A->getValue();
607263508Sdim  if (FPU == "fp-armv8") {
608263508Sdim    Features.push_back("+fp-armv8");
609263508Sdim  } else if (FPU == "neon-fp-armv8") {
610263508Sdim    Features.push_back("+fp-armv8");
611263508Sdim    Features.push_back("+neon");
612263508Sdim  } else if (FPU == "crypto-neon-fp-armv8") {
613263508Sdim    Features.push_back("+fp-armv8");
614263508Sdim    Features.push_back("+neon");
615263508Sdim    Features.push_back("+crypto");
616263508Sdim  } else if (FPU == "neon") {
617263508Sdim    Features.push_back("+neon");
618263508Sdim  } else if (FPU == "none") {
619263508Sdim    Features.push_back("-fp-armv8");
620263508Sdim    Features.push_back("-crypto");
621263508Sdim    Features.push_back("-neon");
622263508Sdim  } else
623263508Sdim    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
624263508Sdim}
625198092Srdivacky
626263508Sdim// Handle -mhwdiv=.
627263508Sdimstatic void getARMHWDivFeatures(const Driver &D, const Arg *A,
628263508Sdim                              const ArgList &Args,
629263508Sdim                              std::vector<const char *> &Features) {
630263508Sdim  StringRef HWDiv = A->getValue();
631263508Sdim  if (HWDiv == "arm") {
632263508Sdim    Features.push_back("+hwdiv-arm");
633263508Sdim    Features.push_back("-hwdiv");
634263508Sdim  } else if (HWDiv == "thumb") {
635263508Sdim    Features.push_back("-hwdiv-arm");
636263508Sdim    Features.push_back("+hwdiv");
637263508Sdim  } else if (HWDiv == "arm,thumb" || HWDiv == "thumb,arm") {
638263508Sdim    Features.push_back("+hwdiv-arm");
639263508Sdim    Features.push_back("+hwdiv");
640263508Sdim  } else if (HWDiv == "none") {
641263508Sdim    Features.push_back("-hwdiv-arm");
642263508Sdim    Features.push_back("-hwdiv");
643263508Sdim  } else
644263508Sdim    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
645263508Sdim}
646263508Sdim
647263508Sdim// Handle -mfpu=.
648263508Sdim//
649263508Sdim// FIXME: Centralize feature selection, defaulting shouldn't be also in the
650263508Sdim// frontend target.
651263508Sdimstatic void getARMFPUFeatures(const Driver &D, const Arg *A,
652263508Sdim                              const ArgList &Args,
653263508Sdim                              std::vector<const char *> &Features) {
654263508Sdim  StringRef FPU = A->getValue();
655263508Sdim
656234353Sdim  // Set the target features based on the FPU.
657234353Sdim  if (FPU == "fpa" || FPU == "fpe2" || FPU == "fpe3" || FPU == "maverick") {
658234353Sdim    // Disable any default FPU support.
659263508Sdim    Features.push_back("-vfp2");
660263508Sdim    Features.push_back("-vfp3");
661263508Sdim    Features.push_back("-neon");
662234353Sdim  } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") {
663263508Sdim    Features.push_back("+vfp3");
664263508Sdim    Features.push_back("+d16");
665263508Sdim    Features.push_back("-neon");
666234353Sdim  } else if (FPU == "vfp") {
667263508Sdim    Features.push_back("+vfp2");
668263508Sdim    Features.push_back("-neon");
669234353Sdim  } else if (FPU == "vfp3" || FPU == "vfpv3") {
670263508Sdim    Features.push_back("+vfp3");
671263508Sdim    Features.push_back("-neon");
672263508Sdim  } else if (FPU == "fp-armv8") {
673263508Sdim    Features.push_back("+fp-armv8");
674263508Sdim    Features.push_back("-neon");
675263508Sdim    Features.push_back("-crypto");
676263508Sdim  } else if (FPU == "neon-fp-armv8") {
677263508Sdim    Features.push_back("+fp-armv8");
678263508Sdim    Features.push_back("+neon");
679263508Sdim    Features.push_back("-crypto");
680263508Sdim  } else if (FPU == "crypto-neon-fp-armv8") {
681263508Sdim    Features.push_back("+fp-armv8");
682263508Sdim    Features.push_back("+neon");
683263508Sdim    Features.push_back("+crypto");
684234353Sdim  } else if (FPU == "neon") {
685263508Sdim    Features.push_back("+neon");
686263508Sdim  } else if (FPU == "none") {
687263508Sdim    Features.push_back("-vfp2");
688263508Sdim    Features.push_back("-vfp3");
689263508Sdim    Features.push_back("-vfp4");
690263508Sdim    Features.push_back("-fp-armv8");
691263508Sdim    Features.push_back("-crypto");
692263508Sdim    Features.push_back("-neon");
693234353Sdim  } else
694234353Sdim    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
695234353Sdim}
696198092Srdivacky
697234353Sdim// Select the float ABI as determined by -msoft-float, -mhard-float, and
698234353Sdim// -mfloat-abi=.
699234353Sdimstatic StringRef getARMFloatABI(const Driver &D,
700234353Sdim                                const ArgList &Args,
701234353Sdim                                const llvm::Triple &Triple) {
702226633Sdim  StringRef FloatABI;
703198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
704198092Srdivacky                               options::OPT_mhard_float,
705198092Srdivacky                               options::OPT_mfloat_abi_EQ)) {
706198092Srdivacky    if (A->getOption().matches(options::OPT_msoft_float))
707198092Srdivacky      FloatABI = "soft";
708198092Srdivacky    else if (A->getOption().matches(options::OPT_mhard_float))
709198092Srdivacky      FloatABI = "hard";
710198092Srdivacky    else {
711243830Sdim      FloatABI = A->getValue();
712198092Srdivacky      if (FloatABI != "soft" && FloatABI != "softfp" && FloatABI != "hard") {
713226633Sdim        D.Diag(diag::err_drv_invalid_mfloat_abi)
714198092Srdivacky          << A->getAsString(Args);
715198092Srdivacky        FloatABI = "soft";
716198092Srdivacky      }
717198092Srdivacky    }
718198092Srdivacky  }
719198092Srdivacky
720198092Srdivacky  // If unspecified, choose the default based on the platform.
721198092Srdivacky  if (FloatABI.empty()) {
722210299Sed    switch (Triple.getOS()) {
723226633Sdim    case llvm::Triple::Darwin:
724226633Sdim    case llvm::Triple::MacOSX:
725226633Sdim    case llvm::Triple::IOS: {
726198092Srdivacky      // Darwin defaults to "softfp" for v6 and v7.
727198092Srdivacky      //
728198092Srdivacky      // FIXME: Factor out an ARM class so we can cache the arch somewhere.
729239462Sdim      std::string ArchName =
730210299Sed        getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
731239462Sdim      if (StringRef(ArchName).startswith("v6") ||
732239462Sdim          StringRef(ArchName).startswith("v7"))
733198092Srdivacky        FloatABI = "softfp";
734198092Srdivacky      else
735198092Srdivacky        FloatABI = "soft";
736198092Srdivacky      break;
737198092Srdivacky    }
738198092Srdivacky
739244640Sandrew    case llvm::Triple::FreeBSD:
740244640Sandrew      // FreeBSD defaults to soft float
741244640Sandrew      FloatABI = "soft";
742244640Sandrew      break;
743244640Sandrew
744198092Srdivacky    default:
745218893Sdim      switch(Triple.getEnvironment()) {
746239462Sdim      case llvm::Triple::GNUEABIHF:
747239462Sdim        FloatABI = "hard";
748239462Sdim        break;
749218893Sdim      case llvm::Triple::GNUEABI:
750218893Sdim        FloatABI = "softfp";
751218893Sdim        break;
752218893Sdim      case llvm::Triple::EABI:
753218893Sdim        // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
754218893Sdim        FloatABI = "softfp";
755218893Sdim        break;
756243830Sdim      case llvm::Triple::Android: {
757239462Sdim        std::string ArchName =
758234353Sdim          getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
759239462Sdim        if (StringRef(ArchName).startswith("v7"))
760234353Sdim          FloatABI = "softfp";
761234353Sdim        else
762234353Sdim          FloatABI = "soft";
763234353Sdim        break;
764234353Sdim      }
765218893Sdim      default:
766218893Sdim        // Assume "soft", but warn the user we are guessing.
767218893Sdim        FloatABI = "soft";
768226633Sdim        D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
769218893Sdim        break;
770218893Sdim      }
771198092Srdivacky    }
772198092Srdivacky  }
773198092Srdivacky
774234353Sdim  return FloatABI;
775234353Sdim}
776234353Sdim
777263508Sdimstatic void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
778263508Sdim                                 const ArgList &Args,
779263508Sdim                                 std::vector<const char *> &Features) {
780263508Sdim  StringRef FloatABI = getARMFloatABI(D, Args, Triple);
781263508Sdim  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
782263508Sdim  // yet (it uses the -mfloat-abi and -msoft-float options), and it is
783263508Sdim  // stripped out by the ARM target.
784263508Sdim  // Use software floating point operations?
785263508Sdim  if (FloatABI == "soft")
786263508Sdim    Features.push_back("+soft-float");
787234353Sdim
788263508Sdim  // Use software floating point argument passing?
789263508Sdim  if (FloatABI != "hard")
790263508Sdim    Features.push_back("+soft-float-abi");
791263508Sdim
792263508Sdim  // Honor -mfpu=.
793263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
794263508Sdim    getARMFPUFeatures(D, A, Args, Features);
795263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
796263508Sdim    getARMHWDivFeatures(D, A, Args, Features);
797263508Sdim
798263508Sdim  // Setting -msoft-float effectively disables NEON because of the GCC
799263508Sdim  // implementation, although the same isn't true of VFP or VFP3.
800263508Sdim  if (FloatABI == "soft")
801263508Sdim    Features.push_back("-neon");
802263508Sdim
803263508Sdim  // En/disable crc
804263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcrc,
805263508Sdim                               options::OPT_mnocrc)) {
806263508Sdim    if (A->getOption().matches(options::OPT_mcrc))
807263508Sdim      Features.push_back("+crc");
808263508Sdim    else
809263508Sdim      Features.push_back("-crc");
810263508Sdim  }
811263508Sdim}
812263508Sdim
813234353Sdimvoid Clang::AddARMTargetArgs(const ArgList &Args,
814234353Sdim                             ArgStringList &CmdArgs,
815234353Sdim                             bool KernelOrKext) const {
816234353Sdim  const Driver &D = getToolChain().getDriver();
817243830Sdim  // Get the effective triple, which takes into account the deployment target.
818243830Sdim  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
819243830Sdim  llvm::Triple Triple(TripleStr);
820243830Sdim  std::string CPUName = getARMTargetCPU(Args, Triple);
821234353Sdim
822234353Sdim  // Select the ABI to use.
823234353Sdim  //
824234353Sdim  // FIXME: Support -meabi.
825234353Sdim  const char *ABIName = 0;
826234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
827243830Sdim    ABIName = A->getValue();
828243830Sdim  } else if (Triple.isOSDarwin()) {
829243830Sdim    // The backend is hardwired to assume AAPCS for M-class processors, ensure
830243830Sdim    // the frontend matches that.
831263508Sdim    if (Triple.getEnvironment() == llvm::Triple::EABI ||
832263508Sdim        StringRef(CPUName).startswith("cortex-m")) {
833243830Sdim      ABIName = "aapcs";
834243830Sdim    } else {
835243830Sdim      ABIName = "apcs-gnu";
836243830Sdim    }
837234353Sdim  } else {
838234353Sdim    // Select the default based on the platform.
839234353Sdim    switch(Triple.getEnvironment()) {
840243830Sdim    case llvm::Triple::Android:
841234353Sdim    case llvm::Triple::GNUEABI:
842239462Sdim    case llvm::Triple::GNUEABIHF:
843234353Sdim      ABIName = "aapcs-linux";
844234353Sdim      break;
845234353Sdim    case llvm::Triple::EABI:
846234353Sdim      ABIName = "aapcs";
847234353Sdim      break;
848234353Sdim    default:
849234353Sdim      ABIName = "apcs-gnu";
850234353Sdim    }
851234353Sdim  }
852234353Sdim  CmdArgs.push_back("-target-abi");
853234353Sdim  CmdArgs.push_back(ABIName);
854234353Sdim
855234353Sdim  // Determine floating point ABI from the options & target defaults.
856234353Sdim  StringRef FloatABI = getARMFloatABI(D, Args, Triple);
857198092Srdivacky  if (FloatABI == "soft") {
858198092Srdivacky    // Floating point operations and argument passing are soft.
859198092Srdivacky    //
860198092Srdivacky    // FIXME: This changes CPP defines, we need -target-soft-float.
861199990Srdivacky    CmdArgs.push_back("-msoft-float");
862200583Srdivacky    CmdArgs.push_back("-mfloat-abi");
863200583Srdivacky    CmdArgs.push_back("soft");
864198092Srdivacky  } else if (FloatABI == "softfp") {
865198092Srdivacky    // Floating point operations are hard, but argument passing is soft.
866200583Srdivacky    CmdArgs.push_back("-mfloat-abi");
867200583Srdivacky    CmdArgs.push_back("soft");
868198092Srdivacky  } else {
869198092Srdivacky    // Floating point operations and argument passing are hard.
870198092Srdivacky    assert(FloatABI == "hard" && "Invalid float abi!");
871200583Srdivacky    CmdArgs.push_back("-mfloat-abi");
872200583Srdivacky    CmdArgs.push_back("hard");
873198092Srdivacky  }
874201361Srdivacky
875221345Sdim  // Kernel code has more strict alignment requirements.
876221345Sdim  if (KernelOrKext) {
877263508Sdim    if (!Triple.isiOS() || Triple.isOSVersionLT(6)) {
878243830Sdim      CmdArgs.push_back("-backend-option");
879243830Sdim      CmdArgs.push_back("-arm-long-calls");
880243830Sdim    }
881221345Sdim
882221345Sdim    CmdArgs.push_back("-backend-option");
883221345Sdim    CmdArgs.push_back("-arm-strict-align");
884221345Sdim
885221345Sdim    // The kext linker doesn't know how to deal with movw/movt.
886221345Sdim    CmdArgs.push_back("-backend-option");
887263508Sdim    CmdArgs.push_back("-arm-use-movt=0");
888221345Sdim  }
889226633Sdim
890226633Sdim  // Setting -mno-global-merge disables the codegen global merge pass. Setting
891226633Sdim  // -mglobal-merge has no effect as the pass is enabled by default.
892226633Sdim  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
893226633Sdim                               options::OPT_mno_global_merge)) {
894226633Sdim    if (A->getOption().matches(options::OPT_mno_global_merge))
895226633Sdim      CmdArgs.push_back("-mno-global-merge");
896226633Sdim  }
897239462Sdim
898251662Sdim  if (!Args.hasFlag(options::OPT_mimplicit_float,
899251662Sdim                    options::OPT_mno_implicit_float,
900251662Sdim                    true))
901239462Sdim    CmdArgs.push_back("-no-implicit-float");
902198092Srdivacky
903263508Sdim    // llvm does not support reserving registers in general. There is support
904263508Sdim    // for reserving r9 on ARM though (defined as a platform-specific register
905263508Sdim    // in ARM EABI).
906263508Sdim    if (Args.hasArg(options::OPT_ffixed_r9)) {
907263508Sdim      CmdArgs.push_back("-backend-option");
908263508Sdim      CmdArgs.push_back("-arm-reserve-r9");
909263508Sdim    }
910226633Sdim}
911226633Sdim
912234353Sdim// Get CPU and ABI names. They are not independent
913234353Sdim// so we have to calculate them together.
914234353Sdimstatic void getMipsCPUAndABI(const ArgList &Args,
915263508Sdim                             const llvm::Triple &Triple,
916234353Sdim                             StringRef &CPUName,
917234353Sdim                             StringRef &ABIName) {
918243830Sdim  const char *DefMips32CPU = "mips32";
919243830Sdim  const char *DefMips64CPU = "mips64";
920226633Sdim
921243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
922263508Sdim                               options::OPT_mcpu_EQ))
923263508Sdim    CPUName = A->getValue();
924243830Sdim
925251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
926243830Sdim    ABIName = A->getValue();
927251662Sdim    // Convert a GNU style Mips ABI name to the name
928251662Sdim    // accepted by LLVM Mips backend.
929251662Sdim    ABIName = llvm::StringSwitch<llvm::StringRef>(ABIName)
930251662Sdim      .Case("32", "o32")
931251662Sdim      .Case("64", "n64")
932251662Sdim      .Default(ABIName);
933251662Sdim  }
934243830Sdim
935243830Sdim  // Setup default CPU and ABI names.
936243830Sdim  if (CPUName.empty() && ABIName.empty()) {
937263508Sdim    switch (Triple.getArch()) {
938243830Sdim    default:
939243830Sdim      llvm_unreachable("Unexpected triple arch name");
940243830Sdim    case llvm::Triple::mips:
941243830Sdim    case llvm::Triple::mipsel:
942243830Sdim      CPUName = DefMips32CPU;
943243830Sdim      break;
944243830Sdim    case llvm::Triple::mips64:
945243830Sdim    case llvm::Triple::mips64el:
946243830Sdim      CPUName = DefMips64CPU;
947243830Sdim      break;
948243830Sdim    }
949243830Sdim  }
950243830Sdim
951243830Sdim  if (!ABIName.empty()) {
952243830Sdim    // Deduce CPU name from ABI name.
953243830Sdim    CPUName = llvm::StringSwitch<const char *>(ABIName)
954249423Sdim      .Cases("32", "o32", "eabi", DefMips32CPU)
955249423Sdim      .Cases("n32", "n64", "64", DefMips64CPU)
956243830Sdim      .Default("");
957243830Sdim  }
958243830Sdim  else if (!CPUName.empty()) {
959243830Sdim    // Deduce ABI name from CPU name.
960243830Sdim    ABIName = llvm::StringSwitch<const char *>(CPUName)
961243830Sdim      .Cases("mips32", "mips32r2", "o32")
962243830Sdim      .Cases("mips64", "mips64r2", "n64")
963243830Sdim      .Default("");
964243830Sdim  }
965243830Sdim
966243830Sdim  // FIXME: Warn on inconsistent cpu and abi usage.
967234353Sdim}
968204643Srdivacky
969249423Sdim// Convert ABI name to the GNU tools acceptable variant.
970249423Sdimstatic StringRef getGnuCompatibleMipsABIName(StringRef ABI) {
971249423Sdim  return llvm::StringSwitch<llvm::StringRef>(ABI)
972249423Sdim    .Case("o32", "32")
973249423Sdim    .Case("n64", "64")
974249423Sdim    .Default(ABI);
975249423Sdim}
976249423Sdim
977239462Sdim// Select the MIPS float ABI as determined by -msoft-float, -mhard-float,
978239462Sdim// and -mfloat-abi=.
979239462Sdimstatic StringRef getMipsFloatABI(const Driver &D, const ArgList &Args) {
980226633Sdim  StringRef FloatABI;
981204643Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
982234353Sdim                               options::OPT_mhard_float,
983234353Sdim                               options::OPT_mfloat_abi_EQ)) {
984204643Srdivacky    if (A->getOption().matches(options::OPT_msoft_float))
985204643Srdivacky      FloatABI = "soft";
986204643Srdivacky    else if (A->getOption().matches(options::OPT_mhard_float))
987204643Srdivacky      FloatABI = "hard";
988234353Sdim    else {
989243830Sdim      FloatABI = A->getValue();
990251662Sdim      if (FloatABI != "soft" && FloatABI != "hard") {
991239462Sdim        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
992234353Sdim        FloatABI = "hard";
993234353Sdim      }
994234353Sdim    }
995204643Srdivacky  }
996204643Srdivacky
997204643Srdivacky  // If unspecified, choose the default based on the platform.
998204643Srdivacky  if (FloatABI.empty()) {
999234353Sdim    // Assume "hard", because it's a default value used by gcc.
1000234353Sdim    // When we start to recognize specific target MIPS processors,
1001234353Sdim    // we will be able to select the default more correctly.
1002234353Sdim    FloatABI = "hard";
1003204643Srdivacky  }
1004204643Srdivacky
1005239462Sdim  return FloatABI;
1006239462Sdim}
1007239462Sdim
1008239462Sdimstatic void AddTargetFeature(const ArgList &Args,
1009263508Sdim                             std::vector<const char *> &Features,
1010263508Sdim                             OptSpecifier OnOpt, OptSpecifier OffOpt,
1011239462Sdim                             StringRef FeatureName) {
1012239462Sdim  if (Arg *A = Args.getLastArg(OnOpt, OffOpt)) {
1013239462Sdim    if (A->getOption().matches(OnOpt))
1014263508Sdim      Features.push_back(Args.MakeArgString("+" + FeatureName));
1015239462Sdim    else
1016263508Sdim      Features.push_back(Args.MakeArgString("-" + FeatureName));
1017239462Sdim  }
1018239462Sdim}
1019239462Sdim
1020263508Sdimstatic void getMIPSTargetFeatures(const Driver &D, const ArgList &Args,
1021263508Sdim                                  std::vector<const char *> &Features) {
1022263508Sdim  StringRef FloatABI = getMipsFloatABI(D, Args);
1023263508Sdim  bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
1024263508Sdim  if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
1025263508Sdim    // FIXME: Note, this is a hack. We need to pass the selected float
1026263508Sdim    // mode to the MipsTargetInfoBase to define appropriate macros there.
1027263508Sdim    // Now it is the only method.
1028263508Sdim    Features.push_back("+soft-float");
1029263508Sdim  }
1030263508Sdim
1031263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
1032263508Sdim    if (StringRef(A->getValue()) == "2008")
1033263508Sdim      Features.push_back("+nan2008");
1034263508Sdim  }
1035263508Sdim
1036263508Sdim  AddTargetFeature(Args, Features, options::OPT_msingle_float,
1037263508Sdim                   options::OPT_mdouble_float, "single-float");
1038263508Sdim  AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16,
1039263508Sdim                   "mips16");
1040263508Sdim  AddTargetFeature(Args, Features, options::OPT_mmicromips,
1041263508Sdim                   options::OPT_mno_micromips, "micromips");
1042263508Sdim  AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp,
1043263508Sdim                   "dsp");
1044263508Sdim  AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2,
1045263508Sdim                   "dspr2");
1046263508Sdim  AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
1047263508Sdim                   "msa");
1048263508Sdim  AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
1049263508Sdim                   "fp64");
1050263508Sdim}
1051263508Sdim
1052239462Sdimvoid Clang::AddMIPSTargetArgs(const ArgList &Args,
1053251662Sdim                              ArgStringList &CmdArgs) const {
1054239462Sdim  const Driver &D = getToolChain().getDriver();
1055239462Sdim  StringRef CPUName;
1056239462Sdim  StringRef ABIName;
1057263508Sdim  const llvm::Triple &Triple = getToolChain().getTriple();
1058263508Sdim  getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
1059239462Sdim
1060239462Sdim  CmdArgs.push_back("-target-abi");
1061239462Sdim  CmdArgs.push_back(ABIName.data());
1062239462Sdim
1063239462Sdim  StringRef FloatABI = getMipsFloatABI(D, Args);
1064239462Sdim
1065249423Sdim  bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
1066249423Sdim
1067249423Sdim  if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
1068204643Srdivacky    // Floating point operations and argument passing are soft.
1069204643Srdivacky    CmdArgs.push_back("-msoft-float");
1070234353Sdim    CmdArgs.push_back("-mfloat-abi");
1071234353Sdim    CmdArgs.push_back("soft");
1072234353Sdim
1073249423Sdim    if (FloatABI == "hard" && IsMips16) {
1074249423Sdim      CmdArgs.push_back("-mllvm");
1075249423Sdim      CmdArgs.push_back("-mips16-hard-float");
1076249423Sdim    }
1077234353Sdim  }
1078234353Sdim  else {
1079234353Sdim    // Floating point operations and argument passing are hard.
1080204643Srdivacky    assert(FloatABI == "hard" && "Invalid float abi!");
1081234353Sdim    CmdArgs.push_back("-mfloat-abi");
1082234353Sdim    CmdArgs.push_back("hard");
1083204643Srdivacky  }
1084239462Sdim
1085249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_mxgot, options::OPT_mno_xgot)) {
1086249423Sdim    if (A->getOption().matches(options::OPT_mxgot)) {
1087249423Sdim      CmdArgs.push_back("-mllvm");
1088249423Sdim      CmdArgs.push_back("-mxgot");
1089249423Sdim    }
1090249423Sdim  }
1091249423Sdim
1092263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mldc1_sdc1,
1093263508Sdim                               options::OPT_mno_ldc1_sdc1)) {
1094263508Sdim    if (A->getOption().matches(options::OPT_mno_ldc1_sdc1)) {
1095263508Sdim      CmdArgs.push_back("-mllvm");
1096263508Sdim      CmdArgs.push_back("-mno-ldc1-sdc1");
1097263508Sdim    }
1098263508Sdim  }
1099263508Sdim
1100263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcheck_zero_division,
1101263508Sdim                               options::OPT_mno_check_zero_division)) {
1102263508Sdim    if (A->getOption().matches(options::OPT_mno_check_zero_division)) {
1103263508Sdim      CmdArgs.push_back("-mllvm");
1104263508Sdim      CmdArgs.push_back("-mno-check-zero-division");
1105263508Sdim    }
1106263508Sdim  }
1107263508Sdim
1108243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_G)) {
1109243830Sdim    StringRef v = A->getValue();
1110243830Sdim    CmdArgs.push_back("-mllvm");
1111243830Sdim    CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v));
1112243830Sdim    A->claim();
1113243830Sdim  }
1114204643Srdivacky}
1115204643Srdivacky
1116239462Sdim/// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting.
1117239462Sdimstatic std::string getPPCTargetCPU(const ArgList &Args) {
1118239462Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1119243830Sdim    StringRef CPUName = A->getValue();
1120239462Sdim
1121239462Sdim    if (CPUName == "native") {
1122239462Sdim      std::string CPU = llvm::sys::getHostCPUName();
1123239462Sdim      if (!CPU.empty() && CPU != "generic")
1124239462Sdim        return CPU;
1125239462Sdim      else
1126239462Sdim        return "";
1127239462Sdim    }
1128239462Sdim
1129239462Sdim    return llvm::StringSwitch<const char *>(CPUName)
1130239462Sdim      .Case("common", "generic")
1131239462Sdim      .Case("440", "440")
1132239462Sdim      .Case("440fp", "440")
1133239462Sdim      .Case("450", "450")
1134239462Sdim      .Case("601", "601")
1135239462Sdim      .Case("602", "602")
1136239462Sdim      .Case("603", "603")
1137239462Sdim      .Case("603e", "603e")
1138239462Sdim      .Case("603ev", "603ev")
1139239462Sdim      .Case("604", "604")
1140239462Sdim      .Case("604e", "604e")
1141239462Sdim      .Case("620", "620")
1142249423Sdim      .Case("630", "pwr3")
1143239462Sdim      .Case("G3", "g3")
1144239462Sdim      .Case("7400", "7400")
1145239462Sdim      .Case("G4", "g4")
1146239462Sdim      .Case("7450", "7450")
1147239462Sdim      .Case("G4+", "g4+")
1148239462Sdim      .Case("750", "750")
1149239462Sdim      .Case("970", "970")
1150239462Sdim      .Case("G5", "g5")
1151239462Sdim      .Case("a2", "a2")
1152249423Sdim      .Case("a2q", "a2q")
1153243830Sdim      .Case("e500mc", "e500mc")
1154243830Sdim      .Case("e5500", "e5500")
1155249423Sdim      .Case("power3", "pwr3")
1156249423Sdim      .Case("power4", "pwr4")
1157249423Sdim      .Case("power5", "pwr5")
1158249423Sdim      .Case("power5x", "pwr5x")
1159239462Sdim      .Case("power6", "pwr6")
1160249423Sdim      .Case("power6x", "pwr6x")
1161239462Sdim      .Case("power7", "pwr7")
1162249423Sdim      .Case("pwr3", "pwr3")
1163249423Sdim      .Case("pwr4", "pwr4")
1164249423Sdim      .Case("pwr5", "pwr5")
1165249423Sdim      .Case("pwr5x", "pwr5x")
1166249423Sdim      .Case("pwr6", "pwr6")
1167249423Sdim      .Case("pwr6x", "pwr6x")
1168249423Sdim      .Case("pwr7", "pwr7")
1169239462Sdim      .Case("powerpc", "ppc")
1170239462Sdim      .Case("powerpc64", "ppc64")
1171263508Sdim      .Case("powerpc64le", "ppc64le")
1172239462Sdim      .Default("");
1173239462Sdim  }
1174239462Sdim
1175239462Sdim  return "";
1176239462Sdim}
1177239462Sdim
1178263508Sdimstatic void getPPCTargetFeatures(const ArgList &Args,
1179263508Sdim                                 std::vector<const char *> &Features) {
1180263508Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT_m_ppc_Features_Group),
1181263508Sdim                    ie = Args.filtered_end();
1182263508Sdim       it != ie; ++it) {
1183263508Sdim    StringRef Name = (*it)->getOption().getName();
1184263508Sdim    (*it)->claim();
1185239462Sdim
1186263508Sdim    // Skip over "-m".
1187263508Sdim    assert(Name.startswith("m") && "Invalid feature name.");
1188263508Sdim    Name = Name.substr(1);
1189239462Sdim
1190263508Sdim    bool IsNegative = Name.startswith("no-");
1191263508Sdim    if (IsNegative)
1192263508Sdim      Name = Name.substr(3);
1193249423Sdim
1194263508Sdim    // Note that gcc calls this mfcrf and LLVM calls this mfocrf so we
1195263508Sdim    // pass the correct option to the backend while calling the frontend
1196263508Sdim    // option the same.
1197263508Sdim    // TODO: Change the LLVM backend option maybe?
1198263508Sdim    if (Name == "mfcrf")
1199263508Sdim      Name = "mfocrf";
1200249423Sdim
1201263508Sdim    Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
1202263508Sdim  }
1203249423Sdim
1204263508Sdim  // Altivec is a bit weird, allow overriding of the Altivec feature here.
1205263508Sdim  AddTargetFeature(Args, Features, options::OPT_faltivec,
1206263508Sdim                   options::OPT_fno_altivec, "altivec");
1207239462Sdim}
1208239462Sdim
1209249423Sdim/// Get the (LLVM) name of the R600 gpu we are targeting.
1210249423Sdimstatic std::string getR600TargetGPU(const ArgList &Args) {
1211249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
1212263508Sdim    const char *GPUName = A->getValue();
1213249423Sdim    return llvm::StringSwitch<const char *>(GPUName)
1214251662Sdim      .Cases("rv630", "rv635", "r600")
1215251662Sdim      .Cases("rv610", "rv620", "rs780", "rs880")
1216249423Sdim      .Case("rv740", "rv770")
1217249423Sdim      .Case("palm", "cedar")
1218251662Sdim      .Cases("sumo", "sumo2", "sumo")
1219249423Sdim      .Case("hemlock", "cypress")
1220249423Sdim      .Case("aruba", "cayman")
1221263508Sdim      .Default(GPUName);
1222249423Sdim  }
1223249423Sdim  return "";
1224249423Sdim}
1225249423Sdim
1226263508Sdimstatic void getSparcTargetFeatures(const ArgList &Args,
1227263508Sdim                                   std::vector<const char *> Features) {
1228263508Sdim  bool SoftFloatABI = true;
1229263508Sdim  if (Arg *A =
1230263508Sdim          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float)) {
1231263508Sdim    if (A->getOption().matches(options::OPT_mhard_float))
1232263508Sdim      SoftFloatABI = false;
1233263508Sdim  }
1234263508Sdim  if (SoftFloatABI)
1235263508Sdim    Features.push_back("+soft-float");
1236249423Sdim}
1237249423Sdim
1238218893Sdimvoid Clang::AddSparcTargetArgs(const ArgList &Args,
1239218893Sdim                             ArgStringList &CmdArgs) const {
1240218893Sdim  const Driver &D = getToolChain().getDriver();
1241218893Sdim
1242218893Sdim  // Select the float ABI as determined by -msoft-float, -mhard-float, and
1243226633Sdim  StringRef FloatABI;
1244218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1245218893Sdim                               options::OPT_mhard_float)) {
1246218893Sdim    if (A->getOption().matches(options::OPT_msoft_float))
1247218893Sdim      FloatABI = "soft";
1248218893Sdim    else if (A->getOption().matches(options::OPT_mhard_float))
1249218893Sdim      FloatABI = "hard";
1250218893Sdim  }
1251218893Sdim
1252218893Sdim  // If unspecified, choose the default based on the platform.
1253218893Sdim  if (FloatABI.empty()) {
1254263508Sdim    // Assume "soft", but warn the user we are guessing.
1255263508Sdim    FloatABI = "soft";
1256263508Sdim    D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
1257218893Sdim  }
1258218893Sdim
1259218893Sdim  if (FloatABI == "soft") {
1260218893Sdim    // Floating point operations and argument passing are soft.
1261218893Sdim    //
1262218893Sdim    // FIXME: This changes CPP defines, we need -target-soft-float.
1263218893Sdim    CmdArgs.push_back("-msoft-float");
1264218893Sdim  } else {
1265218893Sdim    assert(FloatABI == "hard" && "Invalid float abi!");
1266218893Sdim    CmdArgs.push_back("-mhard-float");
1267218893Sdim  }
1268218893Sdim}
1269218893Sdim
1270263508Sdimstatic const char *getSystemZTargetCPU(const ArgList &Args) {
1271263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
1272263508Sdim    return A->getValue();
1273263508Sdim  return "z10";
1274263508Sdim}
1275263508Sdim
1276247166Sdimstatic const char *getX86TargetCPU(const ArgList &Args,
1277247166Sdim                                   const llvm::Triple &Triple) {
1278247166Sdim  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
1279263508Sdim    if (StringRef(A->getValue()) != "native") {
1280263508Sdim      if (Triple.isOSDarwin() && Triple.getArchName() == "x86_64h")
1281263508Sdim        return "core-avx2";
1282263508Sdim
1283247166Sdim      return A->getValue();
1284263508Sdim    }
1285247166Sdim
1286247166Sdim    // FIXME: Reject attempts to use -march=native unless the target matches
1287247166Sdim    // the host.
1288247166Sdim    //
1289247166Sdim    // FIXME: We should also incorporate the detected target features for use
1290247166Sdim    // with -native.
1291247166Sdim    std::string CPU = llvm::sys::getHostCPUName();
1292247166Sdim    if (!CPU.empty() && CPU != "generic")
1293247166Sdim      return Args.MakeArgString(CPU);
1294247166Sdim  }
1295247166Sdim
1296247166Sdim  // Select the default CPU if none was given (or detection failed).
1297247166Sdim
1298247166Sdim  if (Triple.getArch() != llvm::Triple::x86_64 &&
1299247166Sdim      Triple.getArch() != llvm::Triple::x86)
1300247166Sdim    return 0; // This routine is only handling x86 targets.
1301247166Sdim
1302247166Sdim  bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
1303247166Sdim
1304247166Sdim  // FIXME: Need target hooks.
1305263508Sdim  if (Triple.isOSDarwin()) {
1306263508Sdim    if (Triple.getArchName() == "x86_64h")
1307263508Sdim      return "core-avx2";
1308247166Sdim    return Is64Bit ? "core2" : "yonah";
1309263508Sdim  }
1310247166Sdim
1311263508Sdim  // All x86 devices running Android have core2 as their common
1312263508Sdim  // denominator. This makes a better choice than pentium4.
1313263508Sdim  if (Triple.getEnvironment() == llvm::Triple::Android)
1314263508Sdim    return "core2";
1315263508Sdim
1316247166Sdim  // Everything else goes to x86-64 in 64-bit mode.
1317247166Sdim  if (Is64Bit)
1318247166Sdim    return "x86-64";
1319247166Sdim
1320263508Sdim  switch (Triple.getOS()) {
1321263508Sdim  case llvm::Triple::FreeBSD:
1322263508Sdim  case llvm::Triple::NetBSD:
1323263508Sdim  case llvm::Triple::OpenBSD:
1324263508Sdim    return "i486";
1325263508Sdim  case llvm::Triple::Haiku:
1326247166Sdim    return "i586";
1327263508Sdim  case llvm::Triple::Bitrig:
1328247166Sdim    return "i686";
1329263508Sdim  default:
1330263508Sdim    // Fallback to p4.
1331263508Sdim    return "pentium4";
1332263508Sdim  }
1333263508Sdim}
1334247166Sdim
1335263508Sdimstatic std::string getCPUName(const ArgList &Args, const llvm::Triple &T) {
1336263508Sdim  switch(T.getArch()) {
1337263508Sdim  default:
1338263508Sdim    return "";
1339263508Sdim
1340263508Sdim  case llvm::Triple::aarch64:
1341263508Sdim    return getAArch64TargetCPU(Args, T);
1342263508Sdim
1343263508Sdim  case llvm::Triple::arm:
1344263508Sdim  case llvm::Triple::thumb:
1345263508Sdim    return getARMTargetCPU(Args, T);
1346263508Sdim
1347263508Sdim  case llvm::Triple::mips:
1348263508Sdim  case llvm::Triple::mipsel:
1349263508Sdim  case llvm::Triple::mips64:
1350263508Sdim  case llvm::Triple::mips64el: {
1351263508Sdim    StringRef CPUName;
1352263508Sdim    StringRef ABIName;
1353263508Sdim    getMipsCPUAndABI(Args, T, CPUName, ABIName);
1354263508Sdim    return CPUName;
1355263508Sdim  }
1356263508Sdim
1357263508Sdim  case llvm::Triple::ppc:
1358263508Sdim  case llvm::Triple::ppc64:
1359263508Sdim  case llvm::Triple::ppc64le: {
1360263508Sdim    std::string TargetCPUName = getPPCTargetCPU(Args);
1361263508Sdim    // LLVM may default to generating code for the native CPU,
1362263508Sdim    // but, like gcc, we default to a more generic option for
1363263508Sdim    // each architecture. (except on Darwin)
1364263508Sdim    if (TargetCPUName.empty() && !T.isOSDarwin()) {
1365263508Sdim      if (T.getArch() == llvm::Triple::ppc64)
1366263508Sdim        TargetCPUName = "ppc64";
1367263508Sdim      else if (T.getArch() == llvm::Triple::ppc64le)
1368263508Sdim        TargetCPUName = "ppc64le";
1369263508Sdim      else
1370263508Sdim        TargetCPUName = "ppc";
1371263508Sdim    }
1372263508Sdim    return TargetCPUName;
1373263508Sdim  }
1374263508Sdim
1375263508Sdim  case llvm::Triple::sparc:
1376263763Sdim  case llvm::Triple::sparcv9:
1377263763Sdim    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
1378263508Sdim      return A->getValue();
1379263508Sdim    return "";
1380263508Sdim
1381263508Sdim  case llvm::Triple::x86:
1382263508Sdim  case llvm::Triple::x86_64:
1383263508Sdim    return getX86TargetCPU(Args, T);
1384263508Sdim
1385263508Sdim  case llvm::Triple::hexagon:
1386263508Sdim    return "hexagon" + toolchains::Hexagon_TC::GetTargetCPU(Args).str();
1387263508Sdim
1388263508Sdim  case llvm::Triple::systemz:
1389263508Sdim    return getSystemZTargetCPU(Args);
1390263508Sdim
1391263508Sdim  case llvm::Triple::r600:
1392263508Sdim    return getR600TargetGPU(Args);
1393263508Sdim  }
1394247166Sdim}
1395247166Sdim
1396263508Sdimstatic void getX86TargetFeatures(const llvm::Triple &Triple,
1397263508Sdim                                 const ArgList &Args,
1398263508Sdim                                 std::vector<const char *> &Features) {
1399263508Sdim  if (Triple.getArchName() == "x86_64h") {
1400263508Sdim    // x86_64h implies quite a few of the more modern subtarget features
1401263508Sdim    // for Haswell class CPUs, but not all of them. Opt-out of a few.
1402263508Sdim    Features.push_back("-rdrnd");
1403263508Sdim    Features.push_back("-aes");
1404263508Sdim    Features.push_back("-pclmul");
1405263508Sdim    Features.push_back("-rtm");
1406263508Sdim    Features.push_back("-hle");
1407263508Sdim    Features.push_back("-fsgsbase");
1408263508Sdim  }
1409263508Sdim
1410263508Sdim  // Now add any that the user explicitly requested on the command line,
1411263508Sdim  // which may override the defaults.
1412263508Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
1413263508Sdim                    ie = Args.filtered_end();
1414263508Sdim       it != ie; ++it) {
1415263508Sdim    StringRef Name = (*it)->getOption().getName();
1416263508Sdim    (*it)->claim();
1417263508Sdim
1418263508Sdim    // Skip over "-m".
1419263508Sdim    assert(Name.startswith("m") && "Invalid feature name.");
1420263508Sdim    Name = Name.substr(1);
1421263508Sdim
1422263508Sdim    bool IsNegative = Name.startswith("no-");
1423263508Sdim    if (IsNegative)
1424263508Sdim      Name = Name.substr(3);
1425263508Sdim
1426263508Sdim    Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
1427263508Sdim  }
1428263508Sdim}
1429263508Sdim
1430198092Srdivackyvoid Clang::AddX86TargetArgs(const ArgList &Args,
1431198092Srdivacky                             ArgStringList &CmdArgs) const {
1432198092Srdivacky  if (!Args.hasFlag(options::OPT_mred_zone,
1433198092Srdivacky                    options::OPT_mno_red_zone,
1434198092Srdivacky                    true) ||
1435198092Srdivacky      Args.hasArg(options::OPT_mkernel) ||
1436198092Srdivacky      Args.hasArg(options::OPT_fapple_kext))
1437199990Srdivacky    CmdArgs.push_back("-disable-red-zone");
1438198092Srdivacky
1439249423Sdim  // Default to avoid implicit floating-point for kernel/kext code, but allow
1440249423Sdim  // that to be overridden with -mno-soft-float.
1441249423Sdim  bool NoImplicitFloat = (Args.hasArg(options::OPT_mkernel) ||
1442249423Sdim                          Args.hasArg(options::OPT_fapple_kext));
1443249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
1444249423Sdim                               options::OPT_mno_soft_float,
1445251662Sdim                               options::OPT_mimplicit_float,
1446249423Sdim                               options::OPT_mno_implicit_float)) {
1447249423Sdim    const Option &O = A->getOption();
1448249423Sdim    NoImplicitFloat = (O.matches(options::OPT_mno_implicit_float) ||
1449249423Sdim                       O.matches(options::OPT_msoft_float));
1450249423Sdim  }
1451249423Sdim  if (NoImplicitFloat)
1452199990Srdivacky    CmdArgs.push_back("-no-implicit-float");
1453198092Srdivacky}
1454198092Srdivacky
1455249423Sdimstatic inline bool HasPICArg(const ArgList &Args) {
1456249423Sdim  return Args.hasArg(options::OPT_fPIC)
1457249423Sdim    || Args.hasArg(options::OPT_fpic);
1458249423Sdim}
1459234353Sdim
1460249423Sdimstatic Arg *GetLastSmallDataThresholdArg(const ArgList &Args) {
1461249423Sdim  return Args.getLastArg(options::OPT_G,
1462249423Sdim                         options::OPT_G_EQ,
1463249423Sdim                         options::OPT_msmall_data_threshold_EQ);
1464234353Sdim}
1465234353Sdim
1466249423Sdimstatic std::string GetHexagonSmallDataThresholdValue(const ArgList &Args) {
1467249423Sdim  std::string value;
1468249423Sdim  if (HasPICArg(Args))
1469249423Sdim    value = "0";
1470249423Sdim  else if (Arg *A = GetLastSmallDataThresholdArg(Args)) {
1471249423Sdim    value = A->getValue();
1472249423Sdim    A->claim();
1473234353Sdim  }
1474249423Sdim  return value;
1475234353Sdim}
1476234353Sdim
1477234353Sdimvoid Clang::AddHexagonTargetArgs(const ArgList &Args,
1478234353Sdim                                 ArgStringList &CmdArgs) const {
1479234353Sdim  CmdArgs.push_back("-fno-signed-char");
1480249423Sdim  CmdArgs.push_back("-mqdsp6-compat");
1481249423Sdim  CmdArgs.push_back("-Wreturn-type");
1482234353Sdim
1483249423Sdim  std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
1484249423Sdim  if (!SmallDataThreshold.empty()) {
1485234353Sdim    CmdArgs.push_back ("-mllvm");
1486249423Sdim    CmdArgs.push_back(Args.MakeArgString(
1487249423Sdim                        "-hexagon-small-data-threshold=" + SmallDataThreshold));
1488234353Sdim  }
1489234353Sdim
1490239462Sdim  if (!Args.hasArg(options::OPT_fno_short_enums))
1491239462Sdim    CmdArgs.push_back("-fshort-enums");
1492239462Sdim  if (Args.getLastArg(options::OPT_mieee_rnd_near)) {
1493239462Sdim    CmdArgs.push_back ("-mllvm");
1494239462Sdim    CmdArgs.push_back ("-enable-hexagon-ieee-rnd-near");
1495239462Sdim  }
1496234353Sdim  CmdArgs.push_back ("-mllvm");
1497234353Sdim  CmdArgs.push_back ("-machine-sink-split=0");
1498234353Sdim}
1499234353Sdim
1500263508Sdimstatic void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
1501263508Sdim                                     std::vector<const char *> &Features) {
1502263508Sdim  // Honor -mfpu=.
1503263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
1504263508Sdim    getAArch64FPUFeatures(D, A, Args, Features);
1505263508Sdim}
1506263508Sdim
1507263508Sdimstatic void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
1508263508Sdim                              const ArgList &Args, ArgStringList &CmdArgs) {
1509263508Sdim  std::vector<const char *> Features;
1510263508Sdim  switch (Triple.getArch()) {
1511263508Sdim  default:
1512263508Sdim    break;
1513263508Sdim  case llvm::Triple::mips:
1514263508Sdim  case llvm::Triple::mipsel:
1515263508Sdim  case llvm::Triple::mips64:
1516263508Sdim  case llvm::Triple::mips64el:
1517263508Sdim    getMIPSTargetFeatures(D, Args, Features);
1518263508Sdim    break;
1519263508Sdim
1520263508Sdim  case llvm::Triple::arm:
1521263508Sdim  case llvm::Triple::thumb:
1522263508Sdim    getARMTargetFeatures(D, Triple, Args, Features);
1523263508Sdim    break;
1524263508Sdim
1525263508Sdim  case llvm::Triple::ppc:
1526263508Sdim  case llvm::Triple::ppc64:
1527263508Sdim  case llvm::Triple::ppc64le:
1528263508Sdim    getPPCTargetFeatures(Args, Features);
1529263508Sdim    break;
1530263508Sdim  case llvm::Triple::sparc:
1531263508Sdim    getSparcTargetFeatures(Args, Features);
1532263508Sdim    break;
1533263508Sdim  case llvm::Triple::aarch64:
1534263508Sdim    getAArch64TargetFeatures(D, Args, Features);
1535263508Sdim    break;
1536263508Sdim  case llvm::Triple::x86:
1537263508Sdim  case llvm::Triple::x86_64:
1538263508Sdim    getX86TargetFeatures(Triple, Args, Features);
1539263508Sdim    break;
1540263508Sdim  }
1541263508Sdim
1542263508Sdim  // Find the last of each feature.
1543263508Sdim  llvm::StringMap<unsigned> LastOpt;
1544263508Sdim  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
1545263508Sdim    const char *Name = Features[I];
1546263508Sdim    assert(Name[0] == '-' || Name[0] == '+');
1547263508Sdim    LastOpt[Name + 1] = I;
1548263508Sdim  }
1549263508Sdim
1550263508Sdim  for (unsigned I = 0, N = Features.size(); I < N; ++I) {
1551263508Sdim    // If this feature was overridden, ignore it.
1552263508Sdim    const char *Name = Features[I];
1553263508Sdim    llvm::StringMap<unsigned>::iterator LastI = LastOpt.find(Name + 1);
1554263508Sdim    assert(LastI != LastOpt.end());
1555263508Sdim    unsigned Last = LastI->second;
1556263508Sdim    if (Last != I)
1557263508Sdim      continue;
1558263508Sdim
1559263508Sdim    CmdArgs.push_back("-target-feature");
1560263508Sdim    CmdArgs.push_back(Name);
1561263508Sdim  }
1562263508Sdim}
1563263508Sdim
1564226633Sdimstatic bool
1565239462SdimshouldUseExceptionTablesForObjCExceptions(const ObjCRuntime &runtime,
1566221345Sdim                                          const llvm::Triple &Triple) {
1567221345Sdim  // We use the zero-cost exception tables for Objective-C if the non-fragile
1568221345Sdim  // ABI is enabled or when compiling for x86_64 and ARM on Snow Leopard and
1569221345Sdim  // later.
1570239462Sdim  if (runtime.isNonFragile())
1571221345Sdim    return true;
1572221345Sdim
1573226633Sdim  if (!Triple.isOSDarwin())
1574221345Sdim    return false;
1575221345Sdim
1576224145Sdim  return (!Triple.isMacOSXVersionLT(10,5) &&
1577221345Sdim          (Triple.getArch() == llvm::Triple::x86_64 ||
1578226633Sdim           Triple.getArch() == llvm::Triple::arm));
1579221345Sdim}
1580221345Sdim
1581221345Sdim/// addExceptionArgs - Adds exception related arguments to the driver command
1582221345Sdim/// arguments. There's a master flag, -fexceptions and also language specific
1583221345Sdim/// flags to enable/disable C++ and Objective-C exceptions.
1584221345Sdim/// This makes it possible to for example disable C++ exceptions but enable
1585221345Sdim/// Objective-C exceptions.
1586221345Sdimstatic void addExceptionArgs(const ArgList &Args, types::ID InputType,
1587221345Sdim                             const llvm::Triple &Triple,
1588234353Sdim                             bool KernelOrKext,
1589239462Sdim                             const ObjCRuntime &objcRuntime,
1590221345Sdim                             ArgStringList &CmdArgs) {
1591234353Sdim  if (KernelOrKext) {
1592234353Sdim    // -mkernel and -fapple-kext imply no exceptions, so claim exception related
1593234353Sdim    // arguments now to avoid warnings about unused arguments.
1594234353Sdim    Args.ClaimAllArgs(options::OPT_fexceptions);
1595234353Sdim    Args.ClaimAllArgs(options::OPT_fno_exceptions);
1596234353Sdim    Args.ClaimAllArgs(options::OPT_fobjc_exceptions);
1597234353Sdim    Args.ClaimAllArgs(options::OPT_fno_objc_exceptions);
1598234353Sdim    Args.ClaimAllArgs(options::OPT_fcxx_exceptions);
1599234353Sdim    Args.ClaimAllArgs(options::OPT_fno_cxx_exceptions);
1600221345Sdim    return;
1601234353Sdim  }
1602221345Sdim
1603221345Sdim  // Exceptions are enabled by default.
1604221345Sdim  bool ExceptionsEnabled = true;
1605221345Sdim
1606221345Sdim  // This keeps track of whether exceptions were explicitly turned on or off.
1607221345Sdim  bool DidHaveExplicitExceptionFlag = false;
1608221345Sdim
1609198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
1610198092Srdivacky                               options::OPT_fno_exceptions)) {
1611198092Srdivacky    if (A->getOption().matches(options::OPT_fexceptions))
1612221345Sdim      ExceptionsEnabled = true;
1613226633Sdim    else
1614221345Sdim      ExceptionsEnabled = false;
1615221345Sdim
1616221345Sdim    DidHaveExplicitExceptionFlag = true;
1617198092Srdivacky  }
1618218893Sdim
1619221345Sdim  bool ShouldUseExceptionTables = false;
1620198092Srdivacky
1621221345Sdim  // Exception tables and cleanups can be enabled with -fexceptions even if the
1622221345Sdim  // language itself doesn't support exceptions.
1623221345Sdim  if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
1624221345Sdim    ShouldUseExceptionTables = true;
1625221345Sdim
1626221345Sdim  // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
1627221345Sdim  // is not necessarily sensible, but follows GCC.
1628221345Sdim  if (types::isObjC(InputType) &&
1629226633Sdim      Args.hasFlag(options::OPT_fobjc_exceptions,
1630221345Sdim                   options::OPT_fno_objc_exceptions,
1631221345Sdim                   true)) {
1632221345Sdim    CmdArgs.push_back("-fobjc-exceptions");
1633221345Sdim
1634226633Sdim    ShouldUseExceptionTables |=
1635239462Sdim      shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
1636218893Sdim  }
1637198092Srdivacky
1638221345Sdim  if (types::isCXX(InputType)) {
1639221345Sdim    bool CXXExceptionsEnabled = ExceptionsEnabled;
1640221345Sdim
1641226633Sdim    if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
1642226633Sdim                                 options::OPT_fno_cxx_exceptions,
1643221345Sdim                                 options::OPT_fexceptions,
1644221345Sdim                                 options::OPT_fno_exceptions)) {
1645221345Sdim      if (A->getOption().matches(options::OPT_fcxx_exceptions))
1646221345Sdim        CXXExceptionsEnabled = true;
1647221345Sdim      else if (A->getOption().matches(options::OPT_fno_cxx_exceptions))
1648221345Sdim        CXXExceptionsEnabled = false;
1649221345Sdim    }
1650221345Sdim
1651221345Sdim    if (CXXExceptionsEnabled) {
1652221345Sdim      CmdArgs.push_back("-fcxx-exceptions");
1653221345Sdim
1654221345Sdim      ShouldUseExceptionTables = true;
1655221345Sdim    }
1656221345Sdim  }
1657221345Sdim
1658221345Sdim  if (ShouldUseExceptionTables)
1659221345Sdim    CmdArgs.push_back("-fexceptions");
1660198092Srdivacky}
1661198092Srdivacky
1662251662Sdimstatic bool ShouldDisableAutolink(const ArgList &Args,
1663251662Sdim                             const ToolChain &TC) {
1664251662Sdim  bool Default = true;
1665251662Sdim  if (TC.getTriple().isOSDarwin()) {
1666251662Sdim    // The native darwin assembler doesn't support the linker_option directives,
1667251662Sdim    // so we disable them if we think the .s file will be passed to it.
1668251662Sdim    Default = TC.useIntegratedAs();
1669251662Sdim  }
1670251662Sdim  return !Args.hasFlag(options::OPT_fautolink, options::OPT_fno_autolink,
1671251662Sdim                       Default);
1672251662Sdim}
1673251662Sdim
1674221345Sdimstatic bool ShouldDisableCFI(const ArgList &Args,
1675221345Sdim                             const ToolChain &TC) {
1676234353Sdim  bool Default = true;
1677226633Sdim  if (TC.getTriple().isOSDarwin()) {
1678223017Sdim    // The native darwin assembler doesn't support cfi directives, so
1679223017Sdim    // we disable them if we think the .s file will be passed to it.
1680249423Sdim    Default = TC.useIntegratedAs();
1681223017Sdim  }
1682234353Sdim  return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
1683249423Sdim                       options::OPT_fno_dwarf2_cfi_asm,
1684249423Sdim                       Default);
1685234353Sdim}
1686223017Sdim
1687234353Sdimstatic bool ShouldDisableDwarfDirectory(const ArgList &Args,
1688234353Sdim                                        const ToolChain &TC) {
1689234353Sdim  bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm,
1690234353Sdim                                        options::OPT_fno_dwarf_directory_asm,
1691249423Sdim                                        TC.useIntegratedAs());
1692234353Sdim  return !UseDwarfDirectory;
1693221345Sdim}
1694221345Sdim
1695223017Sdim/// \brief Check whether the given input tree contains any compilation actions.
1696223017Sdimstatic bool ContainsCompileAction(const Action *A) {
1697223017Sdim  if (isa<CompileJobAction>(A))
1698223017Sdim    return true;
1699223017Sdim
1700223017Sdim  for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
1701223017Sdim    if (ContainsCompileAction(*it))
1702223017Sdim      return true;
1703223017Sdim
1704223017Sdim  return false;
1705223017Sdim}
1706223017Sdim
1707223017Sdim/// \brief Check if -relax-all should be passed to the internal assembler.
1708223017Sdim/// This is done by default when compiling non-assembler source with -O0.
1709223017Sdimstatic bool UseRelaxAll(Compilation &C, const ArgList &Args) {
1710223017Sdim  bool RelaxDefault = true;
1711223017Sdim
1712223017Sdim  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1713223017Sdim    RelaxDefault = A->getOption().matches(options::OPT_O0);
1714223017Sdim
1715223017Sdim  if (RelaxDefault) {
1716223017Sdim    RelaxDefault = false;
1717223017Sdim    for (ActionList::const_iterator it = C.getActions().begin(),
1718223017Sdim           ie = C.getActions().end(); it != ie; ++it) {
1719223017Sdim      if (ContainsCompileAction(*it)) {
1720223017Sdim        RelaxDefault = true;
1721223017Sdim        break;
1722223017Sdim      }
1723223017Sdim    }
1724223017Sdim  }
1725223017Sdim
1726223017Sdim  return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all,
1727223017Sdim    RelaxDefault);
1728223017Sdim}
1729223017Sdim
1730263508Sdimstatic void CollectArgsForIntegratedAssembler(Compilation &C,
1731263508Sdim                                              const ArgList &Args,
1732263508Sdim                                              ArgStringList &CmdArgs,
1733263508Sdim                                              const Driver &D) {
1734263508Sdim    if (UseRelaxAll(C, Args))
1735263508Sdim      CmdArgs.push_back("-mrelax-all");
1736243830Sdim
1737263508Sdim    // When passing -I arguments to the assembler we sometimes need to
1738263508Sdim    // unconditionally take the next argument.  For example, when parsing
1739263508Sdim    // '-Wa,-I -Wa,foo' we need to accept the -Wa,foo arg after seeing the
1740263508Sdim    // -Wa,-I arg and when parsing '-Wa,-I,foo' we need to accept the 'foo'
1741263508Sdim    // arg after parsing the '-I' arg.
1742263508Sdim    bool TakeNextArg = false;
1743243830Sdim
1744263508Sdim    // When using an integrated assembler, translate -Wa, and -Xassembler
1745263508Sdim    // options.
1746263508Sdim    for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA,
1747263508Sdim                                               options::OPT_Xassembler),
1748263508Sdim           ie = Args.filtered_end(); it != ie; ++it) {
1749263508Sdim      const Arg *A = *it;
1750263508Sdim      A->claim();
1751243830Sdim
1752263508Sdim      for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) {
1753263508Sdim        StringRef Value = A->getValue(i);
1754263508Sdim        if (TakeNextArg) {
1755263508Sdim          CmdArgs.push_back(Value.data());
1756263508Sdim          TakeNextArg = false;
1757263508Sdim          continue;
1758263508Sdim        }
1759249423Sdim
1760263508Sdim        if (Value == "-force_cpusubtype_ALL") {
1761263508Sdim          // Do nothing, this is the default and we don't support anything else.
1762263508Sdim        } else if (Value == "-L") {
1763263508Sdim          CmdArgs.push_back("-msave-temp-labels");
1764263508Sdim        } else if (Value == "--fatal-warnings") {
1765263508Sdim          CmdArgs.push_back("-mllvm");
1766263508Sdim          CmdArgs.push_back("-fatal-assembler-warnings");
1767263508Sdim        } else if (Value == "--noexecstack") {
1768263508Sdim          CmdArgs.push_back("-mnoexecstack");
1769263508Sdim        } else if (Value.startswith("-I")) {
1770263508Sdim          CmdArgs.push_back(Value.data());
1771263508Sdim          // We need to consume the next argument if the current arg is a plain
1772263508Sdim          // -I. The next arg will be the include directory.
1773263508Sdim          if (Value == "-I")
1774263508Sdim            TakeNextArg = true;
1775263508Sdim        } else {
1776263508Sdim          D.Diag(diag::err_drv_unsupported_option_argument)
1777263508Sdim            << A->getOption().getName() << Value;
1778263508Sdim        }
1779263508Sdim      }
1780263508Sdim    }
1781263508Sdim}
1782249423Sdim
1783263508Sdimstatic void addProfileRTLinux(
1784263508Sdim    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
1785263508Sdim  if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
1786263508Sdim        Args.hasArg(options::OPT_fprofile_generate) ||
1787263508Sdim        Args.hasArg(options::OPT_fcreate_profile) ||
1788263508Sdim        Args.hasArg(options::OPT_coverage)))
1789263508Sdim    return;
1790249423Sdim
1791263508Sdim  // The profile runtime is located in the Linux library directory and has name
1792263508Sdim  // "libclang_rt.profile-<ArchName>.a".
1793263508Sdim  SmallString<128> LibProfile(TC.getDriver().ResourceDir);
1794263508Sdim  llvm::sys::path::append(
1795263508Sdim      LibProfile, "lib", "linux",
1796263508Sdim      Twine("libclang_rt.profile-") + TC.getArchName() + ".a");
1797249423Sdim
1798263508Sdim  CmdArgs.push_back(Args.MakeArgString(LibProfile));
1799243830Sdim}
1800243830Sdim
1801249423Sdimstatic void addSanitizerRTLinkFlagsLinux(
1802249423Sdim    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
1803249423Sdim    const StringRef Sanitizer, bool BeforeLibStdCXX,
1804249423Sdim    bool ExportSymbols = true) {
1805249423Sdim  // Sanitizer runtime is located in the Linux library directory and
1806249423Sdim  // has name "libclang_rt.<Sanitizer>-<ArchName>.a".
1807249423Sdim  SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
1808249423Sdim  llvm::sys::path::append(
1809249423Sdim      LibSanitizer, "lib", "linux",
1810249423Sdim      (Twine("libclang_rt.") + Sanitizer + "-" + TC.getArchName() + ".a"));
1811249423Sdim
1812249423Sdim  // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
1813249423Sdim  // etc.) so that the linker picks custom versions of the global 'operator
1814249423Sdim  // new' and 'operator delete' symbols. We take the extreme (but simple)
1815249423Sdim  // strategy of inserting it at the front of the link command. It also
1816249423Sdim  // needs to be forced to end up in the executable, so wrap it in
1817249423Sdim  // whole-archive.
1818249423Sdim  SmallVector<const char *, 3> LibSanitizerArgs;
1819249423Sdim  LibSanitizerArgs.push_back("-whole-archive");
1820249423Sdim  LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer));
1821249423Sdim  LibSanitizerArgs.push_back("-no-whole-archive");
1822249423Sdim
1823249423Sdim  CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
1824249423Sdim                 LibSanitizerArgs.begin(), LibSanitizerArgs.end());
1825249423Sdim
1826249423Sdim  CmdArgs.push_back("-lpthread");
1827251662Sdim  CmdArgs.push_back("-lrt");
1828249423Sdim  CmdArgs.push_back("-ldl");
1829263508Sdim  CmdArgs.push_back("-lm");
1830249423Sdim
1831249423Sdim  // If possible, use a dynamic symbols file to export the symbols from the
1832249423Sdim  // runtime library. If we can't do so, use -export-dynamic instead to export
1833249423Sdim  // all symbols from the binary.
1834249423Sdim  if (ExportSymbols) {
1835249423Sdim    if (llvm::sys::fs::exists(LibSanitizer + ".syms"))
1836249423Sdim      CmdArgs.push_back(
1837249423Sdim          Args.MakeArgString("--dynamic-list=" + LibSanitizer + ".syms"));
1838249423Sdim    else
1839249423Sdim      CmdArgs.push_back("-export-dynamic");
1840249423Sdim  }
1841249423Sdim}
1842249423Sdim
1843234353Sdim/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
1844234353Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1845234353Sdimstatic void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
1846234353Sdim                           ArgStringList &CmdArgs) {
1847263508Sdim  if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
1848243830Sdim    SmallString<128> LibAsan(TC.getDriver().ResourceDir);
1849243830Sdim    llvm::sys::path::append(LibAsan, "lib", "linux",
1850243830Sdim        (Twine("libclang_rt.asan-") +
1851243830Sdim            TC.getArchName() + "-android.so"));
1852249423Sdim    CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
1853239462Sdim  } else {
1854263508Sdim    if (!Args.hasArg(options::OPT_shared))
1855249423Sdim      addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
1856239462Sdim  }
1857234353Sdim}
1858234353Sdim
1859239462Sdim/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
1860239462Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1861239462Sdimstatic void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
1862239462Sdim                           ArgStringList &CmdArgs) {
1863263508Sdim  if (!Args.hasArg(options::OPT_shared))
1864249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
1865239462Sdim}
1866239462Sdim
1867249423Sdim/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
1868249423Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1869249423Sdimstatic void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
1870249423Sdim                           ArgStringList &CmdArgs) {
1871263508Sdim  if (!Args.hasArg(options::OPT_shared))
1872249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
1873249423Sdim}
1874249423Sdim
1875263508Sdim/// If LeakSanitizer is enabled, add appropriate linker flags (Linux).
1876263508Sdim/// This needs to be called before we add the C run-time (malloc, etc).
1877263508Sdimstatic void addLsanRTLinux(const ToolChain &TC, const ArgList &Args,
1878263508Sdim                           ArgStringList &CmdArgs) {
1879263508Sdim  if (!Args.hasArg(options::OPT_shared))
1880263508Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true);
1881263508Sdim}
1882263508Sdim
1883243830Sdim/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
1884243830Sdim/// (Linux).
1885243830Sdimstatic void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
1886249423Sdim                            ArgStringList &CmdArgs, bool IsCXX,
1887249423Sdim                            bool HasOtherSanitizerRt) {
1888249423Sdim  // Need a copy of sanitizer_common. This could come from another sanitizer
1889249423Sdim  // runtime; if we're not including one, include our own copy.
1890249423Sdim  if (!HasOtherSanitizerRt)
1891249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false);
1892249423Sdim
1893249423Sdim  addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
1894249423Sdim
1895249423Sdim  // Only include the bits of the runtime which need a C++ ABI library if
1896249423Sdim  // we're linking in C++ mode.
1897249423Sdim  if (IsCXX)
1898249423Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false);
1899243830Sdim}
1900243830Sdim
1901263508Sdimstatic void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args,
1902263508Sdim                            ArgStringList &CmdArgs) {
1903263508Sdim  if (!Args.hasArg(options::OPT_shared))
1904263508Sdim    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true);
1905263508Sdim}
1906263508Sdim
1907263508Sdimstatic bool shouldUseFramePointerForTarget(const ArgList &Args,
1908263508Sdim                                           const llvm::Triple &Triple) {
1909263508Sdim  switch (Triple.getArch()) {
1910263508Sdim  // Don't use a frame pointer on linux if optimizing for certain targets.
1911263508Sdim  case llvm::Triple::mips64:
1912263508Sdim  case llvm::Triple::mips64el:
1913263508Sdim  case llvm::Triple::mips:
1914263508Sdim  case llvm::Triple::mipsel:
1915263508Sdim  case llvm::Triple::systemz:
1916263508Sdim  case llvm::Triple::x86:
1917263508Sdim  case llvm::Triple::x86_64:
1918263508Sdim    if (Triple.isOSLinux())
1919263508Sdim      if (Arg *A = Args.getLastArg(options::OPT_O_Group))
1920263508Sdim        if (!A->getOption().matches(options::OPT_O0))
1921263508Sdim          return false;
1922263508Sdim    return true;
1923263508Sdim  case llvm::Triple::xcore:
1924263508Sdim    return false;
1925263508Sdim  default:
1926263508Sdim    return true;
1927263508Sdim  }
1928263508Sdim}
1929263508Sdim
1930234353Sdimstatic bool shouldUseFramePointer(const ArgList &Args,
1931234353Sdim                                  const llvm::Triple &Triple) {
1932234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
1933234353Sdim                               options::OPT_fomit_frame_pointer))
1934234353Sdim    return A->getOption().matches(options::OPT_fno_omit_frame_pointer);
1935234353Sdim
1936263508Sdim  return shouldUseFramePointerForTarget(Args, Triple);
1937234353Sdim}
1938234353Sdim
1939249423Sdimstatic bool shouldUseLeafFramePointer(const ArgList &Args,
1940249423Sdim                                      const llvm::Triple &Triple) {
1941249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
1942249423Sdim                               options::OPT_momit_leaf_frame_pointer))
1943249423Sdim    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
1944249423Sdim
1945263508Sdim  return shouldUseFramePointerForTarget(Args, Triple);
1946249423Sdim}
1947249423Sdim
1948263508Sdim/// Add a CC1 option to specify the debug compilation directory.
1949249423Sdimstatic void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) {
1950251662Sdim  SmallString<128> cwd;
1951251662Sdim  if (!llvm::sys::fs::current_path(cwd)) {
1952251662Sdim    CmdArgs.push_back("-fdebug-compilation-dir");
1953251662Sdim    CmdArgs.push_back(Args.MakeArgString(cwd));
1954251662Sdim  }
1955249423Sdim}
1956249423Sdim
1957249423Sdimstatic const char *SplitDebugName(const ArgList &Args,
1958249423Sdim                                  const InputInfoList &Inputs) {
1959249423Sdim  Arg *FinalOutput = Args.getLastArg(options::OPT_o);
1960249423Sdim  if (FinalOutput && Args.hasArg(options::OPT_c)) {
1961249423Sdim    SmallString<128> T(FinalOutput->getValue());
1962249423Sdim    llvm::sys::path::replace_extension(T, "dwo");
1963249423Sdim    return Args.MakeArgString(T);
1964249423Sdim  } else {
1965249423Sdim    // Use the compilation dir.
1966249423Sdim    SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
1967249423Sdim    SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput()));
1968249423Sdim    llvm::sys::path::replace_extension(F, "dwo");
1969249423Sdim    T += F;
1970249423Sdim    return Args.MakeArgString(F);
1971249423Sdim  }
1972249423Sdim}
1973249423Sdim
1974249423Sdimstatic void SplitDebugInfo(const ToolChain &TC, Compilation &C,
1975249423Sdim                           const Tool &T, const JobAction &JA,
1976249423Sdim                           const ArgList &Args, const InputInfo &Output,
1977249423Sdim                           const char *OutFile) {
1978249423Sdim  ArgStringList ExtractArgs;
1979249423Sdim  ExtractArgs.push_back("--extract-dwo");
1980249423Sdim
1981249423Sdim  ArgStringList StripArgs;
1982249423Sdim  StripArgs.push_back("--strip-dwo");
1983249423Sdim
1984249423Sdim  // Grabbing the output of the earlier compile step.
1985249423Sdim  StripArgs.push_back(Output.getFilename());
1986249423Sdim  ExtractArgs.push_back(Output.getFilename());
1987249423Sdim  ExtractArgs.push_back(OutFile);
1988249423Sdim
1989249423Sdim  const char *Exec =
1990249423Sdim    Args.MakeArgString(TC.GetProgramPath("objcopy"));
1991249423Sdim
1992249423Sdim  // First extract the dwo sections.
1993249423Sdim  C.addCommand(new Command(JA, T, Exec, ExtractArgs));
1994249423Sdim
1995249423Sdim  // Then remove them from the original .o file.
1996249423Sdim  C.addCommand(new Command(JA, T, Exec, StripArgs));
1997249423Sdim}
1998249423Sdim
1999263508Sdim/// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
2000263508Sdimstatic bool shouldEnableVectorizerAtOLevel(const ArgList &Args) {
2001263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
2002263508Sdim    if (A->getOption().matches(options::OPT_O4) ||
2003263508Sdim        A->getOption().matches(options::OPT_Ofast))
2004263508Sdim      return true;
2005263508Sdim
2006263508Sdim    if (A->getOption().matches(options::OPT_O0))
2007263508Sdim      return false;
2008263508Sdim
2009263508Sdim    assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
2010263508Sdim
2011263508Sdim    // Vectorize -Os.
2012263508Sdim    StringRef S(A->getValue());
2013263508Sdim    if (S == "s")
2014263508Sdim      return true;
2015263508Sdim
2016263508Sdim    // Don't vectorize -Oz.
2017263508Sdim    if (S == "z")
2018263508Sdim      return false;
2019263508Sdim
2020263508Sdim    unsigned OptLevel = 0;
2021263508Sdim    if (S.getAsInteger(10, OptLevel))
2022263508Sdim      return false;
2023263508Sdim
2024263508Sdim    return OptLevel > 1;
2025263508Sdim  }
2026263508Sdim
2027263508Sdim  return false;
2028263508Sdim}
2029263508Sdim
2030193326Sedvoid Clang::ConstructJob(Compilation &C, const JobAction &JA,
2031193326Sed                         const InputInfo &Output,
2032193326Sed                         const InputInfoList &Inputs,
2033193326Sed                         const ArgList &Args,
2034193326Sed                         const char *LinkingOutput) const {
2035205408Srdivacky  bool KernelOrKext = Args.hasArg(options::OPT_mkernel,
2036205408Srdivacky                                  options::OPT_fapple_kext);
2037201361Srdivacky  const Driver &D = getToolChain().getDriver();
2038193326Sed  ArgStringList CmdArgs;
2039193326Sed
2040193326Sed  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
2041193326Sed
2042200583Srdivacky  // Invoke ourselves in -cc1 mode.
2043200583Srdivacky  //
2044200583Srdivacky  // FIXME: Implement custom jobs for internal actions.
2045200583Srdivacky  CmdArgs.push_back("-cc1");
2046200583Srdivacky
2047198893Srdivacky  // Add the "effective" target triple.
2048193326Sed  CmdArgs.push_back("-triple");
2049212904Sdim  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
2050198893Srdivacky  CmdArgs.push_back(Args.MakeArgString(TripleStr));
2051198092Srdivacky
2052198893Srdivacky  // Select the appropriate action.
2053239462Sdim  RewriteKind rewriteKind = RK_None;
2054234353Sdim
2055193326Sed  if (isa<AnalyzeJobAction>(JA)) {
2056193326Sed    assert(JA.getType() == types::TY_Plist && "Invalid output type.");
2057193326Sed    CmdArgs.push_back("-analyze");
2058234353Sdim  } else if (isa<MigrateJobAction>(JA)) {
2059234353Sdim    CmdArgs.push_back("-migrate");
2060193326Sed  } else if (isa<PreprocessJobAction>(JA)) {
2061193326Sed    if (Output.getType() == types::TY_Dependencies)
2062193326Sed      CmdArgs.push_back("-Eonly");
2063249423Sdim    else {
2064193326Sed      CmdArgs.push_back("-E");
2065249423Sdim      if (Args.hasArg(options::OPT_rewrite_objc) &&
2066249423Sdim          !Args.hasArg(options::OPT_g_Group))
2067249423Sdim        CmdArgs.push_back("-P");
2068249423Sdim    }
2069203955Srdivacky  } else if (isa<AssembleJobAction>(JA)) {
2070203955Srdivacky    CmdArgs.push_back("-emit-obj");
2071208600Srdivacky
2072263508Sdim    CollectArgsForIntegratedAssembler(C, Args, CmdArgs, D);
2073212904Sdim
2074218893Sdim    // Also ignore explicit -force_cpusubtype_ALL option.
2075218893Sdim    (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
2076193326Sed  } else if (isa<PrecompileJobAction>(JA)) {
2077212904Sdim    // Use PCH if the user requested it.
2078198398Srdivacky    bool UsePCH = D.CCCUsePCH;
2079198398Srdivacky
2080239462Sdim    if (JA.getType() == types::TY_Nothing)
2081239462Sdim      CmdArgs.push_back("-fsyntax-only");
2082239462Sdim    else if (UsePCH)
2083193326Sed      CmdArgs.push_back("-emit-pch");
2084193326Sed    else
2085193326Sed      CmdArgs.push_back("-emit-pth");
2086193326Sed  } else {
2087193326Sed    assert(isa<CompileJobAction>(JA) && "Invalid action for clang tool.");
2088193326Sed
2089193326Sed    if (JA.getType() == types::TY_Nothing) {
2090193326Sed      CmdArgs.push_back("-fsyntax-only");
2091210299Sed    } else if (JA.getType() == types::TY_LLVM_IR ||
2092210299Sed               JA.getType() == types::TY_LTO_IR) {
2093193326Sed      CmdArgs.push_back("-emit-llvm");
2094210299Sed    } else if (JA.getType() == types::TY_LLVM_BC ||
2095210299Sed               JA.getType() == types::TY_LTO_BC) {
2096193326Sed      CmdArgs.push_back("-emit-llvm-bc");
2097193326Sed    } else if (JA.getType() == types::TY_PP_Asm) {
2098193326Sed      CmdArgs.push_back("-S");
2099198092Srdivacky    } else if (JA.getType() == types::TY_AST) {
2100198092Srdivacky      CmdArgs.push_back("-emit-pch");
2101249423Sdim    } else if (JA.getType() == types::TY_ModuleFile) {
2102249423Sdim      CmdArgs.push_back("-module-file-info");
2103203955Srdivacky    } else if (JA.getType() == types::TY_RewrittenObjC) {
2104203955Srdivacky      CmdArgs.push_back("-rewrite-objc");
2105239462Sdim      rewriteKind = RK_NonFragile;
2106234353Sdim    } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
2107234353Sdim      CmdArgs.push_back("-rewrite-objc");
2108239462Sdim      rewriteKind = RK_Fragile;
2109203955Srdivacky    } else {
2110203955Srdivacky      assert(JA.getType() == types::TY_PP_Asm &&
2111203955Srdivacky             "Unexpected output type!");
2112193326Sed    }
2113193326Sed  }
2114193326Sed
2115193326Sed  // The make clang go fast button.
2116193326Sed  CmdArgs.push_back("-disable-free");
2117193326Sed
2118203955Srdivacky  // Disable the verification pass in -asserts builds.
2119203955Srdivacky#ifdef NDEBUG
2120203955Srdivacky  CmdArgs.push_back("-disable-llvm-verifier");
2121203955Srdivacky#endif
2122203955Srdivacky
2123193326Sed  // Set the main file name, so that debug info works even with
2124193326Sed  // -save-temps.
2125193326Sed  CmdArgs.push_back("-main-file-name");
2126249423Sdim  CmdArgs.push_back(getBaseInputName(Args, Inputs));
2127193326Sed
2128193326Sed  // Some flags which affect the language (via preprocessor
2129249423Sdim  // defines).
2130193326Sed  if (Args.hasArg(options::OPT_static))
2131193326Sed    CmdArgs.push_back("-static-define");
2132193326Sed
2133193326Sed  if (isa<AnalyzeJobAction>(JA)) {
2134198092Srdivacky    // Enable region store model by default.
2135198092Srdivacky    CmdArgs.push_back("-analyzer-store=region");
2136198092Srdivacky
2137200583Srdivacky    // Treat blocks as analysis entry points.
2138200583Srdivacky    CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
2139200583Srdivacky
2140221345Sdim    CmdArgs.push_back("-analyzer-eagerly-assume");
2141221345Sdim
2142193326Sed    // Add default argument set.
2143193326Sed    if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
2144221345Sdim      CmdArgs.push_back("-analyzer-checker=core");
2145218893Sdim
2146218893Sdim      if (getToolChain().getTriple().getOS() != llvm::Triple::Win32)
2147218893Sdim        CmdArgs.push_back("-analyzer-checker=unix");
2148221345Sdim
2149218893Sdim      if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
2150221345Sdim        CmdArgs.push_back("-analyzer-checker=osx");
2151234353Sdim
2152234353Sdim      CmdArgs.push_back("-analyzer-checker=deadcode");
2153234353Sdim
2154251662Sdim      if (types::isCXX(Inputs[0].getType()))
2155251662Sdim        CmdArgs.push_back("-analyzer-checker=cplusplus");
2156251662Sdim
2157234353Sdim      // Enable the following experimental checkers for testing.
2158234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
2159234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.getpw");
2160234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.gets");
2161234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mktemp");
2162234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.mkstemp");
2163234353Sdim      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.vfork");
2164193326Sed    }
2165193326Sed
2166193326Sed    // Set the output format. The default is plist, for (lame) historical
2167193326Sed    // reasons.
2168193326Sed    CmdArgs.push_back("-analyzer-output");
2169193326Sed    if (Arg *A = Args.getLastArg(options::OPT__analyzer_output))
2170243830Sdim      CmdArgs.push_back(A->getValue());
2171193326Sed    else
2172193326Sed      CmdArgs.push_back("plist");
2173193326Sed
2174206084Srdivacky    // Disable the presentation of standard compiler warnings when
2175206084Srdivacky    // using --analyze.  We only want to show static analyzer diagnostics
2176206084Srdivacky    // or frontend errors.
2177206084Srdivacky    CmdArgs.push_back("-w");
2178206084Srdivacky
2179193326Sed    // Add -Xanalyzer arguments when running as analyzer.
2180193326Sed    Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
2181198092Srdivacky  }
2182198092Srdivacky
2183198092Srdivacky  CheckCodeGenerationOptions(D, Args);
2184198092Srdivacky
2185251662Sdim  bool PIE = getToolChain().isPIEDefault();
2186251662Sdim  bool PIC = PIE || getToolChain().isPICDefault();
2187243830Sdim  bool IsPICLevelTwo = PIC;
2188251662Sdim
2189251662Sdim  // For the PIC and PIE flag options, this logic is different from the
2190251662Sdim  // legacy logic in very old versions of GCC, as that logic was just
2191251662Sdim  // a bug no one had ever fixed. This logic is both more rational and
2192251662Sdim  // consistent with GCC's new logic now that the bugs are fixed. The last
2193251662Sdim  // argument relating to either PIC or PIE wins, and no other argument is
2194251662Sdim  // used. If the last argument is any flavor of the '-fno-...' arguments,
2195251662Sdim  // both PIC and PIE are disabled. Any PIE option implicitly enables PIC
2196251662Sdim  // at the same level.
2197251662Sdim  Arg *LastPICArg =Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
2198251662Sdim                                 options::OPT_fpic, options::OPT_fno_pic,
2199251662Sdim                                 options::OPT_fPIE, options::OPT_fno_PIE,
2200251662Sdim                                 options::OPT_fpie, options::OPT_fno_pie);
2201243830Sdim  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
2202243830Sdim  // is forced, then neither PIC nor PIE flags will have no effect.
2203251662Sdim  if (!getToolChain().isPICDefaultForced()) {
2204251662Sdim    if (LastPICArg) {
2205251662Sdim      Option O = LastPICArg->getOption();
2206251662Sdim      if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
2207251662Sdim          O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
2208251662Sdim        PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
2209251662Sdim        PIC = PIE || O.matches(options::OPT_fPIC) ||
2210251662Sdim              O.matches(options::OPT_fpic);
2211251662Sdim        IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
2212251662Sdim                        O.matches(options::OPT_fPIC);
2213251662Sdim      } else {
2214251662Sdim        PIE = PIC = false;
2215251662Sdim      }
2216251662Sdim    }
2217243830Sdim  }
2218193326Sed
2219263508Sdim  // Introduce a Darwin-specific hack. If the default is PIC but the flags
2220243830Sdim  // specified while enabling PIC enabled level 1 PIC, just force it back to
2221243830Sdim  // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my
2222243830Sdim  // informal testing).
2223243830Sdim  if (PIC && getToolChain().getTriple().isOSDarwin())
2224243830Sdim    IsPICLevelTwo |= getToolChain().isPICDefault();
2225239462Sdim
2226234353Sdim  // Note that these flags are trump-cards. Regardless of the order w.r.t. the
2227234353Sdim  // PIC or PIE options above, if these show up, PIC is disabled.
2228243830Sdim  llvm::Triple Triple(TripleStr);
2229249423Sdim  if (KernelOrKext &&
2230263508Sdim      (!Triple.isiOS() || Triple.isOSVersionLT(6)))
2231243830Sdim    PIC = PIE = false;
2232234353Sdim  if (Args.hasArg(options::OPT_static))
2233243830Sdim    PIC = PIE = false;
2234234353Sdim
2235243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
2236243830Sdim    // This is a very special mode. It trumps the other modes, almost no one
2237243830Sdim    // uses it, and it isn't even valid on any OS but Darwin.
2238243830Sdim    if (!getToolChain().getTriple().isOSDarwin())
2239243830Sdim      D.Diag(diag::err_drv_unsupported_opt_for_target)
2240243830Sdim        << A->getSpelling() << getToolChain().getTriple().str();
2241243830Sdim
2242243830Sdim    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
2243243830Sdim
2244199990Srdivacky    CmdArgs.push_back("-mrelocation-model");
2245243830Sdim    CmdArgs.push_back("dynamic-no-pic");
2246193326Sed
2247243830Sdim    // Only a forced PIC mode can cause the actual compile to have PIC defines
2248243830Sdim    // etc., no flags are sufficient. This behavior was selected to closely
2249243830Sdim    // match that of llvm-gcc and Apple GCC before that.
2250243830Sdim    if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) {
2251243830Sdim      CmdArgs.push_back("-pic-level");
2252243830Sdim      CmdArgs.push_back("2");
2253243830Sdim    }
2254243830Sdim  } else {
2255243830Sdim    // Currently, LLVM only knows about PIC vs. static; the PIE differences are
2256243830Sdim    // handled in Clang's IRGen by the -pie-level flag.
2257243830Sdim    CmdArgs.push_back("-mrelocation-model");
2258243830Sdim    CmdArgs.push_back(PIC ? "pic" : "static");
2259243830Sdim
2260243830Sdim    if (PIC) {
2261243830Sdim      CmdArgs.push_back("-pic-level");
2262243830Sdim      CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
2263243830Sdim      if (PIE) {
2264243830Sdim        CmdArgs.push_back("-pie-level");
2265243830Sdim        CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
2266243830Sdim      }
2267243830Sdim    }
2268193326Sed  }
2269234353Sdim
2270199990Srdivacky  if (!Args.hasFlag(options::OPT_fmerge_all_constants,
2271199990Srdivacky                    options::OPT_fno_merge_all_constants))
2272221345Sdim    CmdArgs.push_back("-fno-merge-all-constants");
2273193326Sed
2274199990Srdivacky  // LLVM Code Generator Options.
2275199990Srdivacky
2276218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
2277218893Sdim    CmdArgs.push_back("-mregparm");
2278243830Sdim    CmdArgs.push_back(A->getValue());
2279218893Sdim  }
2280218893Sdim
2281263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fpcc_struct_return,
2282263508Sdim                               options::OPT_freg_struct_return)) {
2283263508Sdim    if (getToolChain().getArch() != llvm::Triple::x86) {
2284263508Sdim      D.Diag(diag::err_drv_unsupported_opt_for_target)
2285263508Sdim        << A->getSpelling() << getToolChain().getTriple().str();
2286263508Sdim    } else if (A->getOption().matches(options::OPT_fpcc_struct_return)) {
2287263508Sdim      CmdArgs.push_back("-fpcc-struct-return");
2288263508Sdim    } else {
2289263508Sdim      assert(A->getOption().matches(options::OPT_freg_struct_return));
2290263508Sdim      CmdArgs.push_back("-freg-struct-return");
2291263508Sdim    }
2292263508Sdim  }
2293263508Sdim
2294221345Sdim  if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false))
2295221345Sdim    CmdArgs.push_back("-mrtd");
2296221345Sdim
2297234353Sdim  if (shouldUseFramePointer(Args, getToolChain().getTriple()))
2298199990Srdivacky    CmdArgs.push_back("-mdisable-fp-elim");
2299193326Sed  if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss,
2300199990Srdivacky                    options::OPT_fno_zero_initialized_in_bss))
2301199990Srdivacky    CmdArgs.push_back("-mno-zero-initialized-in-bss");
2302251662Sdim
2303251662Sdim  bool OFastEnabled = isOptimizationLevelFast(Args);
2304251662Sdim  // If -Ofast is the optimization level, then -fstrict-aliasing should be
2305251662Sdim  // enabled.  This alias option is being used to simplify the hasFlag logic.
2306251662Sdim  OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast :
2307251662Sdim    options::OPT_fstrict_aliasing;
2308251662Sdim  if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption,
2309263508Sdim                    options::OPT_fno_strict_aliasing, true))
2310218893Sdim    CmdArgs.push_back("-relaxed-aliasing");
2311263508Sdim  if (!Args.hasFlag(options::OPT_fstruct_path_tbaa,
2312263508Sdim                    options::OPT_fno_struct_path_tbaa))
2313263508Sdim    CmdArgs.push_back("-no-struct-path-tbaa");
2314234353Sdim  if (Args.hasFlag(options::OPT_fstrict_enums, options::OPT_fno_strict_enums,
2315234353Sdim                   false))
2316234353Sdim    CmdArgs.push_back("-fstrict-enums");
2317234353Sdim  if (!Args.hasFlag(options::OPT_foptimize_sibling_calls,
2318234353Sdim                    options::OPT_fno_optimize_sibling_calls))
2319234353Sdim    CmdArgs.push_back("-mdisable-tail-calls");
2320208600Srdivacky
2321249423Sdim  // Handle segmented stacks.
2322249423Sdim  if (Args.hasArg(options::OPT_fsplit_stack))
2323249423Sdim    CmdArgs.push_back("-split-stacks");
2324251662Sdim
2325251662Sdim  // If -Ofast is the optimization level, then -ffast-math should be enabled.
2326251662Sdim  // This alias option is being used to simplify the getLastArg logic.
2327251662Sdim  OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast :
2328251662Sdim    options::OPT_ffast_math;
2329249423Sdim
2330234353Sdim  // Handle various floating point optimization flags, mapping them to the
2331234353Sdim  // appropriate LLVM code generation flags. The pattern for all of these is to
2332234353Sdim  // default off the codegen optimizations, and if any flag enables them and no
2333234353Sdim  // flag disables them after the flag enabling them, enable the codegen
2334234353Sdim  // optimization. This is complicated by several "umbrella" flags.
2335251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2336243830Sdim                               options::OPT_fno_fast_math,
2337234353Sdim                               options::OPT_ffinite_math_only,
2338234353Sdim                               options::OPT_fno_finite_math_only,
2339234353Sdim                               options::OPT_fhonor_infinities,
2340234353Sdim                               options::OPT_fno_honor_infinities))
2341243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2342243830Sdim        A->getOption().getID() != options::OPT_fno_finite_math_only &&
2343234353Sdim        A->getOption().getID() != options::OPT_fhonor_infinities)
2344234353Sdim      CmdArgs.push_back("-menable-no-infs");
2345251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2346243830Sdim                               options::OPT_fno_fast_math,
2347234353Sdim                               options::OPT_ffinite_math_only,
2348234353Sdim                               options::OPT_fno_finite_math_only,
2349234353Sdim                               options::OPT_fhonor_nans,
2350234353Sdim                               options::OPT_fno_honor_nans))
2351243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2352243830Sdim        A->getOption().getID() != options::OPT_fno_finite_math_only &&
2353234353Sdim        A->getOption().getID() != options::OPT_fhonor_nans)
2354234353Sdim      CmdArgs.push_back("-menable-no-nans");
2355234353Sdim
2356239462Sdim  // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes.
2357239462Sdim  bool MathErrno = getToolChain().IsMathErrnoDefault();
2358251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2359243830Sdim                               options::OPT_fno_fast_math,
2360234353Sdim                               options::OPT_fmath_errno,
2361263508Sdim                               options::OPT_fno_math_errno)) {
2362263508Sdim    // Turning on -ffast_math (with either flag) removes the need for MathErrno.
2363263508Sdim    // However, turning *off* -ffast_math merely restores the toolchain default
2364263508Sdim    // (which may be false).
2365263508Sdim    if (A->getOption().getID() == options::OPT_fno_math_errno ||
2366263508Sdim        A->getOption().getID() == options::OPT_ffast_math ||
2367263508Sdim        A->getOption().getID() == options::OPT_Ofast)
2368263508Sdim      MathErrno = false;
2369263508Sdim    else if (A->getOption().getID() == options::OPT_fmath_errno)
2370263508Sdim      MathErrno = true;
2371263508Sdim  }
2372239462Sdim  if (MathErrno)
2373239462Sdim    CmdArgs.push_back("-fmath-errno");
2374234353Sdim
2375234353Sdim  // There are several flags which require disabling very specific
2376234353Sdim  // optimizations. Any of these being disabled forces us to turn off the
2377234353Sdim  // entire set of LLVM optimizations, so collect them through all the flag
2378234353Sdim  // madness.
2379234353Sdim  bool AssociativeMath = false;
2380251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2381243830Sdim                               options::OPT_fno_fast_math,
2382234353Sdim                               options::OPT_funsafe_math_optimizations,
2383234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2384234353Sdim                               options::OPT_fassociative_math,
2385234353Sdim                               options::OPT_fno_associative_math))
2386243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2387243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2388234353Sdim        A->getOption().getID() != options::OPT_fno_associative_math)
2389234353Sdim      AssociativeMath = true;
2390234353Sdim  bool ReciprocalMath = false;
2391251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2392243830Sdim                               options::OPT_fno_fast_math,
2393234353Sdim                               options::OPT_funsafe_math_optimizations,
2394234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2395234353Sdim                               options::OPT_freciprocal_math,
2396234353Sdim                               options::OPT_fno_reciprocal_math))
2397243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2398243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2399234353Sdim        A->getOption().getID() != options::OPT_fno_reciprocal_math)
2400234353Sdim      ReciprocalMath = true;
2401234353Sdim  bool SignedZeros = true;
2402251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2403243830Sdim                               options::OPT_fno_fast_math,
2404234353Sdim                               options::OPT_funsafe_math_optimizations,
2405234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2406234353Sdim                               options::OPT_fsigned_zeros,
2407234353Sdim                               options::OPT_fno_signed_zeros))
2408243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2409243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2410234353Sdim        A->getOption().getID() != options::OPT_fsigned_zeros)
2411234353Sdim      SignedZeros = false;
2412234353Sdim  bool TrappingMath = true;
2413251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2414243830Sdim                               options::OPT_fno_fast_math,
2415234353Sdim                               options::OPT_funsafe_math_optimizations,
2416234353Sdim                               options::OPT_fno_unsafe_math_optimizations,
2417234353Sdim                               options::OPT_ftrapping_math,
2418234353Sdim                               options::OPT_fno_trapping_math))
2419243830Sdim    if (A->getOption().getID() != options::OPT_fno_fast_math &&
2420243830Sdim        A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
2421234353Sdim        A->getOption().getID() != options::OPT_ftrapping_math)
2422234353Sdim      TrappingMath = false;
2423234353Sdim  if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
2424234353Sdim      !TrappingMath)
2425234353Sdim    CmdArgs.push_back("-menable-unsafe-fp-math");
2426234353Sdim
2427239462Sdim
2428239462Sdim  // Validate and pass through -fp-contract option.
2429251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2430243830Sdim                               options::OPT_fno_fast_math,
2431239462Sdim                               options::OPT_ffp_contract)) {
2432239462Sdim    if (A->getOption().getID() == options::OPT_ffp_contract) {
2433243830Sdim      StringRef Val = A->getValue();
2434239462Sdim      if (Val == "fast" || Val == "on" || Val == "off") {
2435239462Sdim        CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + Val));
2436239462Sdim      } else {
2437239462Sdim        D.Diag(diag::err_drv_unsupported_option_argument)
2438239462Sdim          << A->getOption().getName() << Val;
2439239462Sdim      }
2440251662Sdim    } else if (A->getOption().matches(options::OPT_ffast_math) ||
2441251662Sdim               (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) {
2442239462Sdim      // If fast-math is set then set the fp-contract mode to fast.
2443239462Sdim      CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
2444239462Sdim    }
2445239462Sdim  }
2446239462Sdim
2447239462Sdim  // We separately look for the '-ffast-math' and '-ffinite-math-only' flags,
2448239462Sdim  // and if we find them, tell the frontend to provide the appropriate
2449239462Sdim  // preprocessor macros. This is distinct from enabling any optimizations as
2450239462Sdim  // these options induce language changes which must survive serialization
2451239462Sdim  // and deserialization, etc.
2452251662Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption,
2453251662Sdim                               options::OPT_fno_fast_math))
2454251662Sdim      if (!A->getOption().matches(options::OPT_fno_fast_math))
2455251662Sdim        CmdArgs.push_back("-ffast-math");
2456243830Sdim  if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math))
2457243830Sdim    if (A->getOption().matches(options::OPT_ffinite_math_only))
2458243830Sdim      CmdArgs.push_back("-ffinite-math-only");
2459234353Sdim
2460208600Srdivacky  // Decide whether to use verbose asm. Verbose assembly is the default on
2461208600Srdivacky  // toolchains which have the integrated assembler on by default.
2462208600Srdivacky  bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
2463208600Srdivacky  if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
2464218893Sdim                   IsVerboseAsmDefault) ||
2465208600Srdivacky      Args.hasArg(options::OPT_dA))
2466199990Srdivacky    CmdArgs.push_back("-masm-verbose");
2467208600Srdivacky
2468199990Srdivacky  if (Args.hasArg(options::OPT_fdebug_pass_structure)) {
2469199990Srdivacky    CmdArgs.push_back("-mdebug-pass");
2470199990Srdivacky    CmdArgs.push_back("Structure");
2471199990Srdivacky  }
2472199990Srdivacky  if (Args.hasArg(options::OPT_fdebug_pass_arguments)) {
2473199990Srdivacky    CmdArgs.push_back("-mdebug-pass");
2474199990Srdivacky    CmdArgs.push_back("Arguments");
2475199990Srdivacky  }
2476198092Srdivacky
2477204643Srdivacky  // Enable -mconstructor-aliases except on darwin, where we have to
2478204643Srdivacky  // work around a linker bug;  see <rdar://problem/7651567>.
2479226633Sdim  if (!getToolChain().getTriple().isOSDarwin())
2480204643Srdivacky    CmdArgs.push_back("-mconstructor-aliases");
2481204643Srdivacky
2482221345Sdim  // Darwin's kernel doesn't support guard variables; just die if we
2483221345Sdim  // try to use them.
2484226633Sdim  if (KernelOrKext && getToolChain().getTriple().isOSDarwin())
2485221345Sdim    CmdArgs.push_back("-fforbid-guard-variables");
2486221345Sdim
2487218893Sdim  if (Args.hasArg(options::OPT_mms_bitfields)) {
2488218893Sdim    CmdArgs.push_back("-mms-bitfields");
2489218893Sdim  }
2490218893Sdim
2491198092Srdivacky  // This is a coarse approximation of what llvm-gcc actually does, both
2492198092Srdivacky  // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
2493198092Srdivacky  // complicated ways.
2494198092Srdivacky  bool AsynchronousUnwindTables =
2495198092Srdivacky    Args.hasFlag(options::OPT_fasynchronous_unwind_tables,
2496198092Srdivacky                 options::OPT_fno_asynchronous_unwind_tables,
2497198092Srdivacky                 getToolChain().IsUnwindTablesDefault() &&
2498205408Srdivacky                 !KernelOrKext);
2499198092Srdivacky  if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
2500198092Srdivacky                   AsynchronousUnwindTables))
2501199990Srdivacky    CmdArgs.push_back("-munwind-tables");
2502193326Sed
2503249423Sdim  getToolChain().addClangTargetOptions(Args, CmdArgs);
2504239462Sdim
2505199990Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
2506199990Srdivacky    CmdArgs.push_back("-mlimit-float-precision");
2507243830Sdim    CmdArgs.push_back(A->getValue());
2508199990Srdivacky  }
2509199990Srdivacky
2510193326Sed  // FIXME: Handle -mtune=.
2511193326Sed  (void) Args.hasArg(options::OPT_mtune_EQ);
2512193326Sed
2513198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
2514199990Srdivacky    CmdArgs.push_back("-mcode-model");
2515243830Sdim    CmdArgs.push_back(A->getValue());
2516193326Sed  }
2517193326Sed
2518263508Sdim  // Add the target cpu
2519263508Sdim  std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
2520263508Sdim  llvm::Triple ETriple(ETripleStr);
2521263508Sdim  std::string CPU = getCPUName(Args, ETriple);
2522263508Sdim  if (!CPU.empty()) {
2523263508Sdim    CmdArgs.push_back("-target-cpu");
2524263508Sdim    CmdArgs.push_back(Args.MakeArgString(CPU));
2525263508Sdim  }
2526263508Sdim
2527263508Sdim  if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ)) {
2528263508Sdim    CmdArgs.push_back("-mfpmath");
2529263508Sdim    CmdArgs.push_back(A->getValue());
2530263508Sdim  }
2531263508Sdim
2532263508Sdim  // Add the target features
2533263508Sdim  getTargetFeatures(D, ETriple, Args, CmdArgs);
2534263508Sdim
2535263508Sdim  // Add target specific flags.
2536263508Sdim  switch(getToolChain().getArch()) {
2537198092Srdivacky  default:
2538198092Srdivacky    break;
2539193326Sed
2540198092Srdivacky  case llvm::Triple::arm:
2541198092Srdivacky  case llvm::Triple::thumb:
2542221345Sdim    AddARMTargetArgs(Args, CmdArgs, KernelOrKext);
2543198092Srdivacky    break;
2544193326Sed
2545204643Srdivacky  case llvm::Triple::mips:
2546204643Srdivacky  case llvm::Triple::mipsel:
2547226633Sdim  case llvm::Triple::mips64:
2548226633Sdim  case llvm::Triple::mips64el:
2549204643Srdivacky    AddMIPSTargetArgs(Args, CmdArgs);
2550204643Srdivacky    break;
2551204643Srdivacky
2552218893Sdim  case llvm::Triple::sparc:
2553218893Sdim    AddSparcTargetArgs(Args, CmdArgs);
2554218893Sdim    break;
2555218893Sdim
2556198092Srdivacky  case llvm::Triple::x86:
2557198092Srdivacky  case llvm::Triple::x86_64:
2558198092Srdivacky    AddX86TargetArgs(Args, CmdArgs);
2559198092Srdivacky    break;
2560234353Sdim
2561234353Sdim  case llvm::Triple::hexagon:
2562234353Sdim    AddHexagonTargetArgs(Args, CmdArgs);
2563234353Sdim    break;
2564193326Sed  }
2565193326Sed
2566263508Sdim  // Add clang-cl arguments.
2567263508Sdim  if (getToolChain().getDriver().IsCLMode())
2568263508Sdim    AddClangCLArgs(Args, CmdArgs);
2569234353Sdim
2570212904Sdim  // Pass the linker version in use.
2571212904Sdim  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
2572212904Sdim    CmdArgs.push_back("-target-linker-version");
2573243830Sdim    CmdArgs.push_back(A->getValue());
2574212904Sdim  }
2575212904Sdim
2576249423Sdim  if (!shouldUseLeafFramePointer(Args, getToolChain().getTriple()))
2577210299Sed    CmdArgs.push_back("-momit-leaf-frame-pointer");
2578210299Sed
2579208600Srdivacky  // Explicitly error on some things we know we don't support and can't just
2580208600Srdivacky  // ignore.
2581208600Srdivacky  types::ID InputType = Inputs[0].getType();
2582218893Sdim  if (!Args.hasArg(options::OPT_fallow_unsupported)) {
2583218893Sdim    Arg *Unsupported;
2584218893Sdim    if (types::isCXX(InputType) &&
2585226633Sdim        getToolChain().getTriple().isOSDarwin() &&
2586263508Sdim        getToolChain().getArch() == llvm::Triple::x86) {
2587226633Sdim      if ((Unsupported = Args.getLastArg(options::OPT_fapple_kext)) ||
2588226633Sdim          (Unsupported = Args.getLastArg(options::OPT_mkernel)))
2589226633Sdim        D.Diag(diag::err_drv_clang_unsupported_opt_cxx_darwin_i386)
2590218893Sdim          << Unsupported->getOption().getName();
2591218893Sdim    }
2592208600Srdivacky  }
2593208600Srdivacky
2594193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_v);
2595212904Sdim  Args.AddLastArg(CmdArgs, options::OPT_H);
2596226633Sdim  if (D.CCPrintHeaders && !D.CCGenDiagnostics) {
2597218893Sdim    CmdArgs.push_back("-header-include-file");
2598218893Sdim    CmdArgs.push_back(D.CCPrintHeadersFilename ?
2599218893Sdim                      D.CCPrintHeadersFilename : "-");
2600218893Sdim  }
2601193326Sed  Args.AddLastArg(CmdArgs, options::OPT_P);
2602198092Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_print_ivar_layout);
2603193326Sed
2604226633Sdim  if (D.CCLogDiagnostics && !D.CCGenDiagnostics) {
2605221345Sdim    CmdArgs.push_back("-diagnostic-log-file");
2606221345Sdim    CmdArgs.push_back(D.CCLogDiagnosticsFilename ?
2607221345Sdim                      D.CCLogDiagnosticsFilename : "-");
2608221345Sdim  }
2609221345Sdim
2610249423Sdim  // Use the last option from "-g" group. "-gline-tables-only"
2611249423Sdim  // is preserved, all other debug options are substituted with "-g".
2612204962Srdivacky  Args.ClaimAllArgs(options::OPT_g_Group);
2613239462Sdim  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
2614249423Sdim    if (A->getOption().matches(options::OPT_gline_tables_only))
2615239462Sdim      CmdArgs.push_back("-gline-tables-only");
2616263508Sdim    else if (A->getOption().matches(options::OPT_gdwarf_2))
2617263508Sdim      CmdArgs.push_back("-gdwarf-2");
2618263508Sdim    else if (A->getOption().matches(options::OPT_gdwarf_3))
2619263508Sdim      CmdArgs.push_back("-gdwarf-3");
2620263508Sdim    else if (A->getOption().matches(options::OPT_gdwarf_4))
2621263508Sdim      CmdArgs.push_back("-gdwarf-4");
2622249423Sdim    else if (!A->getOption().matches(options::OPT_g0) &&
2623263508Sdim             !A->getOption().matches(options::OPT_ggdb0)) {
2624264464Sdim      // Default is dwarf-2 for darwin and FreeBSD.
2625263984Sdim      const llvm::Triple &Triple = getToolChain().getTriple();
2626264464Sdim      if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::FreeBSD)
2627263508Sdim        CmdArgs.push_back("-gdwarf-2");
2628263508Sdim      else
2629263508Sdim        CmdArgs.push_back("-g");
2630263508Sdim    }
2631239462Sdim  }
2632193326Sed
2633239462Sdim  // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
2634239462Sdim  Args.ClaimAllArgs(options::OPT_g_flags_Group);
2635243830Sdim  if (Args.hasArg(options::OPT_gcolumn_info))
2636243830Sdim    CmdArgs.push_back("-dwarf-column-info");
2637239462Sdim
2638263508Sdim  // FIXME: Move backend command line options to the module.
2639249423Sdim  // -gsplit-dwarf should turn on -g and enable the backend dwarf
2640249423Sdim  // splitting and extraction.
2641249423Sdim  // FIXME: Currently only works on Linux.
2642263508Sdim  if (getToolChain().getTriple().isOSLinux() &&
2643249423Sdim      Args.hasArg(options::OPT_gsplit_dwarf)) {
2644249423Sdim    CmdArgs.push_back("-g");
2645249423Sdim    CmdArgs.push_back("-backend-option");
2646249423Sdim    CmdArgs.push_back("-split-dwarf=Enable");
2647249423Sdim  }
2648249423Sdim
2649263508Sdim  // -ggnu-pubnames turns on gnu style pubnames in the backend.
2650263508Sdim  if (Args.hasArg(options::OPT_ggnu_pubnames)) {
2651263508Sdim    CmdArgs.push_back("-backend-option");
2652263508Sdim    CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
2653263508Sdim  }
2654263508Sdim
2655263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fdebug_types_section);
2656263508Sdim
2657208600Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
2658208600Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
2659208600Srdivacky
2660210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
2661210299Sed
2662221345Sdim  if (Args.hasArg(options::OPT_ftest_coverage) ||
2663221345Sdim      Args.hasArg(options::OPT_coverage))
2664221345Sdim    CmdArgs.push_back("-femit-coverage-notes");
2665221345Sdim  if (Args.hasArg(options::OPT_fprofile_arcs) ||
2666221345Sdim      Args.hasArg(options::OPT_coverage))
2667221345Sdim    CmdArgs.push_back("-femit-coverage-data");
2668221345Sdim
2669223017Sdim  if (C.getArgs().hasArg(options::OPT_c) ||
2670223017Sdim      C.getArgs().hasArg(options::OPT_S)) {
2671223017Sdim    if (Output.isFilename()) {
2672223017Sdim      CmdArgs.push_back("-coverage-file");
2673249423Sdim      SmallString<128> CoverageFilename(Output.getFilename());
2674249423Sdim      if (llvm::sys::path::is_relative(CoverageFilename.str())) {
2675263508Sdim        SmallString<128> Pwd;
2676263508Sdim        if (!llvm::sys::fs::current_path(Pwd)) {
2677263508Sdim          llvm::sys::path::append(Pwd, CoverageFilename.str());
2678263508Sdim          CoverageFilename.swap(Pwd);
2679249423Sdim        }
2680249423Sdim      }
2681249423Sdim      CmdArgs.push_back(Args.MakeArgString(CoverageFilename));
2682223017Sdim    }
2683223017Sdim  }
2684223017Sdim
2685226633Sdim  // Pass options for controlling the default header search paths.
2686226633Sdim  if (Args.hasArg(options::OPT_nostdinc)) {
2687226633Sdim    CmdArgs.push_back("-nostdsysteminc");
2688226633Sdim    CmdArgs.push_back("-nobuiltininc");
2689226633Sdim  } else {
2690226633Sdim    if (Args.hasArg(options::OPT_nostdlibinc))
2691226633Sdim        CmdArgs.push_back("-nostdsysteminc");
2692226633Sdim    Args.AddLastArg(CmdArgs, options::OPT_nostdincxx);
2693226633Sdim    Args.AddLastArg(CmdArgs, options::OPT_nobuiltininc);
2694226633Sdim  }
2695193326Sed
2696200583Srdivacky  // Pass the path to compiler resource files.
2697200583Srdivacky  CmdArgs.push_back("-resource-dir");
2698202879Srdivacky  CmdArgs.push_back(D.ResourceDir.c_str());
2699193326Sed
2700218893Sdim  Args.AddLastArg(CmdArgs, options::OPT_working_directory);
2701218893Sdim
2702234353Sdim  bool ARCMTEnabled = false;
2703263508Sdim  if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) {
2704224145Sdim    if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
2705224145Sdim                                       options::OPT_ccc_arcmt_modify,
2706224145Sdim                                       options::OPT_ccc_arcmt_migrate)) {
2707234353Sdim      ARCMTEnabled = true;
2708224145Sdim      switch (A->getOption().getID()) {
2709224145Sdim      default:
2710224145Sdim        llvm_unreachable("missed a case");
2711224145Sdim      case options::OPT_ccc_arcmt_check:
2712224145Sdim        CmdArgs.push_back("-arcmt-check");
2713224145Sdim        break;
2714224145Sdim      case options::OPT_ccc_arcmt_modify:
2715224145Sdim        CmdArgs.push_back("-arcmt-modify");
2716224145Sdim        break;
2717224145Sdim      case options::OPT_ccc_arcmt_migrate:
2718224145Sdim        CmdArgs.push_back("-arcmt-migrate");
2719234353Sdim        CmdArgs.push_back("-mt-migrate-directory");
2720243830Sdim        CmdArgs.push_back(A->getValue());
2721226633Sdim
2722226633Sdim        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
2723226633Sdim        Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors);
2724224145Sdim        break;
2725224145Sdim      }
2726224145Sdim    }
2727263508Sdim  } else {
2728263508Sdim    Args.ClaimAllArgs(options::OPT_ccc_arcmt_check);
2729263508Sdim    Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify);
2730263508Sdim    Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate);
2731224145Sdim  }
2732226633Sdim
2733234353Sdim  if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
2734234353Sdim    if (ARCMTEnabled) {
2735234353Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
2736234353Sdim        << A->getAsString(Args) << "-ccc-arcmt-migrate";
2737234353Sdim    }
2738234353Sdim    CmdArgs.push_back("-mt-migrate-directory");
2739243830Sdim    CmdArgs.push_back(A->getValue());
2740234353Sdim
2741234353Sdim    if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
2742263508Sdim                     options::OPT_objcmt_migrate_subscripting,
2743263508Sdim                     options::OPT_objcmt_migrate_property)) {
2744234353Sdim      // None specified, means enable them all.
2745234353Sdim      CmdArgs.push_back("-objcmt-migrate-literals");
2746234353Sdim      CmdArgs.push_back("-objcmt-migrate-subscripting");
2747263508Sdim      CmdArgs.push_back("-objcmt-migrate-property");
2748234353Sdim    } else {
2749234353Sdim      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
2750234353Sdim      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
2751263508Sdim      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
2752234353Sdim    }
2753263508Sdim  } else {
2754263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
2755263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
2756263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property);
2757263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all);
2758263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property);
2759263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property);
2760263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation);
2761263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype);
2762263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros);
2763263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance);
2764263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property);
2765263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property);
2766263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly);
2767263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_objcmt_white_list_dir_path);
2768234353Sdim  }
2769234353Sdim
2770193326Sed  // Add preprocessing options like -I, -D, etc. if we are using the
2771193326Sed  // preprocessor.
2772193326Sed  //
2773193326Sed  // FIXME: Support -fpreprocessed
2774193326Sed  if (types::getPreprocessedType(InputType) != types::TY_INVALID)
2775249423Sdim    AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
2776193326Sed
2777226633Sdim  // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
2778226633Sdim  // that "The compiler can only warn and ignore the option if not recognized".
2779226633Sdim  // When building with ccache, it will pass -D options to clang even on
2780226633Sdim  // preprocessed inputs and configure concludes that -fPIC is not supported.
2781226633Sdim  Args.ClaimAllArgs(options::OPT_D);
2782226633Sdim
2783263508Sdim  // Manually translate -O4 to -O3; let clang reject others.
2784193326Sed  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
2785263508Sdim    if (A->getOption().matches(options::OPT_O4)) {
2786193326Sed      CmdArgs.push_back("-O3");
2787263508Sdim      D.Diag(diag::warn_O4_is_O3);
2788263508Sdim    } else {
2789193326Sed      A->render(Args, CmdArgs);
2790263508Sdim    }
2791193326Sed  }
2792193326Sed
2793249423Sdim  // Don't warn about unused -flto.  This can happen when we're preprocessing or
2794249423Sdim  // precompiling.
2795249423Sdim  Args.ClaimAllArgs(options::OPT_flto);
2796249423Sdim
2797198893Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_W_Group);
2798239462Sdim  if (Args.hasFlag(options::OPT_pedantic, options::OPT_no_pedantic, false))
2799239462Sdim    CmdArgs.push_back("-pedantic");
2800198893Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
2801193326Sed  Args.AddLastArg(CmdArgs, options::OPT_w);
2802193326Sed
2803193326Sed  // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
2804263508Sdim  // (-ansi is equivalent to -std=c89 or -std=c++98).
2805193326Sed  //
2806193326Sed  // If a std is supplied, only add -trigraphs if it follows the
2807193326Sed  // option.
2808193326Sed  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
2809193326Sed    if (Std->getOption().matches(options::OPT_ansi))
2810198398Srdivacky      if (types::isCXX(InputType))
2811198893Srdivacky        CmdArgs.push_back("-std=c++98");
2812198398Srdivacky      else
2813198893Srdivacky        CmdArgs.push_back("-std=c89");
2814193326Sed    else
2815193326Sed      Std->render(Args, CmdArgs);
2816193326Sed
2817210299Sed    if (Arg *A = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi,
2818210299Sed                                 options::OPT_trigraphs))
2819210299Sed      if (A != Std)
2820193326Sed        A->render(Args, CmdArgs);
2821193326Sed  } else {
2822193326Sed    // Honor -std-default.
2823203955Srdivacky    //
2824203955Srdivacky    // FIXME: Clang doesn't correctly handle -std= when the input language
2825203955Srdivacky    // doesn't match. For the time being just ignore this for C++ inputs;
2826203955Srdivacky    // eventually we want to do all the standard defaulting here instead of
2827203955Srdivacky    // splitting it between the driver and clang -cc1.
2828203955Srdivacky    if (!types::isCXX(InputType))
2829243830Sdim      Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
2830243830Sdim                                "-std=", /*Joined=*/true);
2831243830Sdim    else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32)
2832243830Sdim      CmdArgs.push_back("-std=c++11");
2833243830Sdim
2834193326Sed    Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
2835193326Sed  }
2836193326Sed
2837263508Sdim  // GCC's behavior for -Wwrite-strings is a bit strange:
2838263508Sdim  //  * In C, this "warning flag" changes the types of string literals from
2839263508Sdim  //    'char[N]' to 'const char[N]', and thus triggers an unrelated warning
2840263508Sdim  //    for the discarded qualifier.
2841263508Sdim  //  * In C++, this is just a normal warning flag.
2842263508Sdim  //
2843263508Sdim  // Implementing this warning correctly in C is hard, so we follow GCC's
2844263508Sdim  // behavior for now. FIXME: Directly diagnose uses of a string literal as
2845263508Sdim  // a non-const char* in C, rather than using this crude hack.
2846263508Sdim  if (!types::isCXX(InputType)) {
2847263508Sdim    DiagnosticsEngine::Level DiagLevel = D.getDiags().getDiagnosticLevel(
2848263508Sdim        diag::warn_deprecated_string_literal_conversion_c, SourceLocation());
2849263508Sdim    if (DiagLevel > DiagnosticsEngine::Ignored)
2850263508Sdim      CmdArgs.push_back("-fconst-strings");
2851221345Sdim  }
2852221345Sdim
2853221345Sdim  // GCC provides a macro definition '__DEPRECATED' when -Wdeprecated is active
2854221345Sdim  // during C++ compilation, which it is by default. GCC keeps this define even
2855221345Sdim  // in the presence of '-w', match this behavior bug-for-bug.
2856221345Sdim  if (types::isCXX(InputType) &&
2857221345Sdim      Args.hasFlag(options::OPT_Wdeprecated, options::OPT_Wno_deprecated,
2858221345Sdim                   true)) {
2859221345Sdim    CmdArgs.push_back("-fdeprecated-macro");
2860221345Sdim  }
2861221345Sdim
2862208600Srdivacky  // Translate GCC's misnamer '-fasm' arguments to '-fgnu-keywords'.
2863208600Srdivacky  if (Arg *Asm = Args.getLastArg(options::OPT_fasm, options::OPT_fno_asm)) {
2864208600Srdivacky    if (Asm->getOption().matches(options::OPT_fasm))
2865208600Srdivacky      CmdArgs.push_back("-fgnu-keywords");
2866208600Srdivacky    else
2867208600Srdivacky      CmdArgs.push_back("-fno-gnu-keywords");
2868208600Srdivacky  }
2869208600Srdivacky
2870221345Sdim  if (ShouldDisableCFI(Args, getToolChain()))
2871221345Sdim    CmdArgs.push_back("-fno-dwarf2-cfi-asm");
2872221345Sdim
2873234353Sdim  if (ShouldDisableDwarfDirectory(Args, getToolChain()))
2874234353Sdim    CmdArgs.push_back("-fno-dwarf-directory-asm");
2875234353Sdim
2876251662Sdim  if (ShouldDisableAutolink(Args, getToolChain()))
2877251662Sdim    CmdArgs.push_back("-fno-autolink");
2878251662Sdim
2879249423Sdim  // Add in -fdebug-compilation-dir if necessary.
2880249423Sdim  addDebugCompDirArg(Args, CmdArgs);
2881234353Sdim
2882234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
2883234353Sdim                               options::OPT_ftemplate_depth_EQ)) {
2884193326Sed    CmdArgs.push_back("-ftemplate-depth");
2885243830Sdim    CmdArgs.push_back(A->getValue());
2886193326Sed  }
2887193326Sed
2888263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_foperator_arrow_depth_EQ)) {
2889263508Sdim    CmdArgs.push_back("-foperator-arrow-depth");
2890263508Sdim    CmdArgs.push_back(A->getValue());
2891263508Sdim  }
2892263508Sdim
2893234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_depth_EQ)) {
2894234353Sdim    CmdArgs.push_back("-fconstexpr-depth");
2895243830Sdim    CmdArgs.push_back(A->getValue());
2896234353Sdim  }
2897234353Sdim
2898263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_steps_EQ)) {
2899263508Sdim    CmdArgs.push_back("-fconstexpr-steps");
2900263508Sdim    CmdArgs.push_back(A->getValue());
2901263508Sdim  }
2902263508Sdim
2903249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_fbracket_depth_EQ)) {
2904249423Sdim    CmdArgs.push_back("-fbracket-depth");
2905249423Sdim    CmdArgs.push_back(A->getValue());
2906249423Sdim  }
2907249423Sdim
2908218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_Wlarge_by_value_copy_EQ,
2909218893Sdim                               options::OPT_Wlarge_by_value_copy_def)) {
2910239462Sdim    if (A->getNumValues()) {
2911243830Sdim      StringRef bytes = A->getValue();
2912239462Sdim      CmdArgs.push_back(Args.MakeArgString("-Wlarge-by-value-copy=" + bytes));
2913239462Sdim    } else
2914239462Sdim      CmdArgs.push_back("-Wlarge-by-value-copy=64"); // default value
2915218893Sdim  }
2916218893Sdim
2917239462Sdim
2918243830Sdim  if (Args.hasArg(options::OPT_relocatable_pch))
2919199990Srdivacky    CmdArgs.push_back("-relocatable-pch");
2920198092Srdivacky
2921198893Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
2922198893Srdivacky    CmdArgs.push_back("-fconstant-string-class");
2923243830Sdim    CmdArgs.push_back(A->getValue());
2924198893Srdivacky  }
2925198092Srdivacky
2926202379Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_ftabstop_EQ)) {
2927202379Srdivacky    CmdArgs.push_back("-ftabstop");
2928243830Sdim    CmdArgs.push_back(A->getValue());
2929202379Srdivacky  }
2930202379Srdivacky
2931207619Srdivacky  CmdArgs.push_back("-ferror-limit");
2932207619Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_ferror_limit_EQ))
2933243830Sdim    CmdArgs.push_back(A->getValue());
2934207619Srdivacky  else
2935207619Srdivacky    CmdArgs.push_back("19");
2936207619Srdivacky
2937208600Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fmacro_backtrace_limit_EQ)) {
2938208600Srdivacky    CmdArgs.push_back("-fmacro-backtrace-limit");
2939243830Sdim    CmdArgs.push_back(A->getValue());
2940208600Srdivacky  }
2941208600Srdivacky
2942208600Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_ftemplate_backtrace_limit_EQ)) {
2943208600Srdivacky    CmdArgs.push_back("-ftemplate-backtrace-limit");
2944243830Sdim    CmdArgs.push_back(A->getValue());
2945208600Srdivacky  }
2946208600Srdivacky
2947234353Sdim  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
2948234353Sdim    CmdArgs.push_back("-fconstexpr-backtrace-limit");
2949243830Sdim    CmdArgs.push_back(A->getValue());
2950234353Sdim  }
2951234353Sdim
2952198893Srdivacky  // Pass -fmessage-length=.
2953199990Srdivacky  CmdArgs.push_back("-fmessage-length");
2954198893Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {
2955243830Sdim    CmdArgs.push_back(A->getValue());
2956198893Srdivacky  } else {
2957198893Srdivacky    // If -fmessage-length=N was not specified, determine whether this is a
2958198893Srdivacky    // terminal and, if so, implicitly define -fmessage-length appropriately.
2959198893Srdivacky    unsigned N = llvm::sys::Process::StandardErrColumns();
2960226633Sdim    CmdArgs.push_back(Args.MakeArgString(Twine(N)));
2961198893Srdivacky  }
2962198893Srdivacky
2963249423Sdim  // -fvisibility= and -fvisibility-ms-compat are of a piece.
2964249423Sdim  if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ,
2965249423Sdim                                     options::OPT_fvisibility_ms_compat)) {
2966249423Sdim    if (A->getOption().matches(options::OPT_fvisibility_EQ)) {
2967249423Sdim      CmdArgs.push_back("-fvisibility");
2968249423Sdim      CmdArgs.push_back(A->getValue());
2969249423Sdim    } else {
2970249423Sdim      assert(A->getOption().matches(options::OPT_fvisibility_ms_compat));
2971249423Sdim      CmdArgs.push_back("-fvisibility");
2972249423Sdim      CmdArgs.push_back("hidden");
2973249423Sdim      CmdArgs.push_back("-ftype-visibility");
2974249423Sdim      CmdArgs.push_back("default");
2975249423Sdim    }
2976200583Srdivacky  }
2977200583Srdivacky
2978210299Sed  Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
2979218893Sdim
2980239462Sdim  Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
2981239462Sdim
2982205408Srdivacky  // -fhosted is default.
2983234353Sdim  if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
2984234353Sdim      KernelOrKext)
2985205408Srdivacky    CmdArgs.push_back("-ffreestanding");
2986205408Srdivacky
2987200583Srdivacky  // Forward -f (flag) options which we can pass directly.
2988193326Sed  Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
2989218893Sdim  Args.AddLastArg(CmdArgs, options::OPT_fformat_extensions);
2990193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
2991269011Semaste  Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
2992269011Semaste  Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
2993234353Sdim  Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
2994263508Sdim  // AltiVec language extensions aren't relevant for assembling.
2995263508Sdim  if (!isa<PreprocessJobAction>(JA) ||
2996263508Sdim      Output.getType() != types::TY_PP_Asm)
2997263508Sdim    Args.AddLastArg(CmdArgs, options::OPT_faltivec);
2998239462Sdim  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
2999239462Sdim  Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
3000234353Sdim
3001263508Sdim  const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
3002243830Sdim  Sanitize.addArgs(Args, CmdArgs);
3003243830Sdim
3004249423Sdim  if (!Args.hasFlag(options::OPT_fsanitize_recover,
3005249423Sdim                    options::OPT_fno_sanitize_recover,
3006249423Sdim                    true))
3007249423Sdim    CmdArgs.push_back("-fno-sanitize-recover");
3008249423Sdim
3009249423Sdim  if (Args.hasArg(options::OPT_fcatch_undefined_behavior) ||
3010249423Sdim      Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
3011249423Sdim                   options::OPT_fno_sanitize_undefined_trap_on_error, false))
3012249423Sdim    CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
3013249423Sdim
3014249423Sdim  // Report an error for -faltivec on anything other than PowerPC.
3015234353Sdim  if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
3016263508Sdim    if (!(getToolChain().getArch() == llvm::Triple::ppc ||
3017263508Sdim          getToolChain().getArch() == llvm::Triple::ppc64 ||
3018263508Sdim          getToolChain().getArch() == llvm::Triple::ppc64le))
3019234353Sdim      D.Diag(diag::err_drv_argument_only_allowed_with)
3020263508Sdim        << A->getAsString(Args) << "ppc/ppc64/ppc64le";
3021234353Sdim
3022221345Sdim  if (getToolChain().SupportsProfiling())
3023221345Sdim    Args.AddLastArg(CmdArgs, options::OPT_pg);
3024205408Srdivacky
3025205408Srdivacky  // -flax-vector-conversions is default.
3026205408Srdivacky  if (!Args.hasFlag(options::OPT_flax_vector_conversions,
3027205408Srdivacky                    options::OPT_fno_lax_vector_conversions))
3028205408Srdivacky    CmdArgs.push_back("-fno-lax-vector-conversions");
3029205408Srdivacky
3030218893Sdim  if (Args.getLastArg(options::OPT_fapple_kext))
3031218893Sdim    CmdArgs.push_back("-fapple-kext");
3032218893Sdim
3033239462Sdim  if (Args.hasFlag(options::OPT_frewrite_includes,
3034239462Sdim                   options::OPT_fno_rewrite_includes, false))
3035239462Sdim    CmdArgs.push_back("-frewrite-includes");
3036239462Sdim
3037193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
3038193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
3039212904Sdim  Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
3040193326Sed  Args.AddLastArg(CmdArgs, options::OPT_ftime_report);
3041193326Sed  Args.AddLastArg(CmdArgs, options::OPT_ftrapv);
3042218893Sdim
3043218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) {
3044218893Sdim    CmdArgs.push_back("-ftrapv-handler");
3045243830Sdim    CmdArgs.push_back(A->getValue());
3046218893Sdim  }
3047218893Sdim
3048234353Sdim  Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);
3049221345Sdim
3050221345Sdim  // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
3051221345Sdim  // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
3052221345Sdim  if (Arg *A = Args.getLastArg(options::OPT_fwrapv,
3053221345Sdim                               options::OPT_fno_wrapv)) {
3054221345Sdim    if (A->getOption().matches(options::OPT_fwrapv))
3055221345Sdim      CmdArgs.push_back("-fwrapv");
3056221345Sdim  } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
3057221345Sdim                                      options::OPT_fno_strict_overflow)) {
3058221345Sdim    if (A->getOption().matches(options::OPT_fno_strict_overflow))
3059221345Sdim      CmdArgs.push_back("-fwrapv");
3060221345Sdim  }
3061263508Sdim
3062263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_freroll_loops,
3063263508Sdim                               options::OPT_fno_reroll_loops))
3064263508Sdim    if (A->getOption().matches(options::OPT_freroll_loops))
3065263508Sdim      CmdArgs.push_back("-freroll-loops");
3066263508Sdim
3067193326Sed  Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
3068263508Sdim  Args.AddLastArg(CmdArgs, options::OPT_funroll_loops,
3069263508Sdim                  options::OPT_fno_unroll_loops);
3070193326Sed
3071198092Srdivacky  Args.AddLastArg(CmdArgs, options::OPT_pthread);
3072198092Srdivacky
3073243830Sdim
3074199482Srdivacky  // -stack-protector=0 is default.
3075199482Srdivacky  unsigned StackProtectorLevel = 0;
3076195341Sed  if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
3077195341Sed                               options::OPT_fstack_protector_all,
3078195341Sed                               options::OPT_fstack_protector)) {
3079199482Srdivacky    if (A->getOption().matches(options::OPT_fstack_protector))
3080199482Srdivacky      StackProtectorLevel = 1;
3081199482Srdivacky    else if (A->getOption().matches(options::OPT_fstack_protector_all))
3082199482Srdivacky      StackProtectorLevel = 2;
3083226633Sdim  } else {
3084226633Sdim    StackProtectorLevel =
3085226633Sdim      getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
3086226633Sdim  }
3087199482Srdivacky  if (StackProtectorLevel) {
3088199482Srdivacky    CmdArgs.push_back("-stack-protector");
3089226633Sdim    CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
3090195341Sed  }
3091195341Sed
3092243830Sdim  // --param ssp-buffer-size=
3093243830Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT__param),
3094243830Sdim       ie = Args.filtered_end(); it != ie; ++it) {
3095243830Sdim    StringRef Str((*it)->getValue());
3096243830Sdim    if (Str.startswith("ssp-buffer-size=")) {
3097243830Sdim      if (StackProtectorLevel) {
3098243830Sdim        CmdArgs.push_back("-stack-protector-buffer-size");
3099243830Sdim        // FIXME: Verify the argument is a valid integer.
3100243830Sdim        CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
3101243830Sdim      }
3102243830Sdim      (*it)->claim();
3103243830Sdim    }
3104243830Sdim  }
3105243830Sdim
3106223017Sdim  // Translate -mstackrealign
3107234353Sdim  if (Args.hasFlag(options::OPT_mstackrealign, options::OPT_mno_stackrealign,
3108234353Sdim                   false)) {
3109223017Sdim    CmdArgs.push_back("-backend-option");
3110223017Sdim    CmdArgs.push_back("-force-align-stack");
3111223017Sdim  }
3112234353Sdim  if (!Args.hasFlag(options::OPT_mno_stackrealign, options::OPT_mstackrealign,
3113234353Sdim                   false)) {
3114234353Sdim    CmdArgs.push_back(Args.MakeArgString("-mstackrealign"));
3115234353Sdim  }
3116226633Sdim
3117234353Sdim  if (Args.hasArg(options::OPT_mstack_alignment)) {
3118234353Sdim    StringRef alignment = Args.getLastArgValue(options::OPT_mstack_alignment);
3119234353Sdim    CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));
3120234353Sdim  }
3121249423Sdim  // -mkernel implies -mstrict-align; don't add the redundant option.
3122263508Sdim  if (!KernelOrKext) {
3123263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
3124263508Sdim                                 options::OPT_munaligned_access)) {
3125263508Sdim      if (A->getOption().matches(options::OPT_mno_unaligned_access)) {
3126263508Sdim        CmdArgs.push_back("-backend-option");
3127263508Sdim        CmdArgs.push_back("-arm-strict-align");
3128263508Sdim      } else {
3129263508Sdim        CmdArgs.push_back("-backend-option");
3130263508Sdim        CmdArgs.push_back("-arm-no-strict-align");
3131263508Sdim      }
3132263508Sdim    }
3133243830Sdim  }
3134234353Sdim
3135263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,
3136263508Sdim                               options::OPT_mno_restrict_it)) {
3137263508Sdim    if (A->getOption().matches(options::OPT_mrestrict_it)) {
3138263508Sdim      CmdArgs.push_back("-backend-option");
3139263508Sdim      CmdArgs.push_back("-arm-restrict-it");
3140263508Sdim    } else {
3141263508Sdim      CmdArgs.push_back("-backend-option");
3142263508Sdim      CmdArgs.push_back("-arm-no-restrict-it");
3143263508Sdim    }
3144263508Sdim  }
3145263508Sdim
3146193326Sed  // Forward -f options with positive and negative forms; we translate
3147193326Sed  // these by hand.
3148263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fprofile_sample_use_EQ)) {
3149263508Sdim    StringRef fname = A->getValue();
3150263508Sdim    if (!llvm::sys::fs::exists(fname))
3151263508Sdim      D.Diag(diag::err_drv_no_such_file) << fname;
3152263508Sdim    else
3153263508Sdim      A->render(Args, CmdArgs);
3154263508Sdim  }
3155193326Sed
3156218893Sdim  if (Args.hasArg(options::OPT_mkernel)) {
3157218893Sdim    if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
3158218893Sdim      CmdArgs.push_back("-fapple-kext");
3159218893Sdim    if (!Args.hasArg(options::OPT_fbuiltin))
3160218893Sdim      CmdArgs.push_back("-fno-builtin");
3161234353Sdim    Args.ClaimAllArgs(options::OPT_fno_builtin);
3162218893Sdim  }
3163199482Srdivacky  // -fbuiltin is default.
3164218893Sdim  else if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
3165199512Srdivacky    CmdArgs.push_back("-fno-builtin");
3166193326Sed
3167201361Srdivacky  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
3168201361Srdivacky                    options::OPT_fno_assume_sane_operator_new))
3169201361Srdivacky    CmdArgs.push_back("-fno-assume-sane-operator-new");
3170201361Srdivacky
3171199482Srdivacky  // -fblocks=0 is default.
3172199482Srdivacky  if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
3173221345Sdim                   getToolChain().IsBlocksDefault()) ||
3174221345Sdim        (Args.hasArg(options::OPT_fgnu_runtime) &&
3175221345Sdim         Args.hasArg(options::OPT_fobjc_nonfragile_abi) &&
3176221345Sdim         !Args.hasArg(options::OPT_fno_blocks))) {
3177199482Srdivacky    CmdArgs.push_back("-fblocks");
3178226633Sdim
3179226633Sdim    if (!Args.hasArg(options::OPT_fgnu_runtime) &&
3180226633Sdim        !getToolChain().hasBlocksRuntime())
3181226633Sdim      CmdArgs.push_back("-fblocks-runtime-optional");
3182193326Sed  }
3183193326Sed
3184234353Sdim  // -fmodules enables modules (off by default). However, for C++/Objective-C++,
3185234353Sdim  // users must also pass -fcxx-modules. The latter flag will disappear once the
3186234353Sdim  // modules implementation is solid for C++/Objective-C++ programs as well.
3187249423Sdim  bool HaveModules = false;
3188234353Sdim  if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
3189234353Sdim    bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
3190234353Sdim                                     options::OPT_fno_cxx_modules,
3191234353Sdim                                     false);
3192249423Sdim    if (AllowedInCXX || !types::isCXX(InputType)) {
3193234353Sdim      CmdArgs.push_back("-fmodules");
3194249423Sdim      HaveModules = true;
3195249423Sdim    }
3196234353Sdim  }
3197234353Sdim
3198263508Sdim  // -fmodule-maps enables module map processing (off by default) for header
3199263508Sdim  // checking.  It is implied by -fmodules.
3200263508Sdim  if (Args.hasFlag(options::OPT_fmodule_maps, options::OPT_fno_module_maps,
3201263508Sdim                   false)) {
3202263508Sdim    CmdArgs.push_back("-fmodule-maps");
3203263508Sdim  }
3204263508Sdim
3205263508Sdim  // -fmodules-decluse checks that modules used are declared so (off by
3206263508Sdim  // default).
3207263508Sdim  if (Args.hasFlag(options::OPT_fmodules_decluse,
3208263508Sdim                   options::OPT_fno_modules_decluse,
3209263508Sdim                   false)) {
3210263508Sdim    CmdArgs.push_back("-fmodules-decluse");
3211263508Sdim  }
3212263508Sdim
3213263508Sdim  // -fmodule-name specifies the module that is currently being built (or
3214263508Sdim  // used for header checking by -fmodule-maps).
3215263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) {
3216263508Sdim    A->claim();
3217263508Sdim    A->render(Args, CmdArgs);
3218263508Sdim  }
3219263508Sdim
3220263508Sdim  // -fmodule-map-file can be used to specify a file containing module
3221263508Sdim  // definitions.
3222263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) {
3223263508Sdim    A->claim();
3224263508Sdim    A->render(Args, CmdArgs);
3225263508Sdim  }
3226263508Sdim
3227249423Sdim  // If a module path was provided, pass it along. Otherwise, use a temporary
3228249423Sdim  // directory.
3229249423Sdim  if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) {
3230249423Sdim    A->claim();
3231249423Sdim    if (HaveModules) {
3232249423Sdim      A->render(Args, CmdArgs);
3233249423Sdim    }
3234249423Sdim  } else if (HaveModules) {
3235249423Sdim    SmallString<128> DefaultModuleCache;
3236249423Sdim    llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
3237249423Sdim                                           DefaultModuleCache);
3238249423Sdim    llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
3239249423Sdim    llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
3240249423Sdim    const char Arg[] = "-fmodules-cache-path=";
3241249423Sdim    DefaultModuleCache.insert(DefaultModuleCache.begin(),
3242249423Sdim                              Arg, Arg + strlen(Arg));
3243249423Sdim    CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
3244249423Sdim  }
3245249423Sdim
3246249423Sdim  // Pass through all -fmodules-ignore-macro arguments.
3247249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
3248249423Sdim  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
3249249423Sdim  Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
3250249423Sdim
3251207619Srdivacky  // -faccess-control is default.
3252207619Srdivacky  if (Args.hasFlag(options::OPT_fno_access_control,
3253207619Srdivacky                   options::OPT_faccess_control,
3254205408Srdivacky                   false))
3255207619Srdivacky    CmdArgs.push_back("-fno-access-control");
3256205408Srdivacky
3257218893Sdim  // -felide-constructors is the default.
3258218893Sdim  if (Args.hasFlag(options::OPT_fno_elide_constructors,
3259218893Sdim                   options::OPT_felide_constructors,
3260218893Sdim                   false))
3261218893Sdim    CmdArgs.push_back("-fno-elide-constructors");
3262218893Sdim
3263199482Srdivacky  // -frtti is default.
3264234353Sdim  if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti) ||
3265243830Sdim      KernelOrKext) {
3266199512Srdivacky    CmdArgs.push_back("-fno-rtti");
3267198092Srdivacky
3268243830Sdim    // -fno-rtti cannot usefully be combined with -fsanitize=vptr.
3269243830Sdim    if (Sanitize.sanitizesVptr()) {
3270243830Sdim      std::string NoRttiArg =
3271243830Sdim        Args.getLastArg(options::OPT_mkernel,
3272243830Sdim                        options::OPT_fapple_kext,
3273243830Sdim                        options::OPT_fno_rtti)->getAsString(Args);
3274243830Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
3275243830Sdim        << "-fsanitize=vptr" << NoRttiArg;
3276243830Sdim    }
3277243830Sdim  }
3278243830Sdim
3279234353Sdim  // -fshort-enums=0 is default for all architectures except Hexagon.
3280218893Sdim  if (Args.hasFlag(options::OPT_fshort_enums,
3281234353Sdim                   options::OPT_fno_short_enums,
3282263508Sdim                   getToolChain().getArch() ==
3283234353Sdim                   llvm::Triple::hexagon))
3284218893Sdim    CmdArgs.push_back("-fshort-enums");
3285218893Sdim
3286199482Srdivacky  // -fsigned-char is default.
3287199990Srdivacky  if (!Args.hasFlag(options::OPT_fsigned_char, options::OPT_funsigned_char,
3288199482Srdivacky                    isSignedCharDefault(getToolChain().getTriple())))
3289199990Srdivacky    CmdArgs.push_back("-fno-signed-char");
3290199482Srdivacky
3291203955Srdivacky  // -fthreadsafe-static is default.
3292218893Sdim  if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
3293203955Srdivacky                    options::OPT_fno_threadsafe_statics))
3294203955Srdivacky    CmdArgs.push_back("-fno-threadsafe-statics");
3295203955Srdivacky
3296205408Srdivacky  // -fuse-cxa-atexit is default.
3297263508Sdim  if (!Args.hasFlag(
3298263508Sdim           options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
3299263508Sdim           getToolChain().getTriple().getOS() != llvm::Triple::Cygwin &&
3300263508Sdim               getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 &&
3301263508Sdim               getToolChain().getArch() != llvm::Triple::hexagon &&
3302263508Sdim               getToolChain().getArch() != llvm::Triple::xcore) ||
3303234353Sdim      KernelOrKext)
3304205408Srdivacky    CmdArgs.push_back("-fno-use-cxa-atexit");
3305205408Srdivacky
3306199482Srdivacky  // -fms-extensions=0 is default.
3307199990Srdivacky  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
3308199482Srdivacky                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
3309199482Srdivacky    CmdArgs.push_back("-fms-extensions");
3310199482Srdivacky
3311226633Sdim  // -fms-compatibility=0 is default.
3312234353Sdim  if (Args.hasFlag(options::OPT_fms_compatibility,
3313234353Sdim                   options::OPT_fno_ms_compatibility,
3314234353Sdim                   (getToolChain().getTriple().getOS() == llvm::Triple::Win32 &&
3315234353Sdim                    Args.hasFlag(options::OPT_fms_extensions,
3316234353Sdim                                 options::OPT_fno_ms_extensions,
3317234353Sdim                                 true))))
3318226633Sdim    CmdArgs.push_back("-fms-compatibility");
3319226633Sdim
3320263508Sdim  // -fmsc-version=1700 is default.
3321218893Sdim  if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
3322218893Sdim                   getToolChain().getTriple().getOS() == llvm::Triple::Win32) ||
3323218893Sdim      Args.hasArg(options::OPT_fmsc_version)) {
3324226633Sdim    StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version);
3325218893Sdim    if (msc_ver.empty())
3326263508Sdim      CmdArgs.push_back("-fmsc-version=1700");
3327218893Sdim    else
3328218893Sdim      CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver));
3329218893Sdim  }
3330218893Sdim
3331218893Sdim
3332249423Sdim  // -fno-borland-extensions is default.
3333212904Sdim  if (Args.hasFlag(options::OPT_fborland_extensions,
3334212904Sdim                   options::OPT_fno_borland_extensions, false))
3335212904Sdim    CmdArgs.push_back("-fborland-extensions");
3336212904Sdim
3337226633Sdim  // -fno-delayed-template-parsing is default, except for Windows where MSVC STL
3338226633Sdim  // needs it.
3339221345Sdim  if (Args.hasFlag(options::OPT_fdelayed_template_parsing,
3340221345Sdim                   options::OPT_fno_delayed_template_parsing,
3341226633Sdim                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
3342221345Sdim    CmdArgs.push_back("-fdelayed-template-parsing");
3343221345Sdim
3344207619Srdivacky  // -fgnu-keywords default varies depending on language; only pass if
3345207619Srdivacky  // specified.
3346207619Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords,
3347207619Srdivacky                               options::OPT_fno_gnu_keywords))
3348207619Srdivacky    A->render(Args, CmdArgs);
3349207619Srdivacky
3350223017Sdim  if (Args.hasFlag(options::OPT_fgnu89_inline,
3351223017Sdim                   options::OPT_fno_gnu89_inline,
3352223017Sdim                   false))
3353223017Sdim    CmdArgs.push_back("-fgnu89-inline");
3354223017Sdim
3355234353Sdim  if (Args.hasArg(options::OPT_fno_inline))
3356234353Sdim    CmdArgs.push_back("-fno-inline");
3357234353Sdim
3358234353Sdim  if (Args.hasArg(options::OPT_fno_inline_functions))
3359234353Sdim    CmdArgs.push_back("-fno-inline-functions");
3360234353Sdim
3361239462Sdim  ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
3362224145Sdim
3363239462Sdim  // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
3364263508Sdim  // legacy is the default. Next runtime is always legacy dispatch and
3365263508Sdim  // -fno-objc-legacy-dispatch gets ignored silently.
3366263508Sdim  if (objcRuntime.isNonFragile() && !objcRuntime.isNeXTFamily()) {
3367226633Sdim    if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
3368226633Sdim                      options::OPT_fno_objc_legacy_dispatch,
3369239462Sdim                      objcRuntime.isLegacyDispatchDefaultForArch(
3370263508Sdim                        getToolChain().getArch()))) {
3371226633Sdim      if (getToolChain().UseObjCMixedDispatch())
3372226633Sdim        CmdArgs.push_back("-fobjc-dispatch-method=mixed");
3373226633Sdim      else
3374226633Sdim        CmdArgs.push_back("-fobjc-dispatch-method=non-legacy");
3375218893Sdim    }
3376199482Srdivacky  }
3377199482Srdivacky
3378263508Sdim  // When ObjectiveC legacy runtime is in effect on MacOSX,
3379263508Sdim  // turn on the option to do Array/Dictionary subscripting
3380263508Sdim  // by default.
3381263508Sdim  if (getToolChain().getTriple().getArch() == llvm::Triple::x86 &&
3382263508Sdim      getToolChain().getTriple().isMacOSX() &&
3383263508Sdim      !getToolChain().getTriple().isMacOSXVersionLT(10, 7) &&
3384263508Sdim      objcRuntime.getKind() == ObjCRuntime::FragileMacOSX &&
3385263508Sdim      objcRuntime.isNeXTFamily())
3386263508Sdim    CmdArgs.push_back("-fobjc-subscripting-legacy-runtime");
3387263508Sdim
3388243830Sdim  // -fencode-extended-block-signature=1 is default.
3389243830Sdim  if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) {
3390243830Sdim    CmdArgs.push_back("-fencode-extended-block-signature");
3391243830Sdim  }
3392243830Sdim
3393224145Sdim  // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc.
3394224145Sdim  // NOTE: This logic is duplicated in ToolChains.cpp.
3395224145Sdim  bool ARC = isObjCAutoRefCount(Args);
3396224145Sdim  if (ARC) {
3397243830Sdim    getToolChain().CheckObjCARC();
3398234353Sdim
3399224145Sdim    CmdArgs.push_back("-fobjc-arc");
3400224145Sdim
3401228379Sdim    // FIXME: It seems like this entire block, and several around it should be
3402228379Sdim    // wrapped in isObjC, but for now we just use it here as this is where it
3403228379Sdim    // was being used previously.
3404228379Sdim    if (types::isCXX(InputType) && types::isObjC(InputType)) {
3405228379Sdim      if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
3406228379Sdim        CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
3407228379Sdim      else
3408228379Sdim        CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
3409228379Sdim    }
3410228379Sdim
3411224145Sdim    // Allow the user to enable full exceptions code emission.
3412224145Sdim    // We define off for Objective-CC, on for Objective-C++.
3413224145Sdim    if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,
3414224145Sdim                     options::OPT_fno_objc_arc_exceptions,
3415224145Sdim                     /*default*/ types::isCXX(InputType)))
3416224145Sdim      CmdArgs.push_back("-fobjc-arc-exceptions");
3417224145Sdim  }
3418224145Sdim
3419224145Sdim  // -fobjc-infer-related-result-type is the default, except in the Objective-C
3420224145Sdim  // rewriter.
3421239462Sdim  if (rewriteKind != RK_None)
3422224145Sdim    CmdArgs.push_back("-fno-objc-infer-related-result-type");
3423226633Sdim
3424224145Sdim  // Handle -fobjc-gc and -fobjc-gc-only. They are exclusive, and -fobjc-gc-only
3425224145Sdim  // takes precedence.
3426224145Sdim  const Arg *GCArg = Args.getLastArg(options::OPT_fobjc_gc_only);
3427224145Sdim  if (!GCArg)
3428224145Sdim    GCArg = Args.getLastArg(options::OPT_fobjc_gc);
3429224145Sdim  if (GCArg) {
3430224145Sdim    if (ARC) {
3431226633Sdim      D.Diag(diag::err_drv_objc_gc_arr)
3432224145Sdim        << GCArg->getAsString(Args);
3433224145Sdim    } else if (getToolChain().SupportsObjCGC()) {
3434224145Sdim      GCArg->render(Args, CmdArgs);
3435224145Sdim    } else {
3436224145Sdim      // FIXME: We should move this to a hard error.
3437226633Sdim      D.Diag(diag::warn_drv_objc_gc_unsupported)
3438224145Sdim        << GCArg->getAsString(Args);
3439224145Sdim    }
3440224145Sdim  }
3441224145Sdim
3442224145Sdim  // Add exception args.
3443224145Sdim  addExceptionArgs(Args, InputType, getToolChain().getTriple(),
3444239462Sdim                   KernelOrKext, objcRuntime, CmdArgs);
3445224145Sdim
3446224145Sdim  if (getToolChain().UseSjLjExceptions())
3447224145Sdim    CmdArgs.push_back("-fsjlj-exceptions");
3448224145Sdim
3449224145Sdim  // C++ "sane" operator new.
3450203955Srdivacky  if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
3451203955Srdivacky                    options::OPT_fno_assume_sane_operator_new))
3452203955Srdivacky    CmdArgs.push_back("-fno-assume-sane-operator-new");
3453203955Srdivacky
3454207619Srdivacky  // -fconstant-cfstrings is default, and may be subject to argument translation
3455207619Srdivacky  // on Darwin.
3456207619Srdivacky  if (!Args.hasFlag(options::OPT_fconstant_cfstrings,
3457207619Srdivacky                    options::OPT_fno_constant_cfstrings) ||
3458207619Srdivacky      !Args.hasFlag(options::OPT_mconstant_cfstrings,
3459207619Srdivacky                    options::OPT_mno_constant_cfstrings))
3460207619Srdivacky    CmdArgs.push_back("-fno-constant-cfstrings");
3461207619Srdivacky
3462199482Srdivacky  // -fshort-wchar default varies depending on platform; only
3463193576Sed  // pass if specified.
3464207619Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar))
3465207619Srdivacky    A->render(Args, CmdArgs);
3466193576Sed
3467263508Sdim  // -fno-pascal-strings is default, only pass non-default.
3468193326Sed  if (Args.hasFlag(options::OPT_fpascal_strings,
3469193326Sed                   options::OPT_fno_pascal_strings,
3470193326Sed                   false))
3471193326Sed    CmdArgs.push_back("-fpascal-strings");
3472193326Sed
3473226633Sdim  // Honor -fpack-struct= and -fpack-struct, if given. Note that
3474226633Sdim  // -fno-pack-struct doesn't apply to -fpack-struct=.
3475226633Sdim  if (Arg *A = Args.getLastArg(options::OPT_fpack_struct_EQ)) {
3476239462Sdim    std::string PackStructStr = "-fpack-struct=";
3477243830Sdim    PackStructStr += A->getValue();
3478239462Sdim    CmdArgs.push_back(Args.MakeArgString(PackStructStr));
3479226633Sdim  } else if (Args.hasFlag(options::OPT_fpack_struct,
3480226633Sdim                          options::OPT_fno_pack_struct, false)) {
3481239462Sdim    CmdArgs.push_back("-fpack-struct=1");
3482226633Sdim  }
3483226633Sdim
3484263508Sdim  if (KernelOrKext || isNoCommonDefault(getToolChain().getTriple())) {
3485218893Sdim    if (!Args.hasArg(options::OPT_fcommon))
3486218893Sdim      CmdArgs.push_back("-fno-common");
3487234353Sdim    Args.ClaimAllArgs(options::OPT_fno_common);
3488218893Sdim  }
3489226633Sdim
3490193326Sed  // -fcommon is default, only pass non-default.
3491218893Sdim  else if (!Args.hasFlag(options::OPT_fcommon, options::OPT_fno_common))
3492193326Sed    CmdArgs.push_back("-fno-common");
3493193326Sed
3494193326Sed  // -fsigned-bitfields is default, and clang doesn't yet support
3495218893Sdim  // -funsigned-bitfields.
3496198092Srdivacky  if (!Args.hasFlag(options::OPT_fsigned_bitfields,
3497193326Sed                    options::OPT_funsigned_bitfields))
3498226633Sdim    D.Diag(diag::warn_drv_clang_unsupported)
3499193326Sed      << Args.getLastArg(options::OPT_funsigned_bitfields)->getAsString(Args);
3500193326Sed
3501218893Sdim  // -fsigned-bitfields is default, and clang doesn't support -fno-for-scope.
3502218893Sdim  if (!Args.hasFlag(options::OPT_ffor_scope,
3503218893Sdim                    options::OPT_fno_for_scope))
3504226633Sdim    D.Diag(diag::err_drv_clang_unsupported)
3505218893Sdim      << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
3506218893Sdim
3507210299Sed  // -fcaret-diagnostics is default.
3508210299Sed  if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
3509210299Sed                    options::OPT_fno_caret_diagnostics, true))
3510210299Sed    CmdArgs.push_back("-fno-caret-diagnostics");
3511210299Sed
3512193326Sed  // -fdiagnostics-fixit-info is default, only pass non-default.
3513198092Srdivacky  if (!Args.hasFlag(options::OPT_fdiagnostics_fixit_info,
3514193326Sed                    options::OPT_fno_diagnostics_fixit_info))
3515193326Sed    CmdArgs.push_back("-fno-diagnostics-fixit-info");
3516226633Sdim
3517193326Sed  // Enable -fdiagnostics-show-option by default.
3518198092Srdivacky  if (Args.hasFlag(options::OPT_fdiagnostics_show_option,
3519193326Sed                   options::OPT_fno_diagnostics_show_option))
3520193326Sed    CmdArgs.push_back("-fdiagnostics-show-option");
3521198893Srdivacky
3522208600Srdivacky  if (const Arg *A =
3523208600Srdivacky        Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) {
3524208600Srdivacky    CmdArgs.push_back("-fdiagnostics-show-category");
3525243830Sdim    CmdArgs.push_back(A->getValue());
3526208600Srdivacky  }
3527212904Sdim
3528223017Sdim  if (const Arg *A =
3529223017Sdim        Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) {
3530223017Sdim    CmdArgs.push_back("-fdiagnostics-format");
3531243830Sdim    CmdArgs.push_back(A->getValue());
3532223017Sdim  }
3533223017Sdim
3534221345Sdim  if (Arg *A = Args.getLastArg(
3535221345Sdim      options::OPT_fdiagnostics_show_note_include_stack,
3536221345Sdim      options::OPT_fno_diagnostics_show_note_include_stack)) {
3537221345Sdim    if (A->getOption().matches(
3538221345Sdim        options::OPT_fdiagnostics_show_note_include_stack))
3539221345Sdim      CmdArgs.push_back("-fdiagnostics-show-note-include-stack");
3540221345Sdim    else
3541221345Sdim      CmdArgs.push_back("-fno-diagnostics-show-note-include-stack");
3542221345Sdim  }
3543221345Sdim
3544198893Srdivacky  // Color diagnostics are the default, unless the terminal doesn't support
3545198893Srdivacky  // them.
3546251662Sdim  // Support both clang's -f[no-]color-diagnostics and gcc's
3547251662Sdim  // -f[no-]diagnostics-colors[=never|always|auto].
3548251662Sdim  enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
3549251662Sdim  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
3550251662Sdim       it != ie; ++it) {
3551251662Sdim    const Option &O = (*it)->getOption();
3552251662Sdim    if (!O.matches(options::OPT_fcolor_diagnostics) &&
3553251662Sdim        !O.matches(options::OPT_fdiagnostics_color) &&
3554251662Sdim        !O.matches(options::OPT_fno_color_diagnostics) &&
3555251662Sdim        !O.matches(options::OPT_fno_diagnostics_color) &&
3556251662Sdim        !O.matches(options::OPT_fdiagnostics_color_EQ))
3557251662Sdim      continue;
3558251662Sdim
3559251662Sdim    (*it)->claim();
3560251662Sdim    if (O.matches(options::OPT_fcolor_diagnostics) ||
3561251662Sdim        O.matches(options::OPT_fdiagnostics_color)) {
3562251662Sdim      ShowColors = Colors_On;
3563251662Sdim    } else if (O.matches(options::OPT_fno_color_diagnostics) ||
3564251662Sdim               O.matches(options::OPT_fno_diagnostics_color)) {
3565251662Sdim      ShowColors = Colors_Off;
3566251662Sdim    } else {
3567251662Sdim      assert(O.matches(options::OPT_fdiagnostics_color_EQ));
3568251662Sdim      StringRef value((*it)->getValue());
3569251662Sdim      if (value == "always")
3570251662Sdim        ShowColors = Colors_On;
3571251662Sdim      else if (value == "never")
3572251662Sdim        ShowColors = Colors_Off;
3573251662Sdim      else if (value == "auto")
3574251662Sdim        ShowColors = Colors_Auto;
3575251662Sdim      else
3576251662Sdim        getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
3577251662Sdim          << ("-fdiagnostics-color=" + value).str();
3578251662Sdim    }
3579251662Sdim  }
3580251662Sdim  if (ShowColors == Colors_On ||
3581251662Sdim      (ShowColors == Colors_Auto && llvm::sys::Process::StandardErrHasColors()))
3582198893Srdivacky    CmdArgs.push_back("-fcolor-diagnostics");
3583198893Srdivacky
3584263508Sdim  if (Args.hasArg(options::OPT_fansi_escape_codes))
3585263508Sdim    CmdArgs.push_back("-fansi-escape-codes");
3586263508Sdim
3587194179Sed  if (!Args.hasFlag(options::OPT_fshow_source_location,
3588194179Sed                    options::OPT_fno_show_source_location))
3589194179Sed    CmdArgs.push_back("-fno-show-source-location");
3590193326Sed
3591223017Sdim  if (!Args.hasFlag(options::OPT_fshow_column,
3592223017Sdim                    options::OPT_fno_show_column,
3593223017Sdim                    true))
3594223017Sdim    CmdArgs.push_back("-fno-show-column");
3595223017Sdim
3596210299Sed  if (!Args.hasFlag(options::OPT_fspell_checking,
3597210299Sed                    options::OPT_fno_spell_checking))
3598210299Sed    CmdArgs.push_back("-fno-spell-checking");
3599212904Sdim
3600218893Sdim
3601249423Sdim  // -fno-asm-blocks is default.
3602249423Sdim  if (Args.hasFlag(options::OPT_fasm_blocks, options::OPT_fno_asm_blocks,
3603249423Sdim                   false))
3604249423Sdim    CmdArgs.push_back("-fasm-blocks");
3605218893Sdim
3606263508Sdim  // Enable vectorization per default according to the optimization level
3607263508Sdim  // selected. For optimization levels that want vectorization we use the alias
3608263508Sdim  // option to simplify the hasFlag logic.
3609263508Sdim  bool EnableVec = shouldEnableVectorizerAtOLevel(Args);
3610263508Sdim  OptSpecifier VectorizeAliasOption = EnableVec ? options::OPT_O_Group :
3611251662Sdim    options::OPT_fvectorize;
3612251662Sdim  if (Args.hasFlag(options::OPT_fvectorize, VectorizeAliasOption,
3613263508Sdim                   options::OPT_fno_vectorize, EnableVec))
3614249423Sdim    CmdArgs.push_back("-vectorize-loops");
3615249423Sdim
3616263508Sdim  // -fslp-vectorize is default.
3617249423Sdim  if (Args.hasFlag(options::OPT_fslp_vectorize,
3618263508Sdim                   options::OPT_fno_slp_vectorize, true))
3619251662Sdim    CmdArgs.push_back("-vectorize-slp");
3620249423Sdim
3621251662Sdim  // -fno-slp-vectorize-aggressive is default.
3622251662Sdim  if (Args.hasFlag(options::OPT_fslp_vectorize_aggressive,
3623263508Sdim                   options::OPT_fno_slp_vectorize_aggressive, false))
3624251662Sdim    CmdArgs.push_back("-vectorize-slp-aggressive");
3625251662Sdim
3626210299Sed  if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
3627210299Sed    A->render(Args, CmdArgs);
3628210299Sed
3629193326Sed  // -fdollars-in-identifiers default varies depending on platform and
3630193326Sed  // language; only pass if specified.
3631198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_fdollars_in_identifiers,
3632193326Sed                               options::OPT_fno_dollars_in_identifiers)) {
3633193326Sed    if (A->getOption().matches(options::OPT_fdollars_in_identifiers))
3634201361Srdivacky      CmdArgs.push_back("-fdollars-in-identifiers");
3635193326Sed    else
3636201361Srdivacky      CmdArgs.push_back("-fno-dollars-in-identifiers");
3637193326Sed  }
3638193326Sed
3639193326Sed  // -funit-at-a-time is default, and we don't support -fno-unit-at-a-time for
3640193326Sed  // practical purposes.
3641198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_funit_at_a_time,
3642193326Sed                               options::OPT_fno_unit_at_a_time)) {
3643193326Sed    if (A->getOption().matches(options::OPT_fno_unit_at_a_time))
3644226633Sdim      D.Diag(diag::warn_drv_clang_unsupported) << A->getAsString(Args);
3645193326Sed  }
3646198092Srdivacky
3647234353Sdim  if (Args.hasFlag(options::OPT_fapple_pragma_pack,
3648234353Sdim                   options::OPT_fno_apple_pragma_pack, false))
3649234353Sdim    CmdArgs.push_back("-fapple-pragma-pack");
3650234353Sdim
3651263508Sdim  // le32-specific flags:
3652263508Sdim  //  -fno-math-builtin: clang should not convert math builtins to intrinsics
3653263508Sdim  //                     by default.
3654263508Sdim  if (getToolChain().getArch() == llvm::Triple::le32) {
3655263508Sdim    CmdArgs.push_back("-fno-math-builtin");
3656263508Sdim  }
3657263508Sdim
3658198092Srdivacky  // Default to -fno-builtin-str{cat,cpy} on Darwin for ARM.
3659198092Srdivacky  //
3660200583Srdivacky  // FIXME: This is disabled until clang -cc1 supports -fno-builtin-foo. PR4941.
3661198092Srdivacky#if 0
3662226633Sdim  if (getToolChain().getTriple().isOSDarwin() &&
3663263508Sdim      (getToolChain().getArch() == llvm::Triple::arm ||
3664263508Sdim       getToolChain().getArch() == llvm::Triple::thumb)) {
3665198092Srdivacky    if (!Args.hasArg(options::OPT_fbuiltin_strcat))
3666198092Srdivacky      CmdArgs.push_back("-fno-builtin-strcat");
3667198092Srdivacky    if (!Args.hasArg(options::OPT_fbuiltin_strcpy))
3668198092Srdivacky      CmdArgs.push_back("-fno-builtin-strcpy");
3669198092Srdivacky  }
3670198092Srdivacky#endif
3671198092Srdivacky
3672221345Sdim  // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
3673198092Srdivacky  if (Arg *A = Args.getLastArg(options::OPT_traditional,
3674221345Sdim                               options::OPT_traditional_cpp)) {
3675221345Sdim    if (isa<PreprocessJobAction>(JA))
3676221345Sdim      CmdArgs.push_back("-traditional-cpp");
3677226633Sdim    else
3678226633Sdim      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
3679221345Sdim  }
3680198092Srdivacky
3681193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dM);
3682193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dD);
3683234353Sdim
3684234353Sdim  // Handle serialized diagnostics.
3685234353Sdim  if (Arg *A = Args.getLastArg(options::OPT__serialize_diags)) {
3686234353Sdim    CmdArgs.push_back("-serialize-diagnostic-file");
3687243830Sdim    CmdArgs.push_back(Args.MakeArgString(A->getValue()));
3688234353Sdim  }
3689193326Sed
3690243830Sdim  if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
3691243830Sdim    CmdArgs.push_back("-fretain-comments-from-system-headers");
3692243830Sdim
3693249423Sdim  // Forward -fcomment-block-commands to -cc1.
3694249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
3695251662Sdim  // Forward -fparse-all-comments to -cc1.
3696251662Sdim  Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments);
3697249423Sdim
3698207619Srdivacky  // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
3699207619Srdivacky  // parser.
3700193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
3701207619Srdivacky  for (arg_iterator it = Args.filtered_begin(options::OPT_mllvm),
3702207619Srdivacky         ie = Args.filtered_end(); it != ie; ++it) {
3703210299Sed    (*it)->claim();
3704193326Sed
3705207619Srdivacky    // We translate this by hand to the -cc1 argument, since nightly test uses
3706207619Srdivacky    // it and developers have been trained to spell it with -mllvm.
3707243830Sdim    if (StringRef((*it)->getValue(0)) == "-disable-llvm-optzns")
3708207619Srdivacky      CmdArgs.push_back("-disable-llvm-optzns");
3709207619Srdivacky    else
3710210299Sed      (*it)->render(Args, CmdArgs);
3711207619Srdivacky  }
3712207619Srdivacky
3713193326Sed  if (Output.getType() == types::TY_Dependencies) {
3714193326Sed    // Handled with other dependency code.
3715193326Sed  } else if (Output.isFilename()) {
3716193326Sed    CmdArgs.push_back("-o");
3717193326Sed    CmdArgs.push_back(Output.getFilename());
3718193326Sed  } else {
3719193326Sed    assert(Output.isNothing() && "Invalid output.");
3720193326Sed  }
3721193326Sed
3722193326Sed  for (InputInfoList::const_iterator
3723193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
3724193326Sed    const InputInfo &II = *it;
3725193326Sed    CmdArgs.push_back("-x");
3726243830Sdim    if (Args.hasArg(options::OPT_rewrite_objc))
3727243830Sdim      CmdArgs.push_back(types::getTypeName(types::TY_PP_ObjCXX));
3728243830Sdim    else
3729243830Sdim      CmdArgs.push_back(types::getTypeName(II.getType()));
3730212904Sdim    if (II.isFilename())
3731193326Sed      CmdArgs.push_back(II.getFilename());
3732193326Sed    else
3733193326Sed      II.getInputArg().renderAsInput(Args, CmdArgs);
3734193326Sed  }
3735193326Sed
3736198893Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_undef);
3737198893Srdivacky
3738212904Sdim  const char *Exec = getToolChain().getDriver().getClangProgramPath();
3739201361Srdivacky
3740201361Srdivacky  // Optionally embed the -cc1 level arguments into the debug info, for build
3741201361Srdivacky  // analysis.
3742201361Srdivacky  if (getToolChain().UseDwarfDebugFlags()) {
3743210299Sed    ArgStringList OriginalArgs;
3744210299Sed    for (ArgList::const_iterator it = Args.begin(),
3745210299Sed           ie = Args.end(); it != ie; ++it)
3746210299Sed      (*it)->render(Args, OriginalArgs);
3747212904Sdim
3748234353Sdim    SmallString<256> Flags;
3749201361Srdivacky    Flags += Exec;
3750210299Sed    for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
3751201361Srdivacky      Flags += " ";
3752210299Sed      Flags += OriginalArgs[i];
3753201361Srdivacky    }
3754201361Srdivacky    CmdArgs.push_back("-dwarf-debug-flags");
3755201361Srdivacky    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
3756201361Srdivacky  }
3757201361Srdivacky
3758249423Sdim  // Add the split debug info name to the command lines here so we
3759249423Sdim  // can propagate it to the backend.
3760249423Sdim  bool SplitDwarf = Args.hasArg(options::OPT_gsplit_dwarf) &&
3761263508Sdim    getToolChain().getTriple().isOSLinux() &&
3762249423Sdim    (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA));
3763249423Sdim  const char *SplitDwarfOut;
3764249423Sdim  if (SplitDwarf) {
3765249423Sdim    CmdArgs.push_back("-split-dwarf-file");
3766249423Sdim    SplitDwarfOut = SplitDebugName(Args, Inputs);
3767249423Sdim    CmdArgs.push_back(SplitDwarfOut);
3768249423Sdim  }
3769249423Sdim
3770249423Sdim  // Finally add the compile command to the compilation.
3771263508Sdim  if (Args.hasArg(options::OPT__SLASH_fallback)) {
3772263508Sdim    tools::visualstudio::Compile CL(getToolChain());
3773263508Sdim    Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args,
3774263508Sdim                                       LinkingOutput);
3775263508Sdim    C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
3776263508Sdim  } else {
3777263508Sdim    C.addCommand(new Command(JA, *this, Exec, CmdArgs));
3778263508Sdim  }
3779193326Sed
3780263508Sdim
3781249423Sdim  // Handle the debug info splitting at object creation time if we're
3782249423Sdim  // creating an object.
3783249423Sdim  // TODO: Currently only works on linux with newer objcopy.
3784249423Sdim  if (SplitDwarf && !isa<CompileJobAction>(JA))
3785249423Sdim    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
3786249423Sdim
3787218893Sdim  if (Arg *A = Args.getLastArg(options::OPT_pg))
3788218893Sdim    if (Args.hasArg(options::OPT_fomit_frame_pointer))
3789226633Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
3790218893Sdim        << "-fomit-frame-pointer" << A->getAsString(Args);
3791193326Sed
3792193326Sed  // Claim some arguments which clang supports automatically.
3793193326Sed
3794207619Srdivacky  // -fpch-preprocess is used with gcc to add a special marker in the output to
3795207619Srdivacky  // include the PCH file. Clang's PTH solution is completely transparent, so we
3796207619Srdivacky  // do not need to deal with it at all.
3797193326Sed  Args.ClaimAllArgs(options::OPT_fpch_preprocess);
3798193326Sed
3799193326Sed  // Claim some arguments which clang doesn't support, but we don't
3800193326Sed  // care to warn the user about.
3801199990Srdivacky  Args.ClaimAllArgs(options::OPT_clang_ignored_f_Group);
3802199990Srdivacky  Args.ClaimAllArgs(options::OPT_clang_ignored_m_Group);
3803221345Sdim
3804263508Sdim  // Disable warnings for clang -E -emit-llvm foo.c
3805221345Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
3806193326Sed}
3807193326Sed
3808239462Sdim/// Add options related to the Objective-C runtime/ABI.
3809239462Sdim///
3810239462Sdim/// Returns true if the runtime is non-fragile.
3811239462SdimObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args,
3812239462Sdim                                      ArgStringList &cmdArgs,
3813239462Sdim                                      RewriteKind rewriteKind) const {
3814239462Sdim  // Look for the controlling runtime option.
3815239462Sdim  Arg *runtimeArg = args.getLastArg(options::OPT_fnext_runtime,
3816239462Sdim                                    options::OPT_fgnu_runtime,
3817239462Sdim                                    options::OPT_fobjc_runtime_EQ);
3818239462Sdim
3819239462Sdim  // Just forward -fobjc-runtime= to the frontend.  This supercedes
3820239462Sdim  // options about fragility.
3821239462Sdim  if (runtimeArg &&
3822239462Sdim      runtimeArg->getOption().matches(options::OPT_fobjc_runtime_EQ)) {
3823239462Sdim    ObjCRuntime runtime;
3824243830Sdim    StringRef value = runtimeArg->getValue();
3825239462Sdim    if (runtime.tryParse(value)) {
3826239462Sdim      getToolChain().getDriver().Diag(diag::err_drv_unknown_objc_runtime)
3827239462Sdim        << value;
3828239462Sdim    }
3829239462Sdim
3830239462Sdim    runtimeArg->render(args, cmdArgs);
3831239462Sdim    return runtime;
3832239462Sdim  }
3833239462Sdim
3834239462Sdim  // Otherwise, we'll need the ABI "version".  Version numbers are
3835239462Sdim  // slightly confusing for historical reasons:
3836239462Sdim  //   1 - Traditional "fragile" ABI
3837239462Sdim  //   2 - Non-fragile ABI, version 1
3838239462Sdim  //   3 - Non-fragile ABI, version 2
3839239462Sdim  unsigned objcABIVersion = 1;
3840239462Sdim  // If -fobjc-abi-version= is present, use that to set the version.
3841239462Sdim  if (Arg *abiArg = args.getLastArg(options::OPT_fobjc_abi_version_EQ)) {
3842243830Sdim    StringRef value = abiArg->getValue();
3843239462Sdim    if (value == "1")
3844239462Sdim      objcABIVersion = 1;
3845239462Sdim    else if (value == "2")
3846239462Sdim      objcABIVersion = 2;
3847239462Sdim    else if (value == "3")
3848239462Sdim      objcABIVersion = 3;
3849239462Sdim    else
3850239462Sdim      getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
3851239462Sdim        << value;
3852239462Sdim  } else {
3853239462Sdim    // Otherwise, determine if we are using the non-fragile ABI.
3854239462Sdim    bool nonFragileABIIsDefault =
3855239462Sdim      (rewriteKind == RK_NonFragile ||
3856239462Sdim       (rewriteKind == RK_None &&
3857239462Sdim        getToolChain().IsObjCNonFragileABIDefault()));
3858239462Sdim    if (args.hasFlag(options::OPT_fobjc_nonfragile_abi,
3859239462Sdim                     options::OPT_fno_objc_nonfragile_abi,
3860239462Sdim                     nonFragileABIIsDefault)) {
3861239462Sdim      // Determine the non-fragile ABI version to use.
3862239462Sdim#ifdef DISABLE_DEFAULT_NONFRAGILEABI_TWO
3863239462Sdim      unsigned nonFragileABIVersion = 1;
3864239462Sdim#else
3865239462Sdim      unsigned nonFragileABIVersion = 2;
3866239462Sdim#endif
3867239462Sdim
3868239462Sdim      if (Arg *abiArg = args.getLastArg(
3869239462Sdim            options::OPT_fobjc_nonfragile_abi_version_EQ)) {
3870243830Sdim        StringRef value = abiArg->getValue();
3871239462Sdim        if (value == "1")
3872239462Sdim          nonFragileABIVersion = 1;
3873239462Sdim        else if (value == "2")
3874239462Sdim          nonFragileABIVersion = 2;
3875239462Sdim        else
3876239462Sdim          getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported)
3877239462Sdim            << value;
3878239462Sdim      }
3879239462Sdim
3880239462Sdim      objcABIVersion = 1 + nonFragileABIVersion;
3881239462Sdim    } else {
3882239462Sdim      objcABIVersion = 1;
3883239462Sdim    }
3884239462Sdim  }
3885239462Sdim
3886239462Sdim  // We don't actually care about the ABI version other than whether
3887239462Sdim  // it's non-fragile.
3888239462Sdim  bool isNonFragile = objcABIVersion != 1;
3889239462Sdim
3890239462Sdim  // If we have no runtime argument, ask the toolchain for its default runtime.
3891239462Sdim  // However, the rewriter only really supports the Mac runtime, so assume that.
3892239462Sdim  ObjCRuntime runtime;
3893239462Sdim  if (!runtimeArg) {
3894239462Sdim    switch (rewriteKind) {
3895239462Sdim    case RK_None:
3896239462Sdim      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
3897239462Sdim      break;
3898239462Sdim    case RK_Fragile:
3899239462Sdim      runtime = ObjCRuntime(ObjCRuntime::FragileMacOSX, VersionTuple());
3900239462Sdim      break;
3901239462Sdim    case RK_NonFragile:
3902239462Sdim      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
3903239462Sdim      break;
3904239462Sdim    }
3905239462Sdim
3906239462Sdim  // -fnext-runtime
3907239462Sdim  } else if (runtimeArg->getOption().matches(options::OPT_fnext_runtime)) {
3908239462Sdim    // On Darwin, make this use the default behavior for the toolchain.
3909239462Sdim    if (getToolChain().getTriple().isOSDarwin()) {
3910239462Sdim      runtime = getToolChain().getDefaultObjCRuntime(isNonFragile);
3911239462Sdim
3912239462Sdim    // Otherwise, build for a generic macosx port.
3913239462Sdim    } else {
3914239462Sdim      runtime = ObjCRuntime(ObjCRuntime::MacOSX, VersionTuple());
3915239462Sdim    }
3916239462Sdim
3917239462Sdim  // -fgnu-runtime
3918239462Sdim  } else {
3919239462Sdim    assert(runtimeArg->getOption().matches(options::OPT_fgnu_runtime));
3920239462Sdim    // Legacy behaviour is to target the gnustep runtime if we are i
3921239462Sdim    // non-fragile mode or the GCC runtime in fragile mode.
3922239462Sdim    if (isNonFragile)
3923243830Sdim      runtime = ObjCRuntime(ObjCRuntime::GNUstep, VersionTuple(1,6));
3924239462Sdim    else
3925239462Sdim      runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple());
3926239462Sdim  }
3927239462Sdim
3928239462Sdim  cmdArgs.push_back(args.MakeArgString(
3929239462Sdim                                 "-fobjc-runtime=" + runtime.getAsString()));
3930239462Sdim  return runtime;
3931239462Sdim}
3932239462Sdim
3933263508Sdimvoid Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
3934263508Sdim  unsigned RTOptionID = options::OPT__SLASH_MT;
3935263508Sdim
3936263508Sdim  if (Args.hasArg(options::OPT__SLASH_LDd))
3937263508Sdim    // The /LDd option implies /MTd. The dependent lib part can be overridden,
3938263508Sdim    // but defining _DEBUG is sticky.
3939263508Sdim    RTOptionID = options::OPT__SLASH_MTd;
3940263508Sdim
3941263508Sdim  if (Arg *A = Args.getLastArg(options::OPT__SLASH_M_Group))
3942263508Sdim    RTOptionID = A->getOption().getID();
3943263508Sdim
3944263508Sdim  switch(RTOptionID) {
3945263508Sdim    case options::OPT__SLASH_MD:
3946263508Sdim      if (Args.hasArg(options::OPT__SLASH_LDd))
3947263508Sdim        CmdArgs.push_back("-D_DEBUG");
3948263508Sdim      CmdArgs.push_back("-D_MT");
3949263508Sdim      CmdArgs.push_back("-D_DLL");
3950263508Sdim      CmdArgs.push_back("--dependent-lib=msvcrt");
3951263508Sdim      break;
3952263508Sdim    case options::OPT__SLASH_MDd:
3953263508Sdim      CmdArgs.push_back("-D_DEBUG");
3954263508Sdim      CmdArgs.push_back("-D_MT");
3955263508Sdim      CmdArgs.push_back("-D_DLL");
3956263508Sdim      CmdArgs.push_back("--dependent-lib=msvcrtd");
3957263508Sdim      break;
3958263508Sdim    case options::OPT__SLASH_MT:
3959263508Sdim      if (Args.hasArg(options::OPT__SLASH_LDd))
3960263508Sdim        CmdArgs.push_back("-D_DEBUG");
3961263508Sdim      CmdArgs.push_back("-D_MT");
3962263508Sdim      CmdArgs.push_back("--dependent-lib=libcmt");
3963263508Sdim      break;
3964263508Sdim    case options::OPT__SLASH_MTd:
3965263508Sdim      CmdArgs.push_back("-D_DEBUG");
3966263508Sdim      CmdArgs.push_back("-D_MT");
3967263508Sdim      CmdArgs.push_back("--dependent-lib=libcmtd");
3968263508Sdim      break;
3969263508Sdim    default:
3970263508Sdim      llvm_unreachable("Unexpected option ID.");
3971263508Sdim  }
3972263508Sdim
3973263508Sdim  // This provides POSIX compatibility (maps 'open' to '_open'), which most
3974263508Sdim  // users want.  The /Za flag to cl.exe turns this off, but it's not
3975263508Sdim  // implemented in clang.
3976263508Sdim  CmdArgs.push_back("--dependent-lib=oldnames");
3977263508Sdim
3978263508Sdim  // FIXME: Make this default for the win32 triple.
3979263508Sdim  CmdArgs.push_back("-cxx-abi");
3980263508Sdim  CmdArgs.push_back("microsoft");
3981263508Sdim
3982263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_show_includes))
3983263508Sdim    A->render(Args, CmdArgs);
3984263508Sdim
3985263508Sdim  if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
3986263508Sdim    CmdArgs.push_back("-fdiagnostics-format");
3987263508Sdim    if (Args.hasArg(options::OPT__SLASH_fallback))
3988263508Sdim      CmdArgs.push_back("msvc-fallback");
3989263508Sdim    else
3990263508Sdim      CmdArgs.push_back("msvc");
3991263508Sdim  }
3992263508Sdim}
3993263508Sdim
3994208600Srdivackyvoid ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
3995208600Srdivacky                           const InputInfo &Output,
3996208600Srdivacky                           const InputInfoList &Inputs,
3997208600Srdivacky                           const ArgList &Args,
3998208600Srdivacky                           const char *LinkingOutput) const {
3999208600Srdivacky  ArgStringList CmdArgs;
4000208600Srdivacky
4001208600Srdivacky  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
4002208600Srdivacky  const InputInfo &Input = Inputs[0];
4003208600Srdivacky
4004218893Sdim  // Don't warn about "clang -w -c foo.s"
4005218893Sdim  Args.ClaimAllArgs(options::OPT_w);
4006221345Sdim  // and "clang -emit-llvm -c foo.s"
4007221345Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
4008218893Sdim
4009208600Srdivacky  // Invoke ourselves in -cc1as mode.
4010208600Srdivacky  //
4011208600Srdivacky  // FIXME: Implement custom jobs for internal actions.
4012208600Srdivacky  CmdArgs.push_back("-cc1as");
4013208600Srdivacky
4014208600Srdivacky  // Add the "effective" target triple.
4015208600Srdivacky  CmdArgs.push_back("-triple");
4016226633Sdim  std::string TripleStr =
4017226633Sdim    getToolChain().ComputeEffectiveClangTriple(Args, Input.getType());
4018208600Srdivacky  CmdArgs.push_back(Args.MakeArgString(TripleStr));
4019208600Srdivacky
4020208600Srdivacky  // Set the output mode, we currently only expect to be used as a real
4021208600Srdivacky  // assembler.
4022208600Srdivacky  CmdArgs.push_back("-filetype");
4023208600Srdivacky  CmdArgs.push_back("obj");
4024208600Srdivacky
4025249423Sdim  // Set the main file name, so that debug info works even with
4026249423Sdim  // -save-temps or preprocessed assembly.
4027249423Sdim  CmdArgs.push_back("-main-file-name");
4028249423Sdim  CmdArgs.push_back(Clang::getBaseInputName(Args, Inputs));
4029249423Sdim
4030263508Sdim  // Add the target cpu
4031263508Sdim  const llvm::Triple &Triple = getToolChain().getTriple();
4032263508Sdim  std::string CPU = getCPUName(Args, Triple);
4033263508Sdim  if (!CPU.empty()) {
4034263508Sdim    CmdArgs.push_back("-target-cpu");
4035263508Sdim    CmdArgs.push_back(Args.MakeArgString(CPU));
4036263508Sdim  }
4037208600Srdivacky
4038263508Sdim  // Add the target features
4039263508Sdim  const Driver &D = getToolChain().getDriver();
4040263508Sdim  getTargetFeatures(D, Triple, Args, CmdArgs);
4041234353Sdim
4042221345Sdim  // Ignore explicit -force_cpusubtype_ALL option.
4043221345Sdim  (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
4044208600Srdivacky
4045234353Sdim  // Determine the original source input.
4046234353Sdim  const Action *SourceAction = &JA;
4047234353Sdim  while (SourceAction->getKind() != Action::InputClass) {
4048234353Sdim    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
4049234353Sdim    SourceAction = SourceAction->getInputs()[0];
4050234353Sdim  }
4051208600Srdivacky
4052249423Sdim  // Forward -g and handle debug info related flags, assuming we are dealing
4053249423Sdim  // with an actual assembly file.
4054234353Sdim  if (SourceAction->getType() == types::TY_Asm ||
4055234353Sdim      SourceAction->getType() == types::TY_PP_Asm) {
4056234353Sdim    Args.ClaimAllArgs(options::OPT_g_Group);
4057234353Sdim    if (Arg *A = Args.getLastArg(options::OPT_g_Group))
4058234353Sdim      if (!A->getOption().matches(options::OPT_g0))
4059234353Sdim        CmdArgs.push_back("-g");
4060249423Sdim
4061249423Sdim    // Add the -fdebug-compilation-dir flag if needed.
4062249423Sdim    addDebugCompDirArg(Args, CmdArgs);
4063249423Sdim
4064249423Sdim    // Set the AT_producer to the clang version when using the integrated
4065249423Sdim    // assembler on assembly source files.
4066249423Sdim    CmdArgs.push_back("-dwarf-debug-producer");
4067249423Sdim    CmdArgs.push_back(Args.MakeArgString(getClangFullVersion()));
4068234353Sdim  }
4069234353Sdim
4070234353Sdim  // Optionally embed the -cc1as level arguments into the debug info, for build
4071234353Sdim  // analysis.
4072234353Sdim  if (getToolChain().UseDwarfDebugFlags()) {
4073234353Sdim    ArgStringList OriginalArgs;
4074234353Sdim    for (ArgList::const_iterator it = Args.begin(),
4075234353Sdim           ie = Args.end(); it != ie; ++it)
4076234353Sdim      (*it)->render(Args, OriginalArgs);
4077234353Sdim
4078234353Sdim    SmallString<256> Flags;
4079234353Sdim    const char *Exec = getToolChain().getDriver().getClangProgramPath();
4080234353Sdim    Flags += Exec;
4081234353Sdim    for (unsigned i = 0, e = OriginalArgs.size(); i != e; ++i) {
4082234353Sdim      Flags += " ";
4083234353Sdim      Flags += OriginalArgs[i];
4084234353Sdim    }
4085234353Sdim    CmdArgs.push_back("-dwarf-debug-flags");
4086234353Sdim    CmdArgs.push_back(Args.MakeArgString(Flags.str()));
4087234353Sdim  }
4088234353Sdim
4089208600Srdivacky  // FIXME: Add -static support, once we have it.
4090208600Srdivacky
4091263508Sdim  CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
4092263508Sdim                                    getToolChain().getDriver());
4093263508Sdim
4094221345Sdim  Args.AddAllArgs(CmdArgs, options::OPT_mllvm);
4095208600Srdivacky
4096208600Srdivacky  assert(Output.isFilename() && "Unexpected lipo output.");
4097208600Srdivacky  CmdArgs.push_back("-o");
4098208600Srdivacky  CmdArgs.push_back(Output.getFilename());
4099208600Srdivacky
4100212904Sdim  assert(Input.isFilename() && "Invalid input.");
4101212904Sdim  CmdArgs.push_back(Input.getFilename());
4102208600Srdivacky
4103212904Sdim  const char *Exec = getToolChain().getDriver().getClangProgramPath();
4104212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4105251662Sdim
4106251662Sdim  // Handle the debug info splitting at object creation time if we're
4107251662Sdim  // creating an object.
4108251662Sdim  // TODO: Currently only works on linux with newer objcopy.
4109251662Sdim  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
4110263508Sdim      getToolChain().getTriple().isOSLinux())
4111251662Sdim    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
4112251662Sdim                   SplitDebugName(Args, Inputs));
4113208600Srdivacky}
4114208600Srdivacky
4115193326Sedvoid gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
4116193326Sed                               const InputInfo &Output,
4117193326Sed                               const InputInfoList &Inputs,
4118193326Sed                               const ArgList &Args,
4119193326Sed                               const char *LinkingOutput) const {
4120201361Srdivacky  const Driver &D = getToolChain().getDriver();
4121193326Sed  ArgStringList CmdArgs;
4122193326Sed
4123193326Sed  for (ArgList::const_iterator
4124193326Sed         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
4125193326Sed    Arg *A = *it;
4126243830Sdim    if (forwardToGCC(A->getOption())) {
4127212904Sdim      // Don't forward any -g arguments to assembly steps.
4128212904Sdim      if (isa<AssembleJobAction>(JA) &&
4129212904Sdim          A->getOption().matches(options::OPT_g_Group))
4130212904Sdim        continue;
4131212904Sdim
4132263508Sdim      // Don't forward any -W arguments to assembly and link steps.
4133263508Sdim      if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
4134263508Sdim          A->getOption().matches(options::OPT_W_Group))
4135263508Sdim        continue;
4136263508Sdim
4137193326Sed      // It is unfortunate that we have to claim here, as this means
4138193326Sed      // we will basically never report anything interesting for
4139193326Sed      // platforms using a generic gcc, even if we are just using gcc
4140193326Sed      // to get to the assembler.
4141193326Sed      A->claim();
4142193326Sed      A->render(Args, CmdArgs);
4143193326Sed    }
4144193326Sed  }
4145193326Sed
4146203955Srdivacky  RenderExtraToolArgs(JA, CmdArgs);
4147193326Sed
4148193326Sed  // If using a driver driver, force the arch.
4149243830Sdim  llvm::Triple::ArchType Arch = getToolChain().getArch();
4150226633Sdim  if (getToolChain().getTriple().isOSDarwin()) {
4151193326Sed    CmdArgs.push_back("-arch");
4152193326Sed
4153193326Sed    // FIXME: Remove these special cases.
4154243830Sdim    if (Arch == llvm::Triple::ppc)
4155193326Sed      CmdArgs.push_back("ppc");
4156243830Sdim    else if (Arch == llvm::Triple::ppc64)
4157193326Sed      CmdArgs.push_back("ppc64");
4158263508Sdim    else if (Arch == llvm::Triple::ppc64le)
4159263508Sdim      CmdArgs.push_back("ppc64le");
4160193326Sed    else
4161243830Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().getArchName()));
4162193326Sed  }
4163193326Sed
4164193326Sed  // Try to force gcc to match the tool chain we want, if we recognize
4165193326Sed  // the arch.
4166193326Sed  //
4167193326Sed  // FIXME: The triple class should directly provide the information we want
4168193326Sed  // here.
4169243830Sdim  if (Arch == llvm::Triple::x86 || Arch == llvm::Triple::ppc)
4170193326Sed    CmdArgs.push_back("-m32");
4171263508Sdim  else if (Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::ppc64 ||
4172263508Sdim           Arch == llvm::Triple::ppc64le)
4173193326Sed    CmdArgs.push_back("-m64");
4174193326Sed
4175212904Sdim  if (Output.isFilename()) {
4176193326Sed    CmdArgs.push_back("-o");
4177193326Sed    CmdArgs.push_back(Output.getFilename());
4178193326Sed  } else {
4179193326Sed    assert(Output.isNothing() && "Unexpected output");
4180193326Sed    CmdArgs.push_back("-fsyntax-only");
4181193326Sed  }
4182193326Sed
4183234353Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
4184234353Sdim                       options::OPT_Xassembler);
4185193326Sed
4186193326Sed  // Only pass -x if gcc will understand it; otherwise hope gcc
4187193326Sed  // understands the suffix correctly. The main use case this would go
4188193326Sed  // wrong in is for linker inputs if they happened to have an odd
4189193326Sed  // suffix; really the only way to get this to happen is a command
4190193326Sed  // like '-x foobar a.c' which will treat a.c like a linker input.
4191193326Sed  //
4192193326Sed  // FIXME: For the linker case specifically, can we safely convert
4193193326Sed  // inputs into '-Wl,' options?
4194193326Sed  for (InputInfoList::const_iterator
4195193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
4196193326Sed    const InputInfo &II = *it;
4197193326Sed
4198198092Srdivacky    // Don't try to pass LLVM or AST inputs to a generic gcc.
4199210299Sed    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
4200210299Sed        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
4201226633Sdim      D.Diag(diag::err_drv_no_linker_llvm_support)
4202198092Srdivacky        << getToolChain().getTripleString();
4203198092Srdivacky    else if (II.getType() == types::TY_AST)
4204226633Sdim      D.Diag(diag::err_drv_no_ast_support)
4205198092Srdivacky        << getToolChain().getTripleString();
4206249423Sdim    else if (II.getType() == types::TY_ModuleFile)
4207249423Sdim      D.Diag(diag::err_drv_no_module_support)
4208249423Sdim        << getToolChain().getTripleString();
4209193326Sed
4210193326Sed    if (types::canTypeBeUserSpecified(II.getType())) {
4211193326Sed      CmdArgs.push_back("-x");
4212193326Sed      CmdArgs.push_back(types::getTypeName(II.getType()));
4213193326Sed    }
4214193326Sed
4215212904Sdim    if (II.isFilename())
4216193326Sed      CmdArgs.push_back(II.getFilename());
4217218893Sdim    else {
4218218893Sdim      const Arg &A = II.getInputArg();
4219218893Sdim
4220218893Sdim      // Reverse translate some rewritten options.
4221218893Sdim      if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
4222218893Sdim        CmdArgs.push_back("-lstdc++");
4223218893Sdim        continue;
4224218893Sdim      }
4225218893Sdim
4226193326Sed      // Don't render as input, we need gcc to do the translations.
4227218893Sdim      A.render(Args, CmdArgs);
4228218893Sdim    }
4229193326Sed  }
4230193326Sed
4231221345Sdim  const std::string customGCCName = D.getCCCGenericGCCName();
4232221345Sdim  const char *GCCName;
4233221345Sdim  if (!customGCCName.empty())
4234221345Sdim    GCCName = customGCCName.c_str();
4235263508Sdim  else if (D.CCCIsCXX()) {
4236221345Sdim    GCCName = "g++";
4237221345Sdim  } else
4238221345Sdim    GCCName = "gcc";
4239221345Sdim
4240193326Sed  const char *Exec =
4241210299Sed    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
4242212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4243193326Sed}
4244193326Sed
4245203955Srdivackyvoid gcc::Preprocess::RenderExtraToolArgs(const JobAction &JA,
4246203955Srdivacky                                          ArgStringList &CmdArgs) const {
4247193326Sed  CmdArgs.push_back("-E");
4248193326Sed}
4249193326Sed
4250203955Srdivackyvoid gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
4251203955Srdivacky                                          ArgStringList &CmdArgs) const {
4252193326Sed  // The type is good enough.
4253193326Sed}
4254193326Sed
4255203955Srdivackyvoid gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
4256203955Srdivacky                                       ArgStringList &CmdArgs) const {
4257203955Srdivacky  const Driver &D = getToolChain().getDriver();
4258203955Srdivacky
4259203955Srdivacky  // If -flto, etc. are present then make sure not to force assembly output.
4260210299Sed  if (JA.getType() == types::TY_LLVM_IR || JA.getType() == types::TY_LTO_IR ||
4261210299Sed      JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC)
4262203955Srdivacky    CmdArgs.push_back("-c");
4263203955Srdivacky  else {
4264203955Srdivacky    if (JA.getType() != types::TY_PP_Asm)
4265226633Sdim      D.Diag(diag::err_drv_invalid_gcc_output_type)
4266203955Srdivacky        << getTypeName(JA.getType());
4267218893Sdim
4268203955Srdivacky    CmdArgs.push_back("-S");
4269203955Srdivacky  }
4270193326Sed}
4271193326Sed
4272203955Srdivackyvoid gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
4273203955Srdivacky                                        ArgStringList &CmdArgs) const {
4274193326Sed  CmdArgs.push_back("-c");
4275193326Sed}
4276193326Sed
4277203955Srdivackyvoid gcc::Link::RenderExtraToolArgs(const JobAction &JA,
4278203955Srdivacky                                    ArgStringList &CmdArgs) const {
4279193326Sed  // The types are (hopefully) good enough.
4280193326Sed}
4281193326Sed
4282234353Sdim// Hexagon tools start.
4283234353Sdimvoid hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA,
4284234353Sdim                                        ArgStringList &CmdArgs) const {
4285234353Sdim
4286234353Sdim}
4287234353Sdimvoid hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
4288234353Sdim                               const InputInfo &Output,
4289234353Sdim                               const InputInfoList &Inputs,
4290234353Sdim                               const ArgList &Args,
4291234353Sdim                               const char *LinkingOutput) const {
4292234353Sdim
4293234353Sdim  const Driver &D = getToolChain().getDriver();
4294234353Sdim  ArgStringList CmdArgs;
4295234353Sdim
4296234353Sdim  std::string MarchString = "-march=";
4297249423Sdim  MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args);
4298234353Sdim  CmdArgs.push_back(Args.MakeArgString(MarchString));
4299234353Sdim
4300234353Sdim  RenderExtraToolArgs(JA, CmdArgs);
4301234353Sdim
4302234353Sdim  if (Output.isFilename()) {
4303234353Sdim    CmdArgs.push_back("-o");
4304234353Sdim    CmdArgs.push_back(Output.getFilename());
4305234353Sdim  } else {
4306234353Sdim    assert(Output.isNothing() && "Unexpected output");
4307234353Sdim    CmdArgs.push_back("-fsyntax-only");
4308234353Sdim  }
4309234353Sdim
4310249423Sdim  std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
4311249423Sdim  if (!SmallDataThreshold.empty())
4312249423Sdim    CmdArgs.push_back(
4313249423Sdim      Args.MakeArgString(std::string("-G") + SmallDataThreshold));
4314234353Sdim
4315249423Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
4316249423Sdim                       options::OPT_Xassembler);
4317249423Sdim
4318234353Sdim  // Only pass -x if gcc will understand it; otherwise hope gcc
4319234353Sdim  // understands the suffix correctly. The main use case this would go
4320234353Sdim  // wrong in is for linker inputs if they happened to have an odd
4321234353Sdim  // suffix; really the only way to get this to happen is a command
4322234353Sdim  // like '-x foobar a.c' which will treat a.c like a linker input.
4323234353Sdim  //
4324234353Sdim  // FIXME: For the linker case specifically, can we safely convert
4325234353Sdim  // inputs into '-Wl,' options?
4326234353Sdim  for (InputInfoList::const_iterator
4327234353Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
4328234353Sdim    const InputInfo &II = *it;
4329234353Sdim
4330234353Sdim    // Don't try to pass LLVM or AST inputs to a generic gcc.
4331234353Sdim    if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
4332234353Sdim        II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
4333234353Sdim      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
4334234353Sdim        << getToolChain().getTripleString();
4335234353Sdim    else if (II.getType() == types::TY_AST)
4336234353Sdim      D.Diag(clang::diag::err_drv_no_ast_support)
4337234353Sdim        << getToolChain().getTripleString();
4338249423Sdim    else if (II.getType() == types::TY_ModuleFile)
4339249423Sdim      D.Diag(diag::err_drv_no_module_support)
4340249423Sdim      << getToolChain().getTripleString();
4341234353Sdim
4342234353Sdim    if (II.isFilename())
4343234353Sdim      CmdArgs.push_back(II.getFilename());
4344234353Sdim    else
4345234353Sdim      // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ?
4346234353Sdim      II.getInputArg().render(Args, CmdArgs);
4347234353Sdim  }
4348234353Sdim
4349234353Sdim  const char *GCCName = "hexagon-as";
4350234353Sdim  const char *Exec =
4351234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
4352234353Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4353234353Sdim
4354234353Sdim}
4355234353Sdimvoid hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
4356234353Sdim                                    ArgStringList &CmdArgs) const {
4357234353Sdim  // The types are (hopefully) good enough.
4358234353Sdim}
4359234353Sdim
4360234353Sdimvoid hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
4361234353Sdim                               const InputInfo &Output,
4362234353Sdim                               const InputInfoList &Inputs,
4363234353Sdim                               const ArgList &Args,
4364234353Sdim                               const char *LinkingOutput) const {
4365234353Sdim
4366249423Sdim  const toolchains::Hexagon_TC& ToolChain =
4367249423Sdim    static_cast<const toolchains::Hexagon_TC&>(getToolChain());
4368249423Sdim  const Driver &D = ToolChain.getDriver();
4369249423Sdim
4370234353Sdim  ArgStringList CmdArgs;
4371234353Sdim
4372249423Sdim  //----------------------------------------------------------------------------
4373249423Sdim  //
4374249423Sdim  //----------------------------------------------------------------------------
4375249423Sdim  bool hasStaticArg = Args.hasArg(options::OPT_static);
4376249423Sdim  bool buildingLib = Args.hasArg(options::OPT_shared);
4377249423Sdim  bool buildPIE = Args.hasArg(options::OPT_pie);
4378249423Sdim  bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
4379249423Sdim  bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
4380249423Sdim  bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
4381249423Sdim  bool useShared = buildingLib && !hasStaticArg;
4382234353Sdim
4383249423Sdim  //----------------------------------------------------------------------------
4384249423Sdim  // Silence warnings for various options
4385249423Sdim  //----------------------------------------------------------------------------
4386249423Sdim
4387249423Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
4388249423Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
4389249423Sdim  Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
4390249423Sdim                                     // handled somewhere else.
4391249423Sdim  Args.ClaimAllArgs(options::OPT_static_libgcc);
4392249423Sdim
4393249423Sdim  //----------------------------------------------------------------------------
4394249423Sdim  //
4395249423Sdim  //----------------------------------------------------------------------------
4396249423Sdim  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
4397249423Sdim         e = ToolChain.ExtraOpts.end();
4398249423Sdim       i != e; ++i)
4399249423Sdim    CmdArgs.push_back(i->c_str());
4400249423Sdim
4401249423Sdim  std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
4402249423Sdim  CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
4403249423Sdim
4404249423Sdim  if (buildingLib) {
4405249423Sdim    CmdArgs.push_back("-shared");
4406249423Sdim    CmdArgs.push_back("-call_shared"); // should be the default, but doing as
4407249423Sdim                                       // hexagon-gcc does
4408234353Sdim  }
4409234353Sdim
4410249423Sdim  if (hasStaticArg)
4411249423Sdim    CmdArgs.push_back("-static");
4412234353Sdim
4413249423Sdim  if (buildPIE && !buildingLib)
4414249423Sdim    CmdArgs.push_back("-pie");
4415249423Sdim
4416249423Sdim  std::string SmallDataThreshold = GetHexagonSmallDataThresholdValue(Args);
4417249423Sdim  if (!SmallDataThreshold.empty()) {
4418249423Sdim    CmdArgs.push_back(
4419249423Sdim      Args.MakeArgString(std::string("-G") + SmallDataThreshold));
4420234353Sdim  }
4421234353Sdim
4422249423Sdim  //----------------------------------------------------------------------------
4423249423Sdim  //
4424249423Sdim  //----------------------------------------------------------------------------
4425249423Sdim  CmdArgs.push_back("-o");
4426249423Sdim  CmdArgs.push_back(Output.getFilename());
4427234353Sdim
4428249423Sdim  const std::string MarchSuffix = "/" + MarchString;
4429249423Sdim  const std::string G0Suffix = "/G0";
4430249423Sdim  const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
4431249423Sdim  const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir)
4432249423Sdim                              + "/";
4433249423Sdim  const std::string StartFilesDir = RootDir
4434249423Sdim                                    + "hexagon/lib"
4435249423Sdim                                    + (buildingLib
4436249423Sdim                                       ? MarchG0Suffix : MarchSuffix);
4437234353Sdim
4438249423Sdim  //----------------------------------------------------------------------------
4439249423Sdim  // moslib
4440249423Sdim  //----------------------------------------------------------------------------
4441249423Sdim  std::vector<std::string> oslibs;
4442249423Sdim  bool hasStandalone= false;
4443249423Sdim
4444249423Sdim  for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ),
4445249423Sdim         ie = Args.filtered_end(); it != ie; ++it) {
4446249423Sdim    (*it)->claim();
4447249423Sdim    oslibs.push_back((*it)->getValue());
4448249423Sdim    hasStandalone = hasStandalone || (oslibs.back() == "standalone");
4449234353Sdim  }
4450249423Sdim  if (oslibs.empty()) {
4451249423Sdim    oslibs.push_back("standalone");
4452249423Sdim    hasStandalone = true;
4453249423Sdim  }
4454234353Sdim
4455249423Sdim  //----------------------------------------------------------------------------
4456249423Sdim  // Start Files
4457249423Sdim  //----------------------------------------------------------------------------
4458249423Sdim  if (incStdLib && incStartFiles) {
4459234353Sdim
4460249423Sdim    if (!buildingLib) {
4461249423Sdim      if (hasStandalone) {
4462249423Sdim        CmdArgs.push_back(
4463249423Sdim          Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
4464249423Sdim      }
4465249423Sdim      CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
4466249423Sdim    }
4467249423Sdim    std::string initObj = useShared ? "/initS.o" : "/init.o";
4468249423Sdim    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + initObj));
4469249423Sdim  }
4470234353Sdim
4471249423Sdim  //----------------------------------------------------------------------------
4472249423Sdim  // Library Search Paths
4473249423Sdim  //----------------------------------------------------------------------------
4474249423Sdim  const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
4475249423Sdim  for (ToolChain::path_list::const_iterator
4476249423Sdim         i = LibPaths.begin(),
4477249423Sdim         e = LibPaths.end();
4478249423Sdim       i != e;
4479249423Sdim       ++i)
4480249423Sdim    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
4481249423Sdim
4482249423Sdim  //----------------------------------------------------------------------------
4483249423Sdim  //
4484249423Sdim  //----------------------------------------------------------------------------
4485249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
4486249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
4487249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
4488249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
4489249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
4490249423Sdim
4491249423Sdim  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
4492249423Sdim
4493249423Sdim  //----------------------------------------------------------------------------
4494249423Sdim  // Libraries
4495249423Sdim  //----------------------------------------------------------------------------
4496249423Sdim  if (incStdLib && incDefLibs) {
4497263508Sdim    if (D.CCCIsCXX()) {
4498249423Sdim      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
4499249423Sdim      CmdArgs.push_back("-lm");
4500249423Sdim    }
4501249423Sdim
4502249423Sdim    CmdArgs.push_back("--start-group");
4503249423Sdim
4504249423Sdim    if (!buildingLib) {
4505249423Sdim      for(std::vector<std::string>::iterator i = oslibs.begin(),
4506249423Sdim            e = oslibs.end(); i != e; ++i)
4507249423Sdim        CmdArgs.push_back(Args.MakeArgString("-l" + *i));
4508249423Sdim      CmdArgs.push_back("-lc");
4509249423Sdim    }
4510249423Sdim    CmdArgs.push_back("-lgcc");
4511249423Sdim
4512249423Sdim    CmdArgs.push_back("--end-group");
4513234353Sdim  }
4514234353Sdim
4515249423Sdim  //----------------------------------------------------------------------------
4516249423Sdim  // End files
4517249423Sdim  //----------------------------------------------------------------------------
4518249423Sdim  if (incStdLib && incStartFiles) {
4519249423Sdim    std::string finiObj = useShared ? "/finiS.o" : "/fini.o";
4520249423Sdim    CmdArgs.push_back(Args.MakeArgString(StartFilesDir + finiObj));
4521249423Sdim  }
4522249423Sdim
4523249423Sdim  std::string Linker = ToolChain.GetProgramPath("hexagon-ld");
4524263508Sdim  C.addCommand(new Command(JA, *this, Args.MakeArgString(Linker), CmdArgs));
4525234353Sdim}
4526234353Sdim// Hexagon tools end.
4527234353Sdim
4528243830Sdimllvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
4529243830Sdim  // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
4530243830Sdim  // archs which Darwin doesn't use.
4531234353Sdim
4532243830Sdim  // The matching this routine does is fairly pointless, since it is neither the
4533243830Sdim  // complete architecture list, nor a reasonable subset. The problem is that
4534243830Sdim  // historically the driver driver accepts this and also ties its -march=
4535243830Sdim  // handling to the architecture name, so we need to be careful before removing
4536243830Sdim  // support for it.
4537243830Sdim
4538243830Sdim  // This code must be kept in sync with Clang's Darwin specific argument
4539243830Sdim  // translation.
4540243830Sdim
4541243830Sdim  return llvm::StringSwitch<llvm::Triple::ArchType>(Str)
4542243830Sdim    .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", llvm::Triple::ppc)
4543243830Sdim    .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", llvm::Triple::ppc)
4544243830Sdim    .Case("ppc64", llvm::Triple::ppc64)
4545243830Sdim    .Cases("i386", "i486", "i486SX", "i586", "i686", llvm::Triple::x86)
4546243830Sdim    .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
4547243830Sdim           llvm::Triple::x86)
4548263508Sdim    .Cases("x86_64", "x86_64h", llvm::Triple::x86_64)
4549243830Sdim    // This is derived from the driver driver.
4550249423Sdim    .Cases("arm", "armv4t", "armv5", "armv6", "armv6m", llvm::Triple::arm)
4551249423Sdim    .Cases("armv7", "armv7em", "armv7f", "armv7k", "armv7m", llvm::Triple::arm)
4552249423Sdim    .Cases("armv7s", "xscale", llvm::Triple::arm)
4553243830Sdim    .Case("r600", llvm::Triple::r600)
4554243830Sdim    .Case("nvptx", llvm::Triple::nvptx)
4555243830Sdim    .Case("nvptx64", llvm::Triple::nvptx64)
4556243830Sdim    .Case("amdil", llvm::Triple::amdil)
4557243830Sdim    .Case("spir", llvm::Triple::spir)
4558243830Sdim    .Default(llvm::Triple::UnknownArch);
4559243830Sdim}
4560243830Sdim
4561249423Sdimconst char *Clang::getBaseInputName(const ArgList &Args,
4562249423Sdim                                    const InputInfoList &Inputs) {
4563218893Sdim  return Args.MakeArgString(
4564218893Sdim    llvm::sys::path::filename(Inputs[0].getBaseInput()));
4565193326Sed}
4566193326Sed
4567249423Sdimconst char *Clang::getBaseInputStem(const ArgList &Args,
4568249423Sdim                                    const InputInfoList &Inputs) {
4569193326Sed  const char *Str = getBaseInputName(Args, Inputs);
4570193326Sed
4571218893Sdim  if (const char *End = strrchr(Str, '.'))
4572198092Srdivacky    return Args.MakeArgString(std::string(Str, End));
4573193326Sed
4574193326Sed  return Str;
4575193326Sed}
4576193326Sed
4577249423Sdimconst char *Clang::getDependencyFileName(const ArgList &Args,
4578249423Sdim                                         const InputInfoList &Inputs) {
4579193326Sed  // FIXME: Think about this more.
4580193326Sed  std::string Res;
4581193326Sed
4582193326Sed  if (Arg *OutputOpt = Args.getLastArg(options::OPT_o)) {
4583243830Sdim    std::string Str(OutputOpt->getValue());
4584193326Sed    Res = Str.substr(0, Str.rfind('.'));
4585226633Sdim  } else {
4586249423Sdim    Res = getBaseInputStem(Args, Inputs);
4587226633Sdim  }
4588198092Srdivacky  return Args.MakeArgString(Res + ".d");
4589193326Sed}
4590193326Sed
4591193326Sedvoid darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
4592212904Sdim                                    const InputInfo &Output,
4593193326Sed                                    const InputInfoList &Inputs,
4594193326Sed                                    const ArgList &Args,
4595193326Sed                                    const char *LinkingOutput) const {
4596193326Sed  ArgStringList CmdArgs;
4597193326Sed
4598193326Sed  assert(Inputs.size() == 1 && "Unexpected number of inputs.");
4599193326Sed  const InputInfo &Input = Inputs[0];
4600193326Sed
4601221345Sdim  // Determine the original source input.
4602221345Sdim  const Action *SourceAction = &JA;
4603221345Sdim  while (SourceAction->getKind() != Action::InputClass) {
4604221345Sdim    assert(!SourceAction->getInputs().empty() && "unexpected root action!");
4605221345Sdim    SourceAction = SourceAction->getInputs()[0];
4606221345Sdim  }
4607221345Sdim
4608263508Sdim  // If -no_integrated_as is used add -Q to the darwin assember driver to make
4609263508Sdim  // sure it runs its system assembler not clang's integrated assembler.
4610266715Sdim  // Applicable to darwin11+ and Xcode 4+.  darwin<10 lacked integrated-as.
4611266715Sdim  // FIXME: at run-time detect assembler capabilities or rely on version
4612266715Sdim  // information forwarded by -target-assembler-version (future)
4613266715Sdim  if (Args.hasArg(options::OPT_no_integrated_as)) {
4614266715Sdim    const llvm::Triple& t(getToolChain().getTriple());
4615266715Sdim    if (!(t.isMacOSX() && t.isMacOSXVersionLT(10, 7)))
4616266715Sdim      CmdArgs.push_back("-Q");
4617266715Sdim  }
4618263508Sdim
4619221345Sdim  // Forward -g, assuming we are dealing with an actual assembly file.
4620226633Sdim  if (SourceAction->getType() == types::TY_Asm ||
4621221345Sdim      SourceAction->getType() == types::TY_PP_Asm) {
4622193326Sed    if (Args.hasArg(options::OPT_gstabs))
4623193326Sed      CmdArgs.push_back("--gstabs");
4624193326Sed    else if (Args.hasArg(options::OPT_g_Group))
4625234353Sdim      CmdArgs.push_back("-g");
4626193326Sed  }
4627193326Sed
4628193326Sed  // Derived from asm spec.
4629198092Srdivacky  AddDarwinArch(Args, CmdArgs);
4630193326Sed
4631212904Sdim  // Use -force_cpusubtype_ALL on x86 by default.
4632263508Sdim  if (getToolChain().getArch() == llvm::Triple::x86 ||
4633263508Sdim      getToolChain().getArch() == llvm::Triple::x86_64 ||
4634198092Srdivacky      Args.hasArg(options::OPT_force__cpusubtype__ALL))
4635198092Srdivacky    CmdArgs.push_back("-force_cpusubtype_ALL");
4636198092Srdivacky
4637263508Sdim  if (getToolChain().getArch() != llvm::Triple::x86_64 &&
4638243830Sdim      (((Args.hasArg(options::OPT_mkernel) ||
4639243830Sdim         Args.hasArg(options::OPT_fapple_kext)) &&
4640243830Sdim        (!getDarwinToolChain().isTargetIPhoneOS() ||
4641243830Sdim         getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) ||
4642243830Sdim       Args.hasArg(options::OPT_static)))
4643193326Sed    CmdArgs.push_back("-static");
4644193326Sed
4645193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
4646193326Sed                       options::OPT_Xassembler);
4647193326Sed
4648193326Sed  assert(Output.isFilename() && "Unexpected lipo output.");
4649193326Sed  CmdArgs.push_back("-o");
4650193326Sed  CmdArgs.push_back(Output.getFilename());
4651193326Sed
4652212904Sdim  assert(Input.isFilename() && "Invalid input.");
4653212904Sdim  CmdArgs.push_back(Input.getFilename());
4654193326Sed
4655193326Sed  // asm_final spec is empty.
4656193326Sed
4657193326Sed  const char *Exec =
4658210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
4659212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4660193326Sed}
4661193326Sed
4662234353Sdimvoid darwin::DarwinTool::anchor() {}
4663234353Sdim
4664198092Srdivackyvoid darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
4665198092Srdivacky                                       ArgStringList &CmdArgs) const {
4666226633Sdim  StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
4667202879Srdivacky
4668193326Sed  // Derived from darwin_arch spec.
4669193326Sed  CmdArgs.push_back("-arch");
4670202879Srdivacky  CmdArgs.push_back(Args.MakeArgString(ArchName));
4671198092Srdivacky
4672202879Srdivacky  // FIXME: Is this needed anymore?
4673202879Srdivacky  if (ArchName == "arm")
4674198092Srdivacky    CmdArgs.push_back("-force_cpusubtype_ALL");
4675193326Sed}
4676193326Sed
4677243830Sdimbool darwin::Link::NeedsTempPath(const InputInfoList &Inputs) const {
4678243830Sdim  // We only need to generate a temp path for LTO if we aren't compiling object
4679243830Sdim  // files. When compiling source files, we run 'dsymutil' after linking. We
4680243830Sdim  // don't run 'dsymutil' when compiling object files.
4681243830Sdim  for (InputInfoList::const_iterator
4682243830Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
4683243830Sdim    if (it->getType() != types::TY_Object)
4684243830Sdim      return true;
4685243830Sdim
4686243830Sdim  return false;
4687243830Sdim}
4688243830Sdim
4689218893Sdimvoid darwin::Link::AddLinkArgs(Compilation &C,
4690218893Sdim                               const ArgList &Args,
4691243830Sdim                               ArgStringList &CmdArgs,
4692243830Sdim                               const InputInfoList &Inputs) const {
4693201361Srdivacky  const Driver &D = getToolChain().getDriver();
4694221345Sdim  const toolchains::Darwin &DarwinTC = getDarwinToolChain();
4695193326Sed
4696212904Sdim  unsigned Version[3] = { 0, 0, 0 };
4697212904Sdim  if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
4698212904Sdim    bool HadExtra;
4699243830Sdim    if (!Driver::GetReleaseVersion(A->getValue(), Version[0],
4700212904Sdim                                   Version[1], Version[2], HadExtra) ||
4701212904Sdim        HadExtra)
4702226633Sdim      D.Diag(diag::err_drv_invalid_version_number)
4703212904Sdim        << A->getAsString(Args);
4704212904Sdim  }
4705212904Sdim
4706212904Sdim  // Newer linkers support -demangle, pass it if supported and not disabled by
4707212904Sdim  // the user.
4708234353Sdim  if (Version[0] >= 100 && !Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) {
4709218893Sdim    // Don't pass -demangle to ld_classic.
4710218893Sdim    //
4711218893Sdim    // FIXME: This is a temporary workaround, ld should be handling this.
4712218893Sdim    bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 &&
4713218893Sdim                          Args.hasArg(options::OPT_static));
4714218893Sdim    if (getToolChain().getArch() == llvm::Triple::x86) {
4715218893Sdim      for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker,
4716218893Sdim                                                 options::OPT_Wl_COMMA),
4717218893Sdim             ie = Args.filtered_end(); it != ie; ++it) {
4718218893Sdim        const Arg *A = *it;
4719218893Sdim        for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
4720243830Sdim          if (StringRef(A->getValue(i)) == "-kext")
4721218893Sdim            UsesLdClassic = true;
4722218893Sdim      }
4723218893Sdim    }
4724218893Sdim    if (!UsesLdClassic)
4725218893Sdim      CmdArgs.push_back("-demangle");
4726212904Sdim  }
4727212904Sdim
4728263508Sdim  if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
4729263508Sdim    CmdArgs.push_back("-export_dynamic");
4730263508Sdim
4731224145Sdim  // If we are using LTO, then automatically create a temporary file path for
4732224145Sdim  // the linker to use, so that it's lifetime will extend past a possible
4733224145Sdim  // dsymutil step.
4734243830Sdim  if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
4735224145Sdim    const char *TmpPath = C.getArgs().MakeArgString(
4736226633Sdim      D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
4737224145Sdim    C.addTempFile(TmpPath);
4738224145Sdim    CmdArgs.push_back("-object_path_lto");
4739224145Sdim    CmdArgs.push_back(TmpPath);
4740224145Sdim  }
4741224145Sdim
4742193326Sed  // Derived from the "link" spec.
4743193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_static);
4744193326Sed  if (!Args.hasArg(options::OPT_static))
4745193326Sed    CmdArgs.push_back("-dynamic");
4746193326Sed  if (Args.hasArg(options::OPT_fgnu_runtime)) {
4747193326Sed    // FIXME: gcc replaces -lobjc in forward args with -lobjc-gnu
4748193326Sed    // here. How do we wish to handle such things?
4749193326Sed  }
4750193326Sed
4751193326Sed  if (!Args.hasArg(options::OPT_dynamiclib)) {
4752202879Srdivacky    AddDarwinArch(Args, CmdArgs);
4753202879Srdivacky    // FIXME: Why do this only on this path?
4754202879Srdivacky    Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
4755193326Sed
4756193326Sed    Args.AddLastArg(CmdArgs, options::OPT_bundle);
4757193326Sed    Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader);
4758193326Sed    Args.AddAllArgs(CmdArgs, options::OPT_client__name);
4759193326Sed
4760193326Sed    Arg *A;
4761193326Sed    if ((A = Args.getLastArg(options::OPT_compatibility__version)) ||
4762193326Sed        (A = Args.getLastArg(options::OPT_current__version)) ||
4763193326Sed        (A = Args.getLastArg(options::OPT_install__name)))
4764226633Sdim      D.Diag(diag::err_drv_argument_only_allowed_with)
4765193326Sed        << A->getAsString(Args) << "-dynamiclib";
4766193326Sed
4767193326Sed    Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace);
4768193326Sed    Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs);
4769193326Sed    Args.AddLastArg(CmdArgs, options::OPT_private__bundle);
4770193326Sed  } else {
4771193326Sed    CmdArgs.push_back("-dylib");
4772193326Sed
4773193326Sed    Arg *A;
4774193326Sed    if ((A = Args.getLastArg(options::OPT_bundle)) ||
4775193326Sed        (A = Args.getLastArg(options::OPT_bundle__loader)) ||
4776193326Sed        (A = Args.getLastArg(options::OPT_client__name)) ||
4777193326Sed        (A = Args.getLastArg(options::OPT_force__flat__namespace)) ||
4778193326Sed        (A = Args.getLastArg(options::OPT_keep__private__externs)) ||
4779193326Sed        (A = Args.getLastArg(options::OPT_private__bundle)))
4780226633Sdim      D.Diag(diag::err_drv_argument_not_allowed_with)
4781193326Sed        << A->getAsString(Args) << "-dynamiclib";
4782193326Sed
4783193326Sed    Args.AddAllArgsTranslated(CmdArgs, options::OPT_compatibility__version,
4784193326Sed                              "-dylib_compatibility_version");
4785193326Sed    Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
4786193326Sed                              "-dylib_current_version");
4787193326Sed
4788202879Srdivacky    AddDarwinArch(Args, CmdArgs);
4789193326Sed
4790193326Sed    Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
4791193326Sed                              "-dylib_install_name");
4792193326Sed  }
4793193326Sed
4794193326Sed  Args.AddLastArg(CmdArgs, options::OPT_all__load);
4795193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
4796193326Sed  Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
4797221345Sdim  if (DarwinTC.isTargetIPhoneOS())
4798198092Srdivacky    Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
4799193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
4800193326Sed  Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
4801193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_dylib__file);
4802193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dynamic);
4803193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_exported__symbols__list);
4804193326Sed  Args.AddLastArg(CmdArgs, options::OPT_flat__namespace);
4805224145Sdim  Args.AddAllArgs(CmdArgs, options::OPT_force__load);
4806193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_headerpad__max__install__names);
4807193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_image__base);
4808193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_init);
4809193326Sed
4810221345Sdim  // Add the deployment target.
4811234353Sdim  VersionTuple TargetVersion = DarwinTC.getTargetVersion();
4812221345Sdim
4813221345Sdim  // If we had an explicit -mios-simulator-version-min argument, honor that,
4814221345Sdim  // otherwise use the traditional deployment targets. We can't just check the
4815221345Sdim  // is-sim attribute because existing code follows this path, and the linker
4816221345Sdim  // may not handle the argument.
4817221345Sdim  //
4818221345Sdim  // FIXME: We may be able to remove this, once we can verify no one depends on
4819221345Sdim  // it.
4820221345Sdim  if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
4821221345Sdim    CmdArgs.push_back("-ios_simulator_version_min");
4822221345Sdim  else if (DarwinTC.isTargetIPhoneOS())
4823221345Sdim    CmdArgs.push_back("-iphoneos_version_min");
4824221345Sdim  else
4825221345Sdim    CmdArgs.push_back("-macosx_version_min");
4826234353Sdim  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
4827221345Sdim
4828193326Sed  Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
4829193326Sed  Args.AddLastArg(CmdArgs, options::OPT_multi__module);
4830193326Sed  Args.AddLastArg(CmdArgs, options::OPT_single__module);
4831193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined);
4832193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_multiply__defined__unused);
4833193326Sed
4834210299Sed  if (const Arg *A = Args.getLastArg(options::OPT_fpie, options::OPT_fPIE,
4835210299Sed                                     options::OPT_fno_pie,
4836210299Sed                                     options::OPT_fno_PIE)) {
4837210299Sed    if (A->getOption().matches(options::OPT_fpie) ||
4838210299Sed        A->getOption().matches(options::OPT_fPIE))
4839210299Sed      CmdArgs.push_back("-pie");
4840210299Sed    else
4841210299Sed      CmdArgs.push_back("-no_pie");
4842210299Sed  }
4843193326Sed
4844193326Sed  Args.AddLastArg(CmdArgs, options::OPT_prebind);
4845193326Sed  Args.AddLastArg(CmdArgs, options::OPT_noprebind);
4846193326Sed  Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
4847193326Sed  Args.AddLastArg(CmdArgs, options::OPT_prebind__all__twolevel__modules);
4848193326Sed  Args.AddLastArg(CmdArgs, options::OPT_read__only__relocs);
4849193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectcreate);
4850193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectorder);
4851193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_seg1addr);
4852193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segprot);
4853193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segaddr);
4854193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__only__addr);
4855193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__write__addr);
4856193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table);
4857193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_seg__addr__table__filename);
4858193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
4859193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
4860198092Srdivacky
4861223017Sdim  // Give --sysroot= preference, over the Apple specific behavior to also use
4862223017Sdim  // --isysroot as the syslibroot.
4863234982Sdim  StringRef sysroot = C.getSysRoot();
4864234982Sdim  if (sysroot != "") {
4865223017Sdim    CmdArgs.push_back("-syslibroot");
4866234982Sdim    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
4867223017Sdim  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
4868223017Sdim    CmdArgs.push_back("-syslibroot");
4869243830Sdim    CmdArgs.push_back(A->getValue());
4870198092Srdivacky  }
4871198092Srdivacky
4872193326Sed  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
4873193326Sed  Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace__hints);
4874193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_umbrella);
4875193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_undefined);
4876193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_unexported__symbols__list);
4877193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_weak__reference__mismatches);
4878193326Sed  Args.AddLastArg(CmdArgs, options::OPT_X_Flag);
4879193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_y);
4880193326Sed  Args.AddLastArg(CmdArgs, options::OPT_w);
4881193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_pagezero__size);
4882193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segs__read__);
4883193326Sed  Args.AddLastArg(CmdArgs, options::OPT_seglinkedit);
4884193326Sed  Args.AddLastArg(CmdArgs, options::OPT_noseglinkedit);
4885193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectalign);
4886193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_sectobjectsymbols);
4887193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_segcreate);
4888193326Sed  Args.AddLastArg(CmdArgs, options::OPT_whyload);
4889193326Sed  Args.AddLastArg(CmdArgs, options::OPT_whatsloaded);
4890193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_dylinker__install__name);
4891193326Sed  Args.AddLastArg(CmdArgs, options::OPT_dylinker);
4892193326Sed  Args.AddLastArg(CmdArgs, options::OPT_Mach);
4893193326Sed}
4894193326Sed
4895193326Sedvoid darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
4896212904Sdim                                const InputInfo &Output,
4897193326Sed                                const InputInfoList &Inputs,
4898193326Sed                                const ArgList &Args,
4899193326Sed                                const char *LinkingOutput) const {
4900193326Sed  assert(Output.getType() == types::TY_Image && "Invalid linker output type.");
4901198092Srdivacky
4902193326Sed  // The logic here is derived from gcc's behavior; most of which
4903193326Sed  // comes from specs (starting with link_command). Consult gcc for
4904193326Sed  // more information.
4905193326Sed  ArgStringList CmdArgs;
4906193326Sed
4907226633Sdim  /// Hack(tm) to ignore linking errors when we are doing ARC migration.
4908226633Sdim  if (Args.hasArg(options::OPT_ccc_arcmt_check,
4909226633Sdim                  options::OPT_ccc_arcmt_migrate)) {
4910226633Sdim    for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I)
4911226633Sdim      (*I)->claim();
4912226633Sdim    const char *Exec =
4913226633Sdim      Args.MakeArgString(getToolChain().GetProgramPath("touch"));
4914226633Sdim    CmdArgs.push_back(Output.getFilename());
4915226633Sdim    C.addCommand(new Command(JA, *this, Exec, CmdArgs));
4916226633Sdim    return;
4917226633Sdim  }
4918226633Sdim
4919193326Sed  // I'm not sure why this particular decomposition exists in gcc, but
4920193326Sed  // we follow suite for ease of comparison.
4921243830Sdim  AddLinkArgs(C, Args, CmdArgs, Inputs);
4922193326Sed
4923193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_d_Flag);
4924193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_s);
4925193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_t);
4926193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
4927193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
4928193326Sed  Args.AddLastArg(CmdArgs, options::OPT_e);
4929193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_r);
4930193326Sed
4931218893Sdim  // Forward -ObjC when either -ObjC or -ObjC++ is used, to force loading
4932218893Sdim  // members of static archive libraries which implement Objective-C classes or
4933218893Sdim  // categories.
4934218893Sdim  if (Args.hasArg(options::OPT_ObjC) || Args.hasArg(options::OPT_ObjCXX))
4935218893Sdim    CmdArgs.push_back("-ObjC");
4936218893Sdim
4937193326Sed  CmdArgs.push_back("-o");
4938193326Sed  CmdArgs.push_back(Output.getFilename());
4939193326Sed
4940239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
4941193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
4942193326Sed    // Derived from startfile spec.
4943193326Sed    if (Args.hasArg(options::OPT_dynamiclib)) {
4944193326Sed      // Derived from darwin_dylib1 spec.
4945221345Sdim      if (getDarwinToolChain().isTargetIOSSimulator()) {
4946221345Sdim        // The simulator doesn't have a versioned crt1 file.
4947221345Sdim        CmdArgs.push_back("-ldylib1.o");
4948221345Sdim      } else if (getDarwinToolChain().isTargetIPhoneOS()) {
4949203955Srdivacky        if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
4950203955Srdivacky          CmdArgs.push_back("-ldylib1.o");
4951203955Srdivacky      } else {
4952203955Srdivacky        if (getDarwinToolChain().isMacosxVersionLT(10, 5))
4953203955Srdivacky          CmdArgs.push_back("-ldylib1.o");
4954203955Srdivacky        else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
4955203955Srdivacky          CmdArgs.push_back("-ldylib1.10.5.o");
4956203955Srdivacky      }
4957193326Sed    } else {
4958193326Sed      if (Args.hasArg(options::OPT_bundle)) {
4959193326Sed        if (!Args.hasArg(options::OPT_static)) {
4960193326Sed          // Derived from darwin_bundle1 spec.
4961221345Sdim          if (getDarwinToolChain().isTargetIOSSimulator()) {
4962221345Sdim            // The simulator doesn't have a versioned crt1 file.
4963221345Sdim            CmdArgs.push_back("-lbundle1.o");
4964221345Sdim          } else if (getDarwinToolChain().isTargetIPhoneOS()) {
4965203955Srdivacky            if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
4966203955Srdivacky              CmdArgs.push_back("-lbundle1.o");
4967203955Srdivacky          } else {
4968203955Srdivacky            if (getDarwinToolChain().isMacosxVersionLT(10, 6))
4969203955Srdivacky              CmdArgs.push_back("-lbundle1.o");
4970203955Srdivacky          }
4971193326Sed        }
4972193326Sed      } else {
4973221345Sdim        if (Args.hasArg(options::OPT_pg) &&
4974221345Sdim            getToolChain().SupportsProfiling()) {
4975193326Sed          if (Args.hasArg(options::OPT_static) ||
4976193326Sed              Args.hasArg(options::OPT_object) ||
4977193326Sed              Args.hasArg(options::OPT_preload)) {
4978193326Sed            CmdArgs.push_back("-lgcrt0.o");
4979193326Sed          } else {
4980193326Sed            CmdArgs.push_back("-lgcrt1.o");
4981193326Sed
4982193326Sed            // darwin_crt2 spec is empty.
4983193326Sed          }
4984239462Sdim          // By default on OS X 10.8 and later, we don't link with a crt1.o
4985239462Sdim          // file and the linker knows to use _main as the entry point.  But,
4986239462Sdim          // when compiling with -pg, we need to link with the gcrt1.o file,
4987239462Sdim          // so pass the -no_new_main option to tell the linker to use the
4988239462Sdim          // "start" symbol as the entry point.
4989239462Sdim          if (getDarwinToolChain().isTargetMacOS() &&
4990239462Sdim              !getDarwinToolChain().isMacosxVersionLT(10, 8))
4991239462Sdim            CmdArgs.push_back("-no_new_main");
4992193326Sed        } else {
4993193326Sed          if (Args.hasArg(options::OPT_static) ||
4994193326Sed              Args.hasArg(options::OPT_object) ||
4995193326Sed              Args.hasArg(options::OPT_preload)) {
4996193326Sed            CmdArgs.push_back("-lcrt0.o");
4997193326Sed          } else {
4998193326Sed            // Derived from darwin_crt1 spec.
4999221345Sdim            if (getDarwinToolChain().isTargetIOSSimulator()) {
5000221345Sdim              // The simulator doesn't have a versioned crt1 file.
5001221345Sdim              CmdArgs.push_back("-lcrt1.o");
5002221345Sdim            } else if (getDarwinToolChain().isTargetIPhoneOS()) {
5003203955Srdivacky              if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
5004203955Srdivacky                CmdArgs.push_back("-lcrt1.o");
5005243830Sdim              else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0))
5006203955Srdivacky                CmdArgs.push_back("-lcrt1.3.1.o");
5007203955Srdivacky            } else {
5008203955Srdivacky              if (getDarwinToolChain().isMacosxVersionLT(10, 5))
5009203955Srdivacky                CmdArgs.push_back("-lcrt1.o");
5010203955Srdivacky              else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
5011203955Srdivacky                CmdArgs.push_back("-lcrt1.10.5.o");
5012234353Sdim              else if (getDarwinToolChain().isMacosxVersionLT(10, 8))
5013203955Srdivacky                CmdArgs.push_back("-lcrt1.10.6.o");
5014193326Sed
5015203955Srdivacky              // darwin_crt2 spec is empty.
5016203955Srdivacky            }
5017193326Sed          }
5018193326Sed        }
5019193326Sed      }
5020193326Sed    }
5021193326Sed
5022203955Srdivacky    if (!getDarwinToolChain().isTargetIPhoneOS() &&
5023203955Srdivacky        Args.hasArg(options::OPT_shared_libgcc) &&
5024203955Srdivacky        getDarwinToolChain().isMacosxVersionLT(10, 5)) {
5025198092Srdivacky      const char *Str =
5026210299Sed        Args.MakeArgString(getToolChain().GetFilePath("crt3.o"));
5027198092Srdivacky      CmdArgs.push_back(Str);
5028193326Sed    }
5029193326Sed  }
5030193326Sed
5031193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
5032193326Sed
5033193326Sed  if (Args.hasArg(options::OPT_fopenmp))
5034193326Sed    // This is more complicated in gcc...
5035193326Sed    CmdArgs.push_back("-lgomp");
5036193326Sed
5037239462Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5038239462Sdim
5039239462Sdim  if (isObjCRuntimeLinked(Args) &&
5040239462Sdim      !Args.hasArg(options::OPT_nostdlib) &&
5041239462Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5042234353Sdim    // Avoid linking compatibility stubs on i386 mac.
5043234353Sdim    if (!getDarwinToolChain().isTargetMacOS() ||
5044243830Sdim        getDarwinToolChain().getArch() != llvm::Triple::x86) {
5045234353Sdim      // If we don't have ARC or subscripting runtime support, link in the
5046234353Sdim      // runtime stubs.  We have to do this *before* adding any of the normal
5047234353Sdim      // linker inputs so that its initializer gets run first.
5048239462Sdim      ObjCRuntime runtime =
5049239462Sdim        getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true);
5050234353Sdim      // We use arclite library for both ARC and subscripting support.
5051243830Sdim      if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) ||
5052239462Sdim          !runtime.hasSubscripting())
5053234353Sdim        getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
5054234353Sdim    }
5055239462Sdim    CmdArgs.push_back("-framework");
5056239462Sdim    CmdArgs.push_back("Foundation");
5057234353Sdim    // Link libobj.
5058234353Sdim    CmdArgs.push_back("-lobjc");
5059224145Sdim  }
5060224145Sdim
5061193326Sed  if (LinkingOutput) {
5062193326Sed    CmdArgs.push_back("-arch_multiple");
5063193326Sed    CmdArgs.push_back("-final_output");
5064193326Sed    CmdArgs.push_back(LinkingOutput);
5065193326Sed  }
5066193326Sed
5067193326Sed  if (Args.hasArg(options::OPT_fnested_functions))
5068193326Sed    CmdArgs.push_back("-allow_stack_execute");
5069193326Sed
5070193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5071193326Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
5072263508Sdim    if (getToolChain().getDriver().CCCIsCXX())
5073218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5074193326Sed
5075193326Sed    // link_ssp spec is empty.
5076193326Sed
5077198092Srdivacky    // Let the tool chain choose which runtime library to link.
5078198092Srdivacky    getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
5079193326Sed  }
5080193326Sed
5081239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5082193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5083193326Sed    // endfile_spec is empty.
5084193326Sed  }
5085193326Sed
5086193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5087193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_F);
5088193326Sed
5089193326Sed  const char *Exec =
5090210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5091212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5092193326Sed}
5093193326Sed
5094193326Sedvoid darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
5095212904Sdim                                const InputInfo &Output,
5096193326Sed                                const InputInfoList &Inputs,
5097193326Sed                                const ArgList &Args,
5098193326Sed                                const char *LinkingOutput) const {
5099193326Sed  ArgStringList CmdArgs;
5100193326Sed
5101193326Sed  CmdArgs.push_back("-create");
5102193326Sed  assert(Output.isFilename() && "Unexpected lipo output.");
5103193326Sed
5104193326Sed  CmdArgs.push_back("-output");
5105193326Sed  CmdArgs.push_back(Output.getFilename());
5106193326Sed
5107193326Sed  for (InputInfoList::const_iterator
5108193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5109193326Sed    const InputInfo &II = *it;
5110193326Sed    assert(II.isFilename() && "Unexpected lipo input.");
5111193326Sed    CmdArgs.push_back(II.getFilename());
5112193326Sed  }
5113193326Sed  const char *Exec =
5114210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
5115212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5116193326Sed}
5117193326Sed
5118210299Sedvoid darwin::Dsymutil::ConstructJob(Compilation &C, const JobAction &JA,
5119212904Sdim                                    const InputInfo &Output,
5120210299Sed                                    const InputInfoList &Inputs,
5121210299Sed                                    const ArgList &Args,
5122210299Sed                                    const char *LinkingOutput) const {
5123210299Sed  ArgStringList CmdArgs;
5124210299Sed
5125223017Sdim  CmdArgs.push_back("-o");
5126223017Sdim  CmdArgs.push_back(Output.getFilename());
5127223017Sdim
5128210299Sed  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
5129210299Sed  const InputInfo &Input = Inputs[0];
5130210299Sed  assert(Input.isFilename() && "Unexpected dsymutil input.");
5131210299Sed  CmdArgs.push_back(Input.getFilename());
5132210299Sed
5133210299Sed  const char *Exec =
5134210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("dsymutil"));
5135212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5136210299Sed}
5137210299Sed
5138226633Sdimvoid darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA,
5139249423Sdim                                       const InputInfo &Output,
5140249423Sdim                                       const InputInfoList &Inputs,
5141249423Sdim                                       const ArgList &Args,
5142249423Sdim                                       const char *LinkingOutput) const {
5143226633Sdim  ArgStringList CmdArgs;
5144226633Sdim  CmdArgs.push_back("--verify");
5145234353Sdim  CmdArgs.push_back("--debug-info");
5146234353Sdim  CmdArgs.push_back("--eh-frame");
5147234353Sdim  CmdArgs.push_back("--quiet");
5148226633Sdim
5149226633Sdim  assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
5150226633Sdim  const InputInfo &Input = Inputs[0];
5151226633Sdim  assert(Input.isFilename() && "Unexpected verify input");
5152226633Sdim
5153226633Sdim  // Grabbing the output of the earlier dsymutil run.
5154226633Sdim  CmdArgs.push_back(Input.getFilename());
5155226633Sdim
5156226633Sdim  const char *Exec =
5157226633Sdim    Args.MakeArgString(getToolChain().GetProgramPath("dwarfdump"));
5158226633Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5159226633Sdim}
5160226633Sdim
5161234353Sdimvoid solaris::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5162234353Sdim                                      const InputInfo &Output,
5163234353Sdim                                      const InputInfoList &Inputs,
5164234353Sdim                                      const ArgList &Args,
5165234353Sdim                                      const char *LinkingOutput) const {
5166234353Sdim  ArgStringList CmdArgs;
5167234353Sdim
5168234353Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5169234353Sdim                       options::OPT_Xassembler);
5170234353Sdim
5171234353Sdim  CmdArgs.push_back("-o");
5172234353Sdim  CmdArgs.push_back(Output.getFilename());
5173234353Sdim
5174234353Sdim  for (InputInfoList::const_iterator
5175234353Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5176234353Sdim    const InputInfo &II = *it;
5177234353Sdim    CmdArgs.push_back(II.getFilename());
5178234353Sdim  }
5179234353Sdim
5180234353Sdim  const char *Exec =
5181234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5182234353Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5183234353Sdim}
5184234353Sdim
5185234353Sdim
5186234353Sdimvoid solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
5187234353Sdim                                  const InputInfo &Output,
5188234353Sdim                                  const InputInfoList &Inputs,
5189234353Sdim                                  const ArgList &Args,
5190234353Sdim                                  const char *LinkingOutput) const {
5191234353Sdim  // FIXME: Find a real GCC, don't hard-code versions here
5192234353Sdim  std::string GCCLibPath = "/usr/gcc/4.5/lib/gcc/";
5193234353Sdim  const llvm::Triple &T = getToolChain().getTriple();
5194234353Sdim  std::string LibPath = "/usr/lib/";
5195234353Sdim  llvm::Triple::ArchType Arch = T.getArch();
5196234353Sdim  switch (Arch) {
5197263508Sdim  case llvm::Triple::x86:
5198263508Sdim    GCCLibPath +=
5199263508Sdim        ("i386-" + T.getVendorName() + "-" + T.getOSName()).str() + "/4.5.2/";
5200263508Sdim    break;
5201263508Sdim  case llvm::Triple::x86_64:
5202263508Sdim    GCCLibPath += ("i386-" + T.getVendorName() + "-" + T.getOSName()).str();
5203263508Sdim    GCCLibPath += "/4.5.2/amd64/";
5204263508Sdim    LibPath += "amd64/";
5205263508Sdim    break;
5206263508Sdim  default:
5207263508Sdim    llvm_unreachable("Unsupported architecture");
5208234353Sdim  }
5209234353Sdim
5210234353Sdim  ArgStringList CmdArgs;
5211234353Sdim
5212234353Sdim  // Demangle C++ names in errors
5213234353Sdim  CmdArgs.push_back("-C");
5214234353Sdim
5215234353Sdim  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5216234353Sdim      (!Args.hasArg(options::OPT_shared))) {
5217234353Sdim    CmdArgs.push_back("-e");
5218234353Sdim    CmdArgs.push_back("_start");
5219234353Sdim  }
5220234353Sdim
5221234353Sdim  if (Args.hasArg(options::OPT_static)) {
5222234353Sdim    CmdArgs.push_back("-Bstatic");
5223234353Sdim    CmdArgs.push_back("-dn");
5224234353Sdim  } else {
5225234353Sdim    CmdArgs.push_back("-Bdynamic");
5226234353Sdim    if (Args.hasArg(options::OPT_shared)) {
5227234353Sdim      CmdArgs.push_back("-shared");
5228234353Sdim    } else {
5229234353Sdim      CmdArgs.push_back("--dynamic-linker");
5230234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "ld.so.1"));
5231234353Sdim    }
5232234353Sdim  }
5233234353Sdim
5234234353Sdim  if (Output.isFilename()) {
5235234353Sdim    CmdArgs.push_back("-o");
5236234353Sdim    CmdArgs.push_back(Output.getFilename());
5237234353Sdim  } else {
5238234353Sdim    assert(Output.isNothing() && "Invalid output.");
5239234353Sdim  }
5240234353Sdim
5241234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5242234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5243234353Sdim    if (!Args.hasArg(options::OPT_shared)) {
5244234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "crt1.o"));
5245234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
5246234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
5247234353Sdim      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
5248234353Sdim    } else {
5249234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
5250234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
5251234353Sdim      CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
5252234353Sdim    }
5253263508Sdim    if (getToolChain().getDriver().CCCIsCXX())
5254234353Sdim      CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
5255234353Sdim  }
5256234353Sdim
5257234353Sdim  CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath));
5258234353Sdim
5259234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
5260234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5261234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
5262234353Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
5263234353Sdim
5264234353Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5265234353Sdim
5266234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5267234353Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5268263508Sdim    if (getToolChain().getDriver().CCCIsCXX())
5269234353Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5270234353Sdim    CmdArgs.push_back("-lgcc_s");
5271234353Sdim    if (!Args.hasArg(options::OPT_shared)) {
5272234353Sdim      CmdArgs.push_back("-lgcc");
5273234353Sdim      CmdArgs.push_back("-lc");
5274234353Sdim      CmdArgs.push_back("-lm");
5275234353Sdim    }
5276234353Sdim  }
5277234353Sdim
5278234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5279234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5280234353Sdim    CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtend.o"));
5281234353Sdim  }
5282234353Sdim  CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
5283234353Sdim
5284234353Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
5285234353Sdim
5286234353Sdim  const char *Exec =
5287234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5288234353Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5289234353Sdim}
5290234353Sdim
5291198092Srdivackyvoid auroraux::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5292212904Sdim                                      const InputInfo &Output,
5293198893Srdivacky                                      const InputInfoList &Inputs,
5294198893Srdivacky                                      const ArgList &Args,
5295198893Srdivacky                                      const char *LinkingOutput) const {
5296198092Srdivacky  ArgStringList CmdArgs;
5297198092Srdivacky
5298198092Srdivacky  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5299198092Srdivacky                       options::OPT_Xassembler);
5300198092Srdivacky
5301198092Srdivacky  CmdArgs.push_back("-o");
5302212904Sdim  CmdArgs.push_back(Output.getFilename());
5303198092Srdivacky
5304198092Srdivacky  for (InputInfoList::const_iterator
5305198092Srdivacky         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5306198092Srdivacky    const InputInfo &II = *it;
5307212904Sdim    CmdArgs.push_back(II.getFilename());
5308198092Srdivacky  }
5309198092Srdivacky
5310198092Srdivacky  const char *Exec =
5311210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
5312212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5313198092Srdivacky}
5314198092Srdivacky
5315198092Srdivackyvoid auroraux::Link::ConstructJob(Compilation &C, const JobAction &JA,
5316212904Sdim                                  const InputInfo &Output,
5317198893Srdivacky                                  const InputInfoList &Inputs,
5318198893Srdivacky                                  const ArgList &Args,
5319198893Srdivacky                                  const char *LinkingOutput) const {
5320198092Srdivacky  ArgStringList CmdArgs;
5321198092Srdivacky
5322198092Srdivacky  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5323198893Srdivacky      (!Args.hasArg(options::OPT_shared))) {
5324198092Srdivacky    CmdArgs.push_back("-e");
5325198398Srdivacky    CmdArgs.push_back("_start");
5326198092Srdivacky  }
5327198092Srdivacky
5328198092Srdivacky  if (Args.hasArg(options::OPT_static)) {
5329198092Srdivacky    CmdArgs.push_back("-Bstatic");
5330198398Srdivacky    CmdArgs.push_back("-dn");
5331198092Srdivacky  } else {
5332198398Srdivacky//    CmdArgs.push_back("--eh-frame-hdr");
5333198092Srdivacky    CmdArgs.push_back("-Bdynamic");
5334198092Srdivacky    if (Args.hasArg(options::OPT_shared)) {
5335198092Srdivacky      CmdArgs.push_back("-shared");
5336198092Srdivacky    } else {
5337198398Srdivacky      CmdArgs.push_back("--dynamic-linker");
5338198092Srdivacky      CmdArgs.push_back("/lib/ld.so.1"); // 64Bit Path /lib/amd64/ld.so.1
5339198092Srdivacky    }
5340198092Srdivacky  }
5341198092Srdivacky
5342212904Sdim  if (Output.isFilename()) {
5343198092Srdivacky    CmdArgs.push_back("-o");
5344198092Srdivacky    CmdArgs.push_back(Output.getFilename());
5345198092Srdivacky  } else {
5346198092Srdivacky    assert(Output.isNothing() && "Invalid output.");
5347198092Srdivacky  }
5348198092Srdivacky
5349198092Srdivacky  if (!Args.hasArg(options::OPT_nostdlib) &&
5350198092Srdivacky      !Args.hasArg(options::OPT_nostartfiles)) {
5351198092Srdivacky    if (!Args.hasArg(options::OPT_shared)) {
5352210299Sed      CmdArgs.push_back(Args.MakeArgString(
5353210299Sed                                getToolChain().GetFilePath("crt1.o")));
5354210299Sed      CmdArgs.push_back(Args.MakeArgString(
5355210299Sed                                getToolChain().GetFilePath("crti.o")));
5356210299Sed      CmdArgs.push_back(Args.MakeArgString(
5357210299Sed                                getToolChain().GetFilePath("crtbegin.o")));
5358198092Srdivacky    } else {
5359210299Sed      CmdArgs.push_back(Args.MakeArgString(
5360210299Sed                                getToolChain().GetFilePath("crti.o")));
5361198092Srdivacky    }
5362210299Sed    CmdArgs.push_back(Args.MakeArgString(
5363210299Sed                                getToolChain().GetFilePath("crtn.o")));
5364198092Srdivacky  }
5365198092Srdivacky
5366198893Srdivacky  CmdArgs.push_back(Args.MakeArgString("-L/opt/gcc4/lib/gcc/"
5367198893Srdivacky                                       + getToolChain().getTripleString()
5368198893Srdivacky                                       + "/4.2.4"));
5369198092Srdivacky
5370198092Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_L);
5371198092Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5372198092Srdivacky  Args.AddAllArgs(CmdArgs, options::OPT_e);
5373198092Srdivacky
5374218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5375198092Srdivacky
5376198092Srdivacky  if (!Args.hasArg(options::OPT_nostdlib) &&
5377198092Srdivacky      !Args.hasArg(options::OPT_nodefaultlibs)) {
5378198092Srdivacky    // FIXME: For some reason GCC passes -lgcc before adding
5379198092Srdivacky    // the default system libraries. Just mimic this for now.
5380198092Srdivacky    CmdArgs.push_back("-lgcc");
5381198092Srdivacky
5382198092Srdivacky    if (Args.hasArg(options::OPT_pthread))
5383198092Srdivacky      CmdArgs.push_back("-pthread");
5384198092Srdivacky    if (!Args.hasArg(options::OPT_shared))
5385198092Srdivacky      CmdArgs.push_back("-lc");
5386198092Srdivacky    CmdArgs.push_back("-lgcc");
5387198092Srdivacky  }
5388198092Srdivacky
5389198092Srdivacky  if (!Args.hasArg(options::OPT_nostdlib) &&
5390198092Srdivacky      !Args.hasArg(options::OPT_nostartfiles)) {
5391198092Srdivacky    if (!Args.hasArg(options::OPT_shared))
5392210299Sed      CmdArgs.push_back(Args.MakeArgString(
5393210299Sed                                getToolChain().GetFilePath("crtend.o")));
5394198092Srdivacky  }
5395198092Srdivacky
5396224145Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
5397223017Sdim
5398198092Srdivacky  const char *Exec =
5399210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5400212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5401198092Srdivacky}
5402198092Srdivacky
5403195341Sedvoid openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5404212904Sdim                                     const InputInfo &Output,
5405195341Sed                                     const InputInfoList &Inputs,
5406195341Sed                                     const ArgList &Args,
5407198092Srdivacky                                     const char *LinkingOutput) const {
5408195341Sed  ArgStringList CmdArgs;
5409193326Sed
5410263508Sdim  // When building 32-bit code on OpenBSD/amd64, we have to explicitly
5411263508Sdim  // instruct as in the base system to assemble 32-bit code.
5412263508Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
5413263508Sdim    CmdArgs.push_back("--32");
5414263508Sdim  else if (getToolChain().getArch() == llvm::Triple::ppc) {
5415263508Sdim    CmdArgs.push_back("-mppc");
5416263508Sdim    CmdArgs.push_back("-many");
5417263508Sdim  } else if (getToolChain().getArch() == llvm::Triple::mips64 ||
5418263508Sdim             getToolChain().getArch() == llvm::Triple::mips64el) {
5419263508Sdim    StringRef CPUName;
5420263508Sdim    StringRef ABIName;
5421263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
5422263508Sdim
5423263508Sdim    CmdArgs.push_back("-mabi");
5424263508Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
5425263508Sdim
5426263508Sdim    if (getToolChain().getArch() == llvm::Triple::mips64)
5427263508Sdim      CmdArgs.push_back("-EB");
5428263508Sdim    else
5429263508Sdim      CmdArgs.push_back("-EL");
5430263508Sdim
5431263508Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
5432263508Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
5433263508Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
5434263508Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
5435263508Sdim    if (LastPICArg &&
5436263508Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
5437263508Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
5438263508Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
5439263508Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
5440263508Sdim      CmdArgs.push_back("-KPIC");
5441263508Sdim    }
5442263508Sdim  }
5443263508Sdim
5444195341Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5445195341Sed                       options::OPT_Xassembler);
5446195341Sed
5447195341Sed  CmdArgs.push_back("-o");
5448212904Sdim  CmdArgs.push_back(Output.getFilename());
5449195341Sed
5450195341Sed  for (InputInfoList::const_iterator
5451195341Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5452195341Sed    const InputInfo &II = *it;
5453212904Sdim    CmdArgs.push_back(II.getFilename());
5454195341Sed  }
5455195341Sed
5456195341Sed  const char *Exec =
5457210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5458212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5459195341Sed}
5460195341Sed
5461195341Sedvoid openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
5462212904Sdim                                 const InputInfo &Output,
5463195341Sed                                 const InputInfoList &Inputs,
5464195341Sed                                 const ArgList &Args,
5465195341Sed                                 const char *LinkingOutput) const {
5466201361Srdivacky  const Driver &D = getToolChain().getDriver();
5467195341Sed  ArgStringList CmdArgs;
5468195341Sed
5469249423Sdim  // Silence warning for "clang -g foo.o -o foo"
5470249423Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
5471249423Sdim  // and "clang -emit-llvm foo.o -o foo"
5472249423Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
5473249423Sdim  // and for "clang -w foo.o -o foo". Other warning options are already
5474249423Sdim  // handled somewhere else.
5475249423Sdim  Args.ClaimAllArgs(options::OPT_w);
5476249423Sdim
5477263508Sdim  if (getToolChain().getArch() == llvm::Triple::mips64)
5478263508Sdim    CmdArgs.push_back("-EB");
5479263508Sdim  else if (getToolChain().getArch() == llvm::Triple::mips64el)
5480263508Sdim    CmdArgs.push_back("-EL");
5481263508Sdim
5482198092Srdivacky  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5483198893Srdivacky      (!Args.hasArg(options::OPT_shared))) {
5484198092Srdivacky    CmdArgs.push_back("-e");
5485198092Srdivacky    CmdArgs.push_back("__start");
5486198092Srdivacky  }
5487198092Srdivacky
5488195341Sed  if (Args.hasArg(options::OPT_static)) {
5489195341Sed    CmdArgs.push_back("-Bstatic");
5490195341Sed  } else {
5491218893Sdim    if (Args.hasArg(options::OPT_rdynamic))
5492218893Sdim      CmdArgs.push_back("-export-dynamic");
5493195341Sed    CmdArgs.push_back("--eh-frame-hdr");
5494198092Srdivacky    CmdArgs.push_back("-Bdynamic");
5495195341Sed    if (Args.hasArg(options::OPT_shared)) {
5496198092Srdivacky      CmdArgs.push_back("-shared");
5497195341Sed    } else {
5498195341Sed      CmdArgs.push_back("-dynamic-linker");
5499195341Sed      CmdArgs.push_back("/usr/libexec/ld.so");
5500195341Sed    }
5501195341Sed  }
5502195341Sed
5503263508Sdim  if (Args.hasArg(options::OPT_nopie))
5504263508Sdim    CmdArgs.push_back("-nopie");
5505263508Sdim
5506212904Sdim  if (Output.isFilename()) {
5507195341Sed    CmdArgs.push_back("-o");
5508195341Sed    CmdArgs.push_back(Output.getFilename());
5509195341Sed  } else {
5510195341Sed    assert(Output.isNothing() && "Invalid output.");
5511195341Sed  }
5512195341Sed
5513195341Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5514195341Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5515195341Sed    if (!Args.hasArg(options::OPT_shared)) {
5516234353Sdim      if (Args.hasArg(options::OPT_pg))
5517234353Sdim        CmdArgs.push_back(Args.MakeArgString(
5518234353Sdim                                getToolChain().GetFilePath("gcrt0.o")));
5519234353Sdim      else
5520234353Sdim        CmdArgs.push_back(Args.MakeArgString(
5521234353Sdim                                getToolChain().GetFilePath("crt0.o")));
5522210299Sed      CmdArgs.push_back(Args.MakeArgString(
5523210299Sed                              getToolChain().GetFilePath("crtbegin.o")));
5524195341Sed    } else {
5525210299Sed      CmdArgs.push_back(Args.MakeArgString(
5526210299Sed                              getToolChain().GetFilePath("crtbeginS.o")));
5527195341Sed    }
5528195341Sed  }
5529195341Sed
5530198893Srdivacky  std::string Triple = getToolChain().getTripleString();
5531198893Srdivacky  if (Triple.substr(0, 6) == "x86_64")
5532198893Srdivacky    Triple.replace(0, 6, "amd64");
5533198893Srdivacky  CmdArgs.push_back(Args.MakeArgString("-L/usr/lib/gcc-lib/" + Triple +
5534212904Sdim                                       "/4.2.1"));
5535198092Srdivacky
5536195341Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
5537195341Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5538195341Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
5539249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
5540249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
5541249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
5542249423Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
5543195341Sed
5544218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5545195341Sed
5546195341Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5547195341Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
5548263508Sdim    if (D.CCCIsCXX()) {
5549218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5550234353Sdim      if (Args.hasArg(options::OPT_pg))
5551234353Sdim        CmdArgs.push_back("-lm_p");
5552234353Sdim      else
5553234353Sdim        CmdArgs.push_back("-lm");
5554212904Sdim    }
5555212904Sdim
5556198092Srdivacky    // FIXME: For some reason GCC passes -lgcc before adding
5557198092Srdivacky    // the default system libraries. Just mimic this for now.
5558198092Srdivacky    CmdArgs.push_back("-lgcc");
5559195341Sed
5560243830Sdim    if (Args.hasArg(options::OPT_pthread)) {
5561243830Sdim      if (!Args.hasArg(options::OPT_shared) &&
5562243830Sdim          Args.hasArg(options::OPT_pg))
5563243830Sdim         CmdArgs.push_back("-lpthread_p");
5564243830Sdim      else
5565243830Sdim         CmdArgs.push_back("-lpthread");
5566243830Sdim    }
5567243830Sdim
5568234353Sdim    if (!Args.hasArg(options::OPT_shared)) {
5569243830Sdim      if (Args.hasArg(options::OPT_pg))
5570234353Sdim         CmdArgs.push_back("-lc_p");
5571234353Sdim      else
5572234353Sdim         CmdArgs.push_back("-lc");
5573234353Sdim    }
5574243830Sdim
5575198092Srdivacky    CmdArgs.push_back("-lgcc");
5576195341Sed  }
5577195341Sed
5578195341Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5579195341Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5580195341Sed    if (!Args.hasArg(options::OPT_shared))
5581210299Sed      CmdArgs.push_back(Args.MakeArgString(
5582210299Sed                              getToolChain().GetFilePath("crtend.o")));
5583195341Sed    else
5584210299Sed      CmdArgs.push_back(Args.MakeArgString(
5585210299Sed                              getToolChain().GetFilePath("crtendS.o")));
5586195341Sed  }
5587195341Sed
5588195341Sed  const char *Exec =
5589210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5590212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5591195341Sed}
5592195341Sed
5593239462Sdimvoid bitrig::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5594239462Sdim                                    const InputInfo &Output,
5595239462Sdim                                    const InputInfoList &Inputs,
5596239462Sdim                                    const ArgList &Args,
5597239462Sdim                                    const char *LinkingOutput) const {
5598239462Sdim  ArgStringList CmdArgs;
5599239462Sdim
5600239462Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5601239462Sdim                       options::OPT_Xassembler);
5602239462Sdim
5603239462Sdim  CmdArgs.push_back("-o");
5604239462Sdim  CmdArgs.push_back(Output.getFilename());
5605239462Sdim
5606239462Sdim  for (InputInfoList::const_iterator
5607239462Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5608239462Sdim    const InputInfo &II = *it;
5609239462Sdim    CmdArgs.push_back(II.getFilename());
5610239462Sdim  }
5611239462Sdim
5612239462Sdim  const char *Exec =
5613239462Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5614239462Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5615239462Sdim}
5616239462Sdim
5617239462Sdimvoid bitrig::Link::ConstructJob(Compilation &C, const JobAction &JA,
5618239462Sdim                                const InputInfo &Output,
5619239462Sdim                                const InputInfoList &Inputs,
5620239462Sdim                                const ArgList &Args,
5621239462Sdim                                const char *LinkingOutput) const {
5622239462Sdim  const Driver &D = getToolChain().getDriver();
5623239462Sdim  ArgStringList CmdArgs;
5624239462Sdim
5625239462Sdim  if ((!Args.hasArg(options::OPT_nostdlib)) &&
5626239462Sdim      (!Args.hasArg(options::OPT_shared))) {
5627239462Sdim    CmdArgs.push_back("-e");
5628239462Sdim    CmdArgs.push_back("__start");
5629239462Sdim  }
5630239462Sdim
5631239462Sdim  if (Args.hasArg(options::OPT_static)) {
5632239462Sdim    CmdArgs.push_back("-Bstatic");
5633239462Sdim  } else {
5634239462Sdim    if (Args.hasArg(options::OPT_rdynamic))
5635239462Sdim      CmdArgs.push_back("-export-dynamic");
5636239462Sdim    CmdArgs.push_back("--eh-frame-hdr");
5637239462Sdim    CmdArgs.push_back("-Bdynamic");
5638239462Sdim    if (Args.hasArg(options::OPT_shared)) {
5639239462Sdim      CmdArgs.push_back("-shared");
5640239462Sdim    } else {
5641239462Sdim      CmdArgs.push_back("-dynamic-linker");
5642239462Sdim      CmdArgs.push_back("/usr/libexec/ld.so");
5643239462Sdim    }
5644239462Sdim  }
5645239462Sdim
5646239462Sdim  if (Output.isFilename()) {
5647239462Sdim    CmdArgs.push_back("-o");
5648239462Sdim    CmdArgs.push_back(Output.getFilename());
5649239462Sdim  } else {
5650239462Sdim    assert(Output.isNothing() && "Invalid output.");
5651239462Sdim  }
5652239462Sdim
5653239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5654239462Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5655239462Sdim    if (!Args.hasArg(options::OPT_shared)) {
5656239462Sdim      if (Args.hasArg(options::OPT_pg))
5657239462Sdim        CmdArgs.push_back(Args.MakeArgString(
5658239462Sdim                                getToolChain().GetFilePath("gcrt0.o")));
5659239462Sdim      else
5660239462Sdim        CmdArgs.push_back(Args.MakeArgString(
5661239462Sdim                                getToolChain().GetFilePath("crt0.o")));
5662239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5663239462Sdim                              getToolChain().GetFilePath("crtbegin.o")));
5664239462Sdim    } else {
5665239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5666239462Sdim                              getToolChain().GetFilePath("crtbeginS.o")));
5667239462Sdim    }
5668239462Sdim  }
5669239462Sdim
5670239462Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
5671239462Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5672239462Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
5673239462Sdim
5674239462Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
5675239462Sdim
5676239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5677239462Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5678263508Sdim    if (D.CCCIsCXX()) {
5679239462Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
5680239462Sdim      if (Args.hasArg(options::OPT_pg))
5681239462Sdim        CmdArgs.push_back("-lm_p");
5682239462Sdim      else
5683239462Sdim        CmdArgs.push_back("-lm");
5684239462Sdim    }
5685239462Sdim
5686243830Sdim    if (Args.hasArg(options::OPT_pthread)) {
5687243830Sdim      if (!Args.hasArg(options::OPT_shared) &&
5688243830Sdim          Args.hasArg(options::OPT_pg))
5689243830Sdim        CmdArgs.push_back("-lpthread_p");
5690243830Sdim      else
5691243830Sdim        CmdArgs.push_back("-lpthread");
5692243830Sdim    }
5693243830Sdim
5694239462Sdim    if (!Args.hasArg(options::OPT_shared)) {
5695239462Sdim      if (Args.hasArg(options::OPT_pg))
5696239462Sdim        CmdArgs.push_back("-lc_p");
5697239462Sdim      else
5698239462Sdim        CmdArgs.push_back("-lc");
5699239462Sdim    }
5700239462Sdim
5701263508Sdim    StringRef MyArch;
5702263508Sdim    switch (getToolChain().getTriple().getArch()) {
5703263508Sdim    case llvm::Triple::arm:
5704263508Sdim      MyArch = "arm";
5705263508Sdim      break;
5706263508Sdim    case llvm::Triple::x86:
5707263508Sdim      MyArch = "i386";
5708263508Sdim      break;
5709263508Sdim    case llvm::Triple::x86_64:
5710263508Sdim      MyArch = "amd64";
5711263508Sdim      break;
5712263508Sdim    default:
5713263508Sdim      llvm_unreachable("Unsupported architecture");
5714263508Sdim    }
5715263508Sdim    CmdArgs.push_back(Args.MakeArgString("-lclang_rt." + MyArch));
5716239462Sdim  }
5717239462Sdim
5718239462Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5719239462Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
5720239462Sdim    if (!Args.hasArg(options::OPT_shared))
5721239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5722239462Sdim                              getToolChain().GetFilePath("crtend.o")));
5723239462Sdim    else
5724239462Sdim      CmdArgs.push_back(Args.MakeArgString(
5725239462Sdim                              getToolChain().GetFilePath("crtendS.o")));
5726239462Sdim  }
5727239462Sdim
5728239462Sdim  const char *Exec =
5729239462Sdim    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
5730239462Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5731239462Sdim}
5732239462Sdim
5733193326Sedvoid freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
5734212904Sdim                                     const InputInfo &Output,
5735193326Sed                                     const InputInfoList &Inputs,
5736193326Sed                                     const ArgList &Args,
5737198092Srdivacky                                     const char *LinkingOutput) const {
5738193326Sed  ArgStringList CmdArgs;
5739193326Sed
5740193326Sed  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
5741193326Sed  // instruct as in the base system to assemble 32-bit code.
5742243830Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
5743193326Sed    CmdArgs.push_back("--32");
5744243830Sdim  else if (getToolChain().getArch() == llvm::Triple::ppc)
5745223017Sdim    CmdArgs.push_back("-a32");
5746243830Sdim  else if (getToolChain().getArch() == llvm::Triple::mips ||
5747243830Sdim           getToolChain().getArch() == llvm::Triple::mipsel ||
5748243830Sdim           getToolChain().getArch() == llvm::Triple::mips64 ||
5749243830Sdim           getToolChain().getArch() == llvm::Triple::mips64el) {
5750243830Sdim    StringRef CPUName;
5751243830Sdim    StringRef ABIName;
5752263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
5753218893Sdim
5754243830Sdim    CmdArgs.push_back("-march");
5755243830Sdim    CmdArgs.push_back(CPUName.data());
5756204643Srdivacky
5757243830Sdim    CmdArgs.push_back("-mabi");
5758249423Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
5759243830Sdim
5760243830Sdim    if (getToolChain().getArch() == llvm::Triple::mips ||
5761243830Sdim        getToolChain().getArch() == llvm::Triple::mips64)
5762243830Sdim      CmdArgs.push_back("-EB");
5763243830Sdim    else
5764243830Sdim      CmdArgs.push_back("-EL");
5765243830Sdim
5766243830Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
5767243830Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
5768243830Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
5769243830Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
5770243830Sdim    if (LastPICArg &&
5771243830Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
5772243830Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
5773243830Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
5774243830Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
5775243830Sdim      CmdArgs.push_back("-KPIC");
5776243830Sdim    }
5777244640Sandrew  } else if (getToolChain().getArch() == llvm::Triple::arm ||
5778244640Sandrew             getToolChain().getArch() == llvm::Triple::thumb) {
5779244640Sandrew    CmdArgs.push_back("-mfpu=softvfp");
5780244640Sandrew    switch(getToolChain().getTriple().getEnvironment()) {
5781244640Sandrew    case llvm::Triple::GNUEABI:
5782244640Sandrew    case llvm::Triple::EABI:
5783248548Sandrew      CmdArgs.push_back("-meabi=5");
5784244640Sandrew      break;
5785244640Sandrew
5786244640Sandrew    default:
5787244640Sandrew      CmdArgs.push_back("-matpcs");
5788244640Sandrew    }
5789263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::sparc ||
5790263763Sdim             getToolChain().getArch() == llvm::Triple::sparcv9) {
5791263763Sdim    if (getToolChain().getArch() == llvm::Triple::sparc)
5792263763Sdim      CmdArgs.push_back("-Av8plusa");
5793263763Sdim    else
5794263763Sdim      CmdArgs.push_back("-Av9a");
5795263763Sdim
5796263763Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
5797263763Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
5798263763Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
5799263763Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
5800263763Sdim    if (LastPICArg &&
5801263763Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
5802263763Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
5803263763Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
5804263763Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
5805263763Sdim      CmdArgs.push_back("-KPIC");
5806263763Sdim    }
5807243830Sdim  }
5808243830Sdim
5809193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
5810193326Sed                       options::OPT_Xassembler);
5811193326Sed
5812193326Sed  CmdArgs.push_back("-o");
5813212904Sdim  CmdArgs.push_back(Output.getFilename());
5814193326Sed
5815193326Sed  for (InputInfoList::const_iterator
5816193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
5817193326Sed    const InputInfo &II = *it;
5818212904Sdim    CmdArgs.push_back(II.getFilename());
5819193326Sed  }
5820193326Sed
5821193326Sed  const char *Exec =
5822210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
5823212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
5824193326Sed}
5825193326Sed
5826193326Sedvoid freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
5827212904Sdim                                 const InputInfo &Output,
5828193326Sed                                 const InputInfoList &Inputs,
5829193326Sed                                 const ArgList &Args,
5830193326Sed                                 const char *LinkingOutput) const {
5831243830Sdim  const toolchains::FreeBSD& ToolChain =
5832243830Sdim    static_cast<const toolchains::FreeBSD&>(getToolChain());
5833243830Sdim  const Driver &D = ToolChain.getDriver();
5834193326Sed  ArgStringList CmdArgs;
5835193326Sed
5836238864Sdim  // Silence warning for "clang -g foo.o -o foo"
5837238864Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
5838238864Sdim  // and "clang -emit-llvm foo.o -o foo"
5839238864Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
5840238864Sdim  // and for "clang -w foo.o -o foo". Other warning options are already
5841238864Sdim  // handled somewhere else.
5842238864Sdim  Args.ClaimAllArgs(options::OPT_w);
5843238864Sdim
5844221345Sdim  if (!D.SysRoot.empty())
5845221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
5846221345Sdim
5847243830Sdim  if (Args.hasArg(options::OPT_pie))
5848243830Sdim    CmdArgs.push_back("-pie");
5849243830Sdim
5850193326Sed  if (Args.hasArg(options::OPT_static)) {
5851193326Sed    CmdArgs.push_back("-Bstatic");
5852193326Sed  } else {
5853218893Sdim    if (Args.hasArg(options::OPT_rdynamic))
5854218893Sdim      CmdArgs.push_back("-export-dynamic");
5855193326Sed    CmdArgs.push_back("--eh-frame-hdr");
5856193326Sed    if (Args.hasArg(options::OPT_shared)) {
5857193326Sed      CmdArgs.push_back("-Bshareable");
5858193326Sed    } else {
5859193326Sed      CmdArgs.push_back("-dynamic-linker");
5860193326Sed      CmdArgs.push_back("/libexec/ld-elf.so.1");
5861193326Sed    }
5862243830Sdim    if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
5863243830Sdim      llvm::Triple::ArchType Arch = ToolChain.getArch();
5864239462Sdim      if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
5865239462Sdim          Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
5866239462Sdim        CmdArgs.push_back("--hash-style=both");
5867239462Sdim      }
5868239462Sdim    }
5869238863Sdim    CmdArgs.push_back("--enable-new-dtags");
5870193326Sed  }
5871193326Sed
5872193326Sed  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
5873193326Sed  // instruct ld in the base system to link 32-bit code.
5874243830Sdim  if (ToolChain.getArch() == llvm::Triple::x86) {
5875193326Sed    CmdArgs.push_back("-m");
5876193326Sed    CmdArgs.push_back("elf_i386_fbsd");
5877193326Sed  }
5878193326Sed
5879243830Sdim  if (ToolChain.getArch() == llvm::Triple::ppc) {
5880223017Sdim    CmdArgs.push_back("-m");
5881227739Sandreast    CmdArgs.push_back("elf32ppc_fbsd");
5882223017Sdim  }
5883223017Sdim
5884212904Sdim  if (Output.isFilename()) {
5885193326Sed    CmdArgs.push_back("-o");
5886193326Sed    CmdArgs.push_back(Output.getFilename());
5887193326Sed  } else {
5888193326Sed    assert(Output.isNothing() && "Invalid output.");
5889193326Sed  }
5890193326Sed
5891193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
5892193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
5893243830Sdim    const char *crt1 = NULL;
5894193326Sed    if (!Args.hasArg(options::OPT_shared)) {
5895218893Sdim      if (Args.hasArg(options::OPT_pg))
5896243830Sdim        crt1 = "gcrt1.o";
5897243830Sdim      else if (Args.hasArg(options::OPT_pie))
5898243830Sdim        crt1 = "Scrt1.o";
5899243830Sdim      else
5900243830Sdim        crt1 = "crt1.o";
5901193326Sed    }
5902243830Sdim    if (crt1)
5903243830Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
5904243830Sdim
5905243830Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
5906243830Sdim
5907243830Sdim    const char *crtbegin = NULL;
5908243830Sdim    if (Args.hasArg(options::OPT_static))
5909243830Sdim      crtbegin = "crtbeginT.o";
5910243830Sdim    else if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
5911243830Sdim      crtbegin = "crtbeginS.o";
5912243830Sdim    else
5913243830Sdim      crtbegin = "crtbegin.o";
5914243830Sdim
5915243830Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
5916193326Sed  }
5917193326Sed
5918193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
5919243830Sdim  const ToolChain::path_list Paths = ToolChain.getFilePaths();
5920219011Sdim  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
5921219011Sdim       i != e; ++i)
5922226633Sdim    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
5923193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
5924193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
5925212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
5926212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
5927212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
5928212904Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
5929193326Sed
5930263508Sdim  // Tell the linker to load the plugin. This has to come before AddLinkerInputs
5931263508Sdim  // as gold requires -plugin to come before any -plugin-opt that -Wl might
5932263508Sdim  // forward.
5933263508Sdim  if (D.IsUsingLTO(Args)) {
5934263508Sdim    CmdArgs.push_back("-plugin");
5935263508Sdim    std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
5936263508Sdim    CmdArgs.push_back(Args.MakeArgString(Plugin));
5937263508Sdim
5938263508Sdim    // Try to pass driver level flags relevant to LTO code generation down to
5939263508Sdim    // the plugin.
5940263508Sdim
5941263508Sdim    // Handle flags for selecting CPU variants.
5942263508Sdim    std::string CPU = getCPUName(Args, ToolChain.getTriple());
5943263508Sdim    if (!CPU.empty()) {
5944263508Sdim      CmdArgs.push_back(
5945263508Sdim                        Args.MakeArgString(Twine("-plugin-opt=mcpu=") +
5946263508Sdim                                           CPU));
5947263508Sdim    }
5948263508Sdim  }
5949263508Sdim
5950243830Sdim  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
5951218893Sdim
5952218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
5953218893Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
5954263508Sdim    if (D.CCCIsCXX()) {
5955243830Sdim      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
5956218893Sdim      if (Args.hasArg(options::OPT_pg))
5957218893Sdim        CmdArgs.push_back("-lm_p");
5958218893Sdim      else
5959218893Sdim        CmdArgs.push_back("-lm");
5960218893Sdim    }
5961218893Sdim    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
5962218893Sdim    // the default system libraries. Just mimic this for now.
5963218893Sdim    if (Args.hasArg(options::OPT_pg))
5964218893Sdim      CmdArgs.push_back("-lgcc_p");
5965218893Sdim    else
5966218893Sdim      CmdArgs.push_back("-lgcc");
5967218893Sdim    if (Args.hasArg(options::OPT_static)) {
5968218893Sdim      CmdArgs.push_back("-lgcc_eh");
5969218893Sdim    } else if (Args.hasArg(options::OPT_pg)) {
5970218893Sdim      CmdArgs.push_back("-lgcc_eh_p");
5971218893Sdim    } else {
5972218893Sdim      CmdArgs.push_back("--as-needed");
5973218893Sdim      CmdArgs.push_back("-lgcc_s");
5974218893Sdim      CmdArgs.push_back("--no-as-needed");
5975218893Sdim    }
5976218893Sdim
5977218893Sdim    if (Args.hasArg(options::OPT_pthread)) {
5978218893Sdim      if (Args.hasArg(options::OPT_pg))
5979218893Sdim        CmdArgs.push_back("-lpthread_p");
5980218893Sdim      else
5981218893Sdim        CmdArgs.push_back("-lpthread");
5982218893Sdim    }
5983218893Sdim
5984218893Sdim    if (Args.hasArg(options::OPT_pg)) {
5985218893Sdim      if (Args.hasArg(options::OPT_shared))
5986218893Sdim        CmdArgs.push_back("-lc");
5987218893Sdim      else
5988218893Sdim        CmdArgs.push_back("-lc_p");
5989218893Sdim      CmdArgs.push_back("-lgcc_p");
5990218893Sdim    } else {
5991218893Sdim      CmdArgs.push_back("-lc");
5992218893Sdim      CmdArgs.push_back("-lgcc");
5993218893Sdim    }
5994218893Sdim
5995218893Sdim    if (Args.hasArg(options::OPT_static)) {
5996218893Sdim      CmdArgs.push_back("-lgcc_eh");
5997218893Sdim    } else if (Args.hasArg(options::OPT_pg)) {
5998218893Sdim      CmdArgs.push_back("-lgcc_eh_p");
5999218893Sdim    } else {
6000218893Sdim      CmdArgs.push_back("--as-needed");
6001218893Sdim      CmdArgs.push_back("-lgcc_s");
6002218893Sdim      CmdArgs.push_back("--no-as-needed");
6003218893Sdim    }
6004218893Sdim  }
6005218893Sdim
6006218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6007218893Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6008243830Sdim    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
6009243830Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
6010218893Sdim    else
6011243830Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
6012243830Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
6013218893Sdim  }
6014218893Sdim
6015243830Sdim  addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
6016223017Sdim
6017218893Sdim  const char *Exec =
6018243830Sdim    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
6019218893Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6020218893Sdim}
6021218893Sdim
6022218893Sdimvoid netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6023218893Sdim                                     const InputInfo &Output,
6024218893Sdim                                     const InputInfoList &Inputs,
6025218893Sdim                                     const ArgList &Args,
6026218893Sdim                                     const char *LinkingOutput) const {
6027218893Sdim  ArgStringList CmdArgs;
6028218893Sdim
6029218893Sdim  // When building 32-bit code on NetBSD/amd64, we have to explicitly
6030218893Sdim  // instruct as in the base system to assemble 32-bit code.
6031234353Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
6032218893Sdim    CmdArgs.push_back("--32");
6033218893Sdim
6034263508Sdim  // Pass the target CPU to GNU as for ARM, since the source code might
6035263508Sdim  // not have the correct .cpu annotation.
6036263508Sdim  if (getToolChain().getArch() == llvm::Triple::arm) {
6037263508Sdim    std::string MArch(getARMTargetCPU(Args, getToolChain().getTriple()));
6038263508Sdim    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
6039263508Sdim  }
6040218893Sdim
6041263508Sdim  if (getToolChain().getArch() == llvm::Triple::mips ||
6042263508Sdim      getToolChain().getArch() == llvm::Triple::mipsel ||
6043263508Sdim      getToolChain().getArch() == llvm::Triple::mips64 ||
6044263508Sdim      getToolChain().getArch() == llvm::Triple::mips64el) {
6045263508Sdim    StringRef CPUName;
6046263508Sdim    StringRef ABIName;
6047263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6048263508Sdim
6049263508Sdim    CmdArgs.push_back("-march");
6050263508Sdim    CmdArgs.push_back(CPUName.data());
6051263508Sdim
6052263508Sdim    CmdArgs.push_back("-mabi");
6053263508Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6054263508Sdim
6055263508Sdim    if (getToolChain().getArch() == llvm::Triple::mips ||
6056263508Sdim        getToolChain().getArch() == llvm::Triple::mips64)
6057263508Sdim      CmdArgs.push_back("-EB");
6058263508Sdim    else
6059263508Sdim      CmdArgs.push_back("-EL");
6060263508Sdim
6061263508Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
6062263508Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
6063263508Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
6064263508Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
6065263508Sdim    if (LastPICArg &&
6066263508Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
6067263508Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
6068263508Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
6069263508Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
6070263508Sdim      CmdArgs.push_back("-KPIC");
6071263508Sdim    }
6072263508Sdim  }
6073263508Sdim
6074218893Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6075218893Sdim                       options::OPT_Xassembler);
6076218893Sdim
6077218893Sdim  CmdArgs.push_back("-o");
6078218893Sdim  CmdArgs.push_back(Output.getFilename());
6079218893Sdim
6080193326Sed  for (InputInfoList::const_iterator
6081193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6082193326Sed    const InputInfo &II = *it;
6083218893Sdim    CmdArgs.push_back(II.getFilename());
6084218893Sdim  }
6085193326Sed
6086226633Sdim  const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
6087218893Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6088218893Sdim}
6089193326Sed
6090218893Sdimvoid netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
6091218893Sdim                                 const InputInfo &Output,
6092218893Sdim                                 const InputInfoList &Inputs,
6093218893Sdim                                 const ArgList &Args,
6094218893Sdim                                 const char *LinkingOutput) const {
6095218893Sdim  const Driver &D = getToolChain().getDriver();
6096218893Sdim  ArgStringList CmdArgs;
6097218893Sdim
6098221345Sdim  if (!D.SysRoot.empty())
6099221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6100221345Sdim
6101218893Sdim  if (Args.hasArg(options::OPT_static)) {
6102218893Sdim    CmdArgs.push_back("-Bstatic");
6103218893Sdim  } else {
6104218893Sdim    if (Args.hasArg(options::OPT_rdynamic))
6105218893Sdim      CmdArgs.push_back("-export-dynamic");
6106218893Sdim    CmdArgs.push_back("--eh-frame-hdr");
6107218893Sdim    if (Args.hasArg(options::OPT_shared)) {
6108218893Sdim      CmdArgs.push_back("-Bshareable");
6109218893Sdim    } else {
6110218893Sdim      CmdArgs.push_back("-dynamic-linker");
6111218893Sdim      CmdArgs.push_back("/libexec/ld.elf_so");
6112218893Sdim    }
6113193326Sed  }
6114193326Sed
6115218893Sdim  // When building 32-bit code on NetBSD/amd64, we have to explicitly
6116218893Sdim  // instruct ld in the base system to link 32-bit code.
6117234353Sdim  if (getToolChain().getArch() == llvm::Triple::x86) {
6118218893Sdim    CmdArgs.push_back("-m");
6119218893Sdim    CmdArgs.push_back("elf_i386");
6120218893Sdim  }
6121218893Sdim
6122218893Sdim  if (Output.isFilename()) {
6123218893Sdim    CmdArgs.push_back("-o");
6124218893Sdim    CmdArgs.push_back(Output.getFilename());
6125218893Sdim  } else {
6126218893Sdim    assert(Output.isNothing() && "Invalid output.");
6127218893Sdim  }
6128218893Sdim
6129193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6130218893Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6131218893Sdim    if (!Args.hasArg(options::OPT_shared)) {
6132218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6133218893Sdim                              getToolChain().GetFilePath("crt0.o")));
6134218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6135218893Sdim                              getToolChain().GetFilePath("crti.o")));
6136218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6137218893Sdim                              getToolChain().GetFilePath("crtbegin.o")));
6138218893Sdim    } else {
6139218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6140218893Sdim                              getToolChain().GetFilePath("crti.o")));
6141218893Sdim      CmdArgs.push_back(Args.MakeArgString(
6142218893Sdim                              getToolChain().GetFilePath("crtbeginS.o")));
6143218893Sdim    }
6144218893Sdim  }
6145218893Sdim
6146218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
6147218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6148218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_e);
6149218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_s);
6150218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_t);
6151218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
6152218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_r);
6153218893Sdim
6154218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6155218893Sdim
6156263508Sdim  unsigned Major, Minor, Micro;
6157263508Sdim  getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
6158263508Sdim  bool useLibgcc = true;
6159263508Sdim  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
6160263508Sdim    if (getToolChain().getArch() == llvm::Triple::x86 ||
6161263508Sdim        getToolChain().getArch() == llvm::Triple::x86_64)
6162263508Sdim      useLibgcc = false;
6163263508Sdim  }
6164263508Sdim
6165218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6166193326Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
6167263508Sdim    if (D.CCCIsCXX()) {
6168218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6169204643Srdivacky      CmdArgs.push_back("-lm");
6170204643Srdivacky    }
6171193326Sed    if (Args.hasArg(options::OPT_pthread))
6172193326Sed      CmdArgs.push_back("-lpthread");
6173193326Sed    CmdArgs.push_back("-lc");
6174193326Sed
6175263508Sdim    if (useLibgcc) {
6176263508Sdim      if (Args.hasArg(options::OPT_static)) {
6177263508Sdim        // libgcc_eh depends on libc, so resolve as much as possible,
6178263508Sdim        // pull in any new requirements from libc and then get the rest
6179263508Sdim        // of libgcc.
6180263508Sdim        CmdArgs.push_back("-lgcc_eh");
6181263508Sdim        CmdArgs.push_back("-lc");
6182263508Sdim        CmdArgs.push_back("-lgcc");
6183263508Sdim      } else {
6184263508Sdim        CmdArgs.push_back("-lgcc");
6185263508Sdim        CmdArgs.push_back("--as-needed");
6186263508Sdim        CmdArgs.push_back("-lgcc_s");
6187263508Sdim        CmdArgs.push_back("--no-as-needed");
6188263508Sdim      }
6189193326Sed    }
6190193326Sed  }
6191193326Sed
6192193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6193193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
6194193326Sed    if (!Args.hasArg(options::OPT_shared))
6195210299Sed      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
6196210299Sed                                                                  "crtend.o")));
6197193326Sed    else
6198210299Sed      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
6199210299Sed                                                                 "crtendS.o")));
6200210299Sed    CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(
6201210299Sed                                                                    "crtn.o")));
6202193326Sed  }
6203193326Sed
6204224145Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
6205223017Sdim
6206226633Sdim  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
6207212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6208193326Sed}
6209193326Sed
6210249423Sdimvoid gnutools::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6211249423Sdim                                      const InputInfo &Output,
6212249423Sdim                                      const InputInfoList &Inputs,
6213249423Sdim                                      const ArgList &Args,
6214249423Sdim                                      const char *LinkingOutput) const {
6215212904Sdim  ArgStringList CmdArgs;
6216263763Sdim  bool NeedsKPIC = false;
6217212904Sdim
6218212904Sdim  // Add --32/--64 to make sure we get the format we want.
6219212904Sdim  // This is incomplete
6220212904Sdim  if (getToolChain().getArch() == llvm::Triple::x86) {
6221212904Sdim    CmdArgs.push_back("--32");
6222212904Sdim  } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
6223212904Sdim    CmdArgs.push_back("--64");
6224234353Sdim  } else if (getToolChain().getArch() == llvm::Triple::ppc) {
6225234353Sdim    CmdArgs.push_back("-a32");
6226234353Sdim    CmdArgs.push_back("-mppc");
6227234353Sdim    CmdArgs.push_back("-many");
6228234353Sdim  } else if (getToolChain().getArch() == llvm::Triple::ppc64) {
6229234353Sdim    CmdArgs.push_back("-a64");
6230234353Sdim    CmdArgs.push_back("-mppc64");
6231234353Sdim    CmdArgs.push_back("-many");
6232263508Sdim  } else if (getToolChain().getArch() == llvm::Triple::ppc64le) {
6233263508Sdim    CmdArgs.push_back("-a64");
6234263508Sdim    CmdArgs.push_back("-mppc64le");
6235263508Sdim    CmdArgs.push_back("-many");
6236263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::sparc) {
6237263763Sdim    CmdArgs.push_back("-32");
6238263763Sdim    CmdArgs.push_back("-Av8plusa");
6239263763Sdim    NeedsKPIC = true;
6240263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
6241263763Sdim    CmdArgs.push_back("-64");
6242263763Sdim    CmdArgs.push_back("-Av9a");
6243263763Sdim    NeedsKPIC = true;
6244212904Sdim  } else if (getToolChain().getArch() == llvm::Triple::arm) {
6245226633Sdim    StringRef MArch = getToolChain().getArchName();
6246212904Sdim    if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
6247212904Sdim      CmdArgs.push_back("-mfpu=neon");
6248263508Sdim    if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a")
6249263508Sdim      CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
6250239462Sdim
6251239462Sdim    StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args,
6252239462Sdim                                           getToolChain().getTriple());
6253239462Sdim    CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
6254239462Sdim
6255239462Sdim    Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
6256239462Sdim    Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
6257239462Sdim    Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
6258234353Sdim  } else if (getToolChain().getArch() == llvm::Triple::mips ||
6259234353Sdim             getToolChain().getArch() == llvm::Triple::mipsel ||
6260234353Sdim             getToolChain().getArch() == llvm::Triple::mips64 ||
6261234353Sdim             getToolChain().getArch() == llvm::Triple::mips64el) {
6262234353Sdim    StringRef CPUName;
6263234353Sdim    StringRef ABIName;
6264263508Sdim    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
6265234353Sdim
6266234353Sdim    CmdArgs.push_back("-march");
6267234353Sdim    CmdArgs.push_back(CPUName.data());
6268234353Sdim
6269234353Sdim    CmdArgs.push_back("-mabi");
6270249423Sdim    CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
6271234353Sdim
6272234353Sdim    if (getToolChain().getArch() == llvm::Triple::mips ||
6273234353Sdim        getToolChain().getArch() == llvm::Triple::mips64)
6274234353Sdim      CmdArgs.push_back("-EB");
6275234353Sdim    else
6276234353Sdim      CmdArgs.push_back("-EL");
6277239462Sdim
6278263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
6279263508Sdim      if (StringRef(A->getValue()) == "2008")
6280263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
6281263508Sdim    }
6282263508Sdim
6283263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfp64)) {
6284263508Sdim      if (A->getOption().matches(options::OPT_mfp32))
6285263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mfp32"));
6286263508Sdim      else
6287263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mfp64"));
6288263508Sdim    }
6289263508Sdim
6290251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16);
6291251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
6292251662Sdim                    options::OPT_mno_micromips);
6293251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
6294251662Sdim    Args.AddLastArg(CmdArgs, options::OPT_mdspr2, options::OPT_mno_dspr2);
6295251662Sdim
6296263508Sdim    if (Arg *A = Args.getLastArg(options::OPT_mmsa, options::OPT_mno_msa)) {
6297263508Sdim      // Do not use AddLastArg because not all versions of MIPS assembler
6298263508Sdim      // support -mmsa / -mno-msa options.
6299263508Sdim      if (A->getOption().matches(options::OPT_mmsa))
6300263508Sdim        CmdArgs.push_back(Args.MakeArgString("-mmsa"));
6301263508Sdim    }
6302263508Sdim
6303263763Sdim    NeedsKPIC = true;
6304263763Sdim  } else if (getToolChain().getArch() == llvm::Triple::systemz) {
6305263763Sdim    // Always pass an -march option, since our default of z10 is later
6306263763Sdim    // than the GNU assembler's default.
6307263763Sdim    StringRef CPUName = getSystemZTargetCPU(Args);
6308263763Sdim    CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
6309263763Sdim  }
6310263763Sdim
6311263763Sdim  if (NeedsKPIC) {
6312239462Sdim    Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
6313239462Sdim                                      options::OPT_fpic, options::OPT_fno_pic,
6314239462Sdim                                      options::OPT_fPIE, options::OPT_fno_PIE,
6315239462Sdim                                      options::OPT_fpie, options::OPT_fno_pie);
6316239462Sdim    if (LastPICArg &&
6317239462Sdim        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
6318239462Sdim         LastPICArg->getOption().matches(options::OPT_fpic) ||
6319239462Sdim         LastPICArg->getOption().matches(options::OPT_fPIE) ||
6320239462Sdim         LastPICArg->getOption().matches(options::OPT_fpie))) {
6321239462Sdim      CmdArgs.push_back("-KPIC");
6322239462Sdim    }
6323212904Sdim  }
6324212904Sdim
6325212904Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6326212904Sdim                       options::OPT_Xassembler);
6327212904Sdim
6328212904Sdim  CmdArgs.push_back("-o");
6329212904Sdim  CmdArgs.push_back(Output.getFilename());
6330212904Sdim
6331212904Sdim  for (InputInfoList::const_iterator
6332212904Sdim         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6333212904Sdim    const InputInfo &II = *it;
6334212904Sdim    CmdArgs.push_back(II.getFilename());
6335212904Sdim  }
6336212904Sdim
6337212904Sdim  const char *Exec =
6338212904Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
6339212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6340263508Sdim
6341263508Sdim  // Handle the debug info splitting at object creation time if we're
6342263508Sdim  // creating an object.
6343263508Sdim  // TODO: Currently only works on linux with newer objcopy.
6344263508Sdim  if (Args.hasArg(options::OPT_gsplit_dwarf) &&
6345263508Sdim      getToolChain().getTriple().isOSLinux())
6346263508Sdim    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output,
6347263508Sdim                   SplitDebugName(Args, Inputs));
6348212904Sdim}
6349212904Sdim
6350239462Sdimstatic void AddLibgcc(llvm::Triple Triple, const Driver &D,
6351239462Sdim                      ArgStringList &CmdArgs, const ArgList &Args) {
6352243830Sdim  bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
6353249423Sdim  bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
6354249423Sdim                      Args.hasArg(options::OPT_static);
6355263508Sdim  if (!D.CCCIsCXX())
6356234353Sdim    CmdArgs.push_back("-lgcc");
6357234353Sdim
6358249423Sdim  if (StaticLibgcc || isAndroid) {
6359263508Sdim    if (D.CCCIsCXX())
6360234353Sdim      CmdArgs.push_back("-lgcc");
6361234353Sdim  } else {
6362263508Sdim    if (!D.CCCIsCXX())
6363234353Sdim      CmdArgs.push_back("--as-needed");
6364234353Sdim    CmdArgs.push_back("-lgcc_s");
6365263508Sdim    if (!D.CCCIsCXX())
6366234353Sdim      CmdArgs.push_back("--no-as-needed");
6367234353Sdim  }
6368234353Sdim
6369239462Sdim  if (StaticLibgcc && !isAndroid)
6370234353Sdim    CmdArgs.push_back("-lgcc_eh");
6371263508Sdim  else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
6372234353Sdim    CmdArgs.push_back("-lgcc");
6373249423Sdim
6374249423Sdim  // According to Android ABI, we have to link with libdl if we are
6375249423Sdim  // linking with non-static libgcc.
6376249423Sdim  //
6377249423Sdim  // NOTE: This fixes a link error on Android MIPS as well.  The non-static
6378249423Sdim  // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl.
6379249423Sdim  if (isAndroid && !StaticLibgcc)
6380249423Sdim    CmdArgs.push_back("-ldl");
6381234353Sdim}
6382234353Sdim
6383243830Sdimstatic bool hasMipsN32ABIArg(const ArgList &Args) {
6384243830Sdim  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
6385243830Sdim  return A && (A->getValue() == StringRef("n32"));
6386243830Sdim}
6387243830Sdim
6388263508Sdimstatic StringRef getLinuxDynamicLinker(const ArgList &Args,
6389263508Sdim                                       const toolchains::Linux &ToolChain) {
6390263508Sdim  if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android)
6391263508Sdim    return "/system/bin/linker";
6392263763Sdim  else if (ToolChain.getArch() == llvm::Triple::x86 ||
6393263763Sdim           ToolChain.getArch() == llvm::Triple::sparc)
6394263508Sdim    return "/lib/ld-linux.so.2";
6395263508Sdim  else if (ToolChain.getArch() == llvm::Triple::aarch64)
6396263508Sdim    return "/lib/ld-linux-aarch64.so.1";
6397263508Sdim  else if (ToolChain.getArch() == llvm::Triple::arm ||
6398263508Sdim           ToolChain.getArch() == llvm::Triple::thumb) {
6399263508Sdim    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
6400263508Sdim      return "/lib/ld-linux-armhf.so.3";
6401263508Sdim    else
6402263508Sdim      return "/lib/ld-linux.so.3";
6403263508Sdim  } else if (ToolChain.getArch() == llvm::Triple::mips ||
6404263508Sdim             ToolChain.getArch() == llvm::Triple::mipsel)
6405263508Sdim    return "/lib/ld.so.1";
6406263508Sdim  else if (ToolChain.getArch() == llvm::Triple::mips64 ||
6407263508Sdim           ToolChain.getArch() == llvm::Triple::mips64el) {
6408263508Sdim    if (hasMipsN32ABIArg(Args))
6409263508Sdim      return "/lib32/ld.so.1";
6410263508Sdim    else
6411263508Sdim      return "/lib64/ld.so.1";
6412263508Sdim  } else if (ToolChain.getArch() == llvm::Triple::ppc)
6413263508Sdim    return "/lib/ld.so.1";
6414263508Sdim  else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
6415263508Sdim           ToolChain.getArch() == llvm::Triple::ppc64le ||
6416263508Sdim           ToolChain.getArch() == llvm::Triple::systemz)
6417263508Sdim    return "/lib64/ld64.so.1";
6418263763Sdim  else if (ToolChain.getArch() == llvm::Triple::sparcv9)
6419263763Sdim    return "/lib64/ld-linux.so.2";
6420263508Sdim  else
6421263508Sdim    return "/lib64/ld-linux-x86-64.so.2";
6422263508Sdim}
6423263508Sdim
6424249423Sdimvoid gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
6425249423Sdim                                  const InputInfo &Output,
6426249423Sdim                                  const InputInfoList &Inputs,
6427249423Sdim                                  const ArgList &Args,
6428249423Sdim                                  const char *LinkingOutput) const {
6429218893Sdim  const toolchains::Linux& ToolChain =
6430218893Sdim    static_cast<const toolchains::Linux&>(getToolChain());
6431218893Sdim  const Driver &D = ToolChain.getDriver();
6432243830Sdim  const bool isAndroid =
6433243830Sdim    ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
6434263508Sdim  const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs();
6435251662Sdim  const bool IsPIE =
6436251662Sdim    !Args.hasArg(options::OPT_shared) &&
6437251662Sdim    (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow());
6438239462Sdim
6439218893Sdim  ArgStringList CmdArgs;
6440212904Sdim
6441218893Sdim  // Silence warning for "clang -g foo.o -o foo"
6442218893Sdim  Args.ClaimAllArgs(options::OPT_g_Group);
6443221345Sdim  // and "clang -emit-llvm foo.o -o foo"
6444221345Sdim  Args.ClaimAllArgs(options::OPT_emit_llvm);
6445239462Sdim  // and for "clang -w foo.o -o foo". Other warning options are already
6446218893Sdim  // handled somewhere else.
6447218893Sdim  Args.ClaimAllArgs(options::OPT_w);
6448218893Sdim
6449221345Sdim  if (!D.SysRoot.empty())
6450221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6451218893Sdim
6452251662Sdim  if (IsPIE)
6453218893Sdim    CmdArgs.push_back("-pie");
6454218893Sdim
6455218893Sdim  if (Args.hasArg(options::OPT_rdynamic))
6456218893Sdim    CmdArgs.push_back("-export-dynamic");
6457218893Sdim
6458218893Sdim  if (Args.hasArg(options::OPT_s))
6459218893Sdim    CmdArgs.push_back("-s");
6460218893Sdim
6461218893Sdim  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
6462218893Sdim         e = ToolChain.ExtraOpts.end();
6463218893Sdim       i != e; ++i)
6464218893Sdim    CmdArgs.push_back(i->c_str());
6465218893Sdim
6466218893Sdim  if (!Args.hasArg(options::OPT_static)) {
6467218893Sdim    CmdArgs.push_back("--eh-frame-hdr");
6468218893Sdim  }
6469218893Sdim
6470218893Sdim  CmdArgs.push_back("-m");
6471218893Sdim  if (ToolChain.getArch() == llvm::Triple::x86)
6472218893Sdim    CmdArgs.push_back("elf_i386");
6473249423Sdim  else if (ToolChain.getArch() == llvm::Triple::aarch64)
6474249423Sdim    CmdArgs.push_back("aarch64linux");
6475226633Sdim  else if (ToolChain.getArch() == llvm::Triple::arm
6476221345Sdim           ||  ToolChain.getArch() == llvm::Triple::thumb)
6477218893Sdim    CmdArgs.push_back("armelf_linux_eabi");
6478221345Sdim  else if (ToolChain.getArch() == llvm::Triple::ppc)
6479221345Sdim    CmdArgs.push_back("elf32ppclinux");
6480221345Sdim  else if (ToolChain.getArch() == llvm::Triple::ppc64)
6481221345Sdim    CmdArgs.push_back("elf64ppc");
6482263763Sdim  else if (ToolChain.getArch() == llvm::Triple::sparc)
6483263763Sdim    CmdArgs.push_back("elf32_sparc");
6484263763Sdim  else if (ToolChain.getArch() == llvm::Triple::sparcv9)
6485263763Sdim    CmdArgs.push_back("elf64_sparc");
6486234353Sdim  else if (ToolChain.getArch() == llvm::Triple::mips)
6487234353Sdim    CmdArgs.push_back("elf32btsmip");
6488234353Sdim  else if (ToolChain.getArch() == llvm::Triple::mipsel)
6489234353Sdim    CmdArgs.push_back("elf32ltsmip");
6490243830Sdim  else if (ToolChain.getArch() == llvm::Triple::mips64) {
6491243830Sdim    if (hasMipsN32ABIArg(Args))
6492243830Sdim      CmdArgs.push_back("elf32btsmipn32");
6493243830Sdim    else
6494243830Sdim      CmdArgs.push_back("elf64btsmip");
6495243830Sdim  }
6496243830Sdim  else if (ToolChain.getArch() == llvm::Triple::mips64el) {
6497243830Sdim    if (hasMipsN32ABIArg(Args))
6498243830Sdim      CmdArgs.push_back("elf32ltsmipn32");
6499243830Sdim    else
6500243830Sdim      CmdArgs.push_back("elf64ltsmip");
6501243830Sdim  }
6502251662Sdim  else if (ToolChain.getArch() == llvm::Triple::systemz)
6503251662Sdim    CmdArgs.push_back("elf64_s390");
6504218893Sdim  else
6505218893Sdim    CmdArgs.push_back("elf_x86_64");
6506218893Sdim
6507218893Sdim  if (Args.hasArg(options::OPT_static)) {
6508221345Sdim    if (ToolChain.getArch() == llvm::Triple::arm
6509221345Sdim        || ToolChain.getArch() == llvm::Triple::thumb)
6510218893Sdim      CmdArgs.push_back("-Bstatic");
6511218893Sdim    else
6512218893Sdim      CmdArgs.push_back("-static");
6513218893Sdim  } else if (Args.hasArg(options::OPT_shared)) {
6514218893Sdim    CmdArgs.push_back("-shared");
6515243830Sdim    if (isAndroid) {
6516239462Sdim      CmdArgs.push_back("-Bsymbolic");
6517239462Sdim    }
6518218893Sdim  }
6519218893Sdim
6520218893Sdim  if (ToolChain.getArch() == llvm::Triple::arm ||
6521221345Sdim      ToolChain.getArch() == llvm::Triple::thumb ||
6522218893Sdim      (!Args.hasArg(options::OPT_static) &&
6523218893Sdim       !Args.hasArg(options::OPT_shared))) {
6524218893Sdim    CmdArgs.push_back("-dynamic-linker");
6525263508Sdim    CmdArgs.push_back(Args.MakeArgString(
6526263508Sdim        D.DyldPrefix + getLinuxDynamicLinker(Args, ToolChain)));
6527218893Sdim  }
6528218893Sdim
6529218893Sdim  CmdArgs.push_back("-o");
6530218893Sdim  CmdArgs.push_back(Output.getFilename());
6531218893Sdim
6532218893Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6533218893Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6534239462Sdim    if (!isAndroid) {
6535239462Sdim      const char *crt1 = NULL;
6536239462Sdim      if (!Args.hasArg(options::OPT_shared)){
6537263508Sdim        if (Args.hasArg(options::OPT_pg))
6538263508Sdim          crt1 = "gcrt1.o";
6539263508Sdim        else if (IsPIE)
6540239462Sdim          crt1 = "Scrt1.o";
6541239462Sdim        else
6542239462Sdim          crt1 = "crt1.o";
6543239462Sdim      }
6544239462Sdim      if (crt1)
6545239462Sdim        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
6546239462Sdim
6547239462Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
6548218893Sdim    }
6549218893Sdim
6550218893Sdim    const char *crtbegin;
6551218893Sdim    if (Args.hasArg(options::OPT_static))
6552239462Sdim      crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o";
6553243830Sdim    else if (Args.hasArg(options::OPT_shared))
6554239462Sdim      crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o";
6555251662Sdim    else if (IsPIE)
6556243830Sdim      crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o";
6557218893Sdim    else
6558239462Sdim      crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o";
6559218893Sdim    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
6560243830Sdim
6561243830Sdim    // Add crtfastmath.o if available and fast math is enabled.
6562243830Sdim    ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
6563218893Sdim  }
6564218893Sdim
6565218893Sdim  Args.AddAllArgs(CmdArgs, options::OPT_L);
6566218893Sdim
6567218893Sdim  const ToolChain::path_list Paths = ToolChain.getFilePaths();
6568221345Sdim
6569219011Sdim  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
6570219011Sdim       i != e; ++i)
6571226633Sdim    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
6572218893Sdim
6573234353Sdim  // Tell the linker to load the plugin. This has to come before AddLinkerInputs
6574234353Sdim  // as gold requires -plugin to come before any -plugin-opt that -Wl might
6575234353Sdim  // forward.
6576263508Sdim  if (D.IsUsingLTO(Args)) {
6577234353Sdim    CmdArgs.push_back("-plugin");
6578234353Sdim    std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
6579234353Sdim    CmdArgs.push_back(Args.MakeArgString(Plugin));
6580247166Sdim
6581247166Sdim    // Try to pass driver level flags relevant to LTO code generation down to
6582247166Sdim    // the plugin.
6583247166Sdim
6584263508Sdim    // Handle flags for selecting CPU variants.
6585263508Sdim    std::string CPU = getCPUName(Args, ToolChain.getTriple());
6586263508Sdim    if (!CPU.empty()) {
6587247166Sdim      CmdArgs.push_back(
6588263508Sdim                        Args.MakeArgString(Twine("-plugin-opt=mcpu=") +
6589263508Sdim                                           CPU));
6590263508Sdim    }
6591234353Sdim  }
6592234353Sdim
6593247166Sdim
6594239462Sdim  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
6595239462Sdim    CmdArgs.push_back("--no-demangle");
6596239462Sdim
6597218893Sdim  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
6598218893Sdim
6599249423Sdim  // Call these before we add the C++ ABI library.
6600243830Sdim  if (Sanitize.needsUbsanRt())
6601263508Sdim    addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(),
6602249423Sdim                    Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
6603263508Sdim                    Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
6604249423Sdim  if (Sanitize.needsAsanRt())
6605249423Sdim    addAsanRTLinux(getToolChain(), Args, CmdArgs);
6606249423Sdim  if (Sanitize.needsTsanRt())
6607249423Sdim    addTsanRTLinux(getToolChain(), Args, CmdArgs);
6608249423Sdim  if (Sanitize.needsMsanRt())
6609249423Sdim    addMsanRTLinux(getToolChain(), Args, CmdArgs);
6610263508Sdim  if (Sanitize.needsLsanRt())
6611263508Sdim    addLsanRTLinux(getToolChain(), Args, CmdArgs);
6612263508Sdim  if (Sanitize.needsDfsanRt())
6613263508Sdim    addDfsanRTLinux(getToolChain(), Args, CmdArgs);
6614243830Sdim
6615263508Sdim  // The profile runtime also needs access to system libraries.
6616263508Sdim  addProfileRTLinux(getToolChain(), Args, CmdArgs);
6617263508Sdim
6618263508Sdim  if (D.CCCIsCXX() &&
6619239462Sdim      !Args.hasArg(options::OPT_nostdlib) &&
6620239462Sdim      !Args.hasArg(options::OPT_nodefaultlibs)) {
6621234353Sdim    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
6622234353Sdim      !Args.hasArg(options::OPT_static);
6623234353Sdim    if (OnlyLibstdcxxStatic)
6624234353Sdim      CmdArgs.push_back("-Bstatic");
6625218893Sdim    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
6626234353Sdim    if (OnlyLibstdcxxStatic)
6627234353Sdim      CmdArgs.push_back("-Bdynamic");
6628218893Sdim    CmdArgs.push_back("-lm");
6629218893Sdim  }
6630218893Sdim
6631223017Sdim  if (!Args.hasArg(options::OPT_nostdlib)) {
6632239462Sdim    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
6633239462Sdim      if (Args.hasArg(options::OPT_static))
6634239462Sdim        CmdArgs.push_back("--start-group");
6635218893Sdim
6636249423Sdim      bool OpenMP = Args.hasArg(options::OPT_fopenmp);
6637249423Sdim      if (OpenMP) {
6638249423Sdim        CmdArgs.push_back("-lgomp");
6639249423Sdim
6640249423Sdim        // FIXME: Exclude this for platforms whith libgomp that doesn't require
6641249423Sdim        // librt. Most modern Linux platfroms require it, but some may not.
6642249423Sdim        CmdArgs.push_back("-lrt");
6643249423Sdim      }
6644249423Sdim
6645239462Sdim      AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
6646218893Sdim
6647239462Sdim      if (Args.hasArg(options::OPT_pthread) ||
6648249423Sdim          Args.hasArg(options::OPT_pthreads) || OpenMP)
6649239462Sdim        CmdArgs.push_back("-lpthread");
6650218893Sdim
6651239462Sdim      CmdArgs.push_back("-lc");
6652218893Sdim
6653239462Sdim      if (Args.hasArg(options::OPT_static))
6654239462Sdim        CmdArgs.push_back("--end-group");
6655239462Sdim      else
6656239462Sdim        AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
6657239462Sdim    }
6658218893Sdim
6659218893Sdim    if (!Args.hasArg(options::OPT_nostartfiles)) {
6660218893Sdim      const char *crtend;
6661243830Sdim      if (Args.hasArg(options::OPT_shared))
6662239462Sdim        crtend = isAndroid ? "crtend_so.o" : "crtendS.o";
6663251662Sdim      else if (IsPIE)
6664243830Sdim        crtend = isAndroid ? "crtend_android.o" : "crtendS.o";
6665218893Sdim      else
6666239462Sdim        crtend = isAndroid ? "crtend_android.o" : "crtend.o";
6667218893Sdim
6668218893Sdim      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
6669239462Sdim      if (!isAndroid)
6670239462Sdim        CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
6671218893Sdim    }
6672218893Sdim  }
6673218893Sdim
6674218893Sdim  C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
6675218893Sdim}
6676218893Sdim
6677210299Sedvoid minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6678212904Sdim                                   const InputInfo &Output,
6679212904Sdim                                   const InputInfoList &Inputs,
6680212904Sdim                                   const ArgList &Args,
6681212904Sdim                                   const char *LinkingOutput) const {
6682210299Sed  ArgStringList CmdArgs;
6683210299Sed
6684210299Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6685210299Sed                       options::OPT_Xassembler);
6686210299Sed
6687210299Sed  CmdArgs.push_back("-o");
6688212904Sdim  CmdArgs.push_back(Output.getFilename());
6689210299Sed
6690210299Sed  for (InputInfoList::const_iterator
6691210299Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6692210299Sed    const InputInfo &II = *it;
6693212904Sdim    CmdArgs.push_back(II.getFilename());
6694210299Sed  }
6695210299Sed
6696210299Sed  const char *Exec =
6697234353Sdim    Args.MakeArgString(getToolChain().GetProgramPath("as"));
6698212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6699210299Sed}
6700210299Sed
6701210299Sedvoid minix::Link::ConstructJob(Compilation &C, const JobAction &JA,
6702212904Sdim                               const InputInfo &Output,
6703212904Sdim                               const InputInfoList &Inputs,
6704212904Sdim                               const ArgList &Args,
6705212904Sdim                               const char *LinkingOutput) const {
6706210299Sed  const Driver &D = getToolChain().getDriver();
6707210299Sed  ArgStringList CmdArgs;
6708210299Sed
6709212904Sdim  if (Output.isFilename()) {
6710210299Sed    CmdArgs.push_back("-o");
6711210299Sed    CmdArgs.push_back(Output.getFilename());
6712210299Sed  } else {
6713210299Sed    assert(Output.isNothing() && "Invalid output.");
6714210299Sed  }
6715210299Sed
6716210299Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6717234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6718234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
6719234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
6720234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
6721234353Sdim      CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
6722234353Sdim  }
6723210299Sed
6724210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
6725210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6726210299Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
6727210299Sed
6728218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6729210299Sed
6730234353Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
6731234353Sdim
6732210299Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6733210299Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
6734263508Sdim    if (D.CCCIsCXX()) {
6735218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6736210299Sed      CmdArgs.push_back("-lm");
6737210299Sed    }
6738234353Sdim  }
6739210299Sed
6740234353Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6741234353Sdim      !Args.hasArg(options::OPT_nostartfiles)) {
6742210299Sed    if (Args.hasArg(options::OPT_pthread))
6743210299Sed      CmdArgs.push_back("-lpthread");
6744210299Sed    CmdArgs.push_back("-lc");
6745234353Sdim    CmdArgs.push_back("-lCompilerRT-Generic");
6746234353Sdim    CmdArgs.push_back("-L/usr/pkg/compiler-rt/lib");
6747234353Sdim    CmdArgs.push_back(
6748249423Sdim         Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
6749210299Sed  }
6750210299Sed
6751234353Sdim  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
6752212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6753210299Sed}
6754210299Sed
6755193326Sed/// DragonFly Tools
6756193326Sed
6757193326Sed// For now, DragonFly Assemble does just about the same as for
6758193326Sed// FreeBSD, but this may change soon.
6759193326Sedvoid dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
6760212904Sdim                                       const InputInfo &Output,
6761198893Srdivacky                                       const InputInfoList &Inputs,
6762198893Srdivacky                                       const ArgList &Args,
6763198893Srdivacky                                       const char *LinkingOutput) const {
6764193326Sed  ArgStringList CmdArgs;
6765193326Sed
6766193326Sed  // When building 32-bit code on DragonFly/pc64, we have to explicitly
6767193326Sed  // instruct as in the base system to assemble 32-bit code.
6768243830Sdim  if (getToolChain().getArch() == llvm::Triple::x86)
6769193326Sed    CmdArgs.push_back("--32");
6770193326Sed
6771193326Sed  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
6772193326Sed                       options::OPT_Xassembler);
6773193326Sed
6774193326Sed  CmdArgs.push_back("-o");
6775212904Sdim  CmdArgs.push_back(Output.getFilename());
6776193326Sed
6777193326Sed  for (InputInfoList::const_iterator
6778193326Sed         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6779193326Sed    const InputInfo &II = *it;
6780212904Sdim    CmdArgs.push_back(II.getFilename());
6781193326Sed  }
6782193326Sed
6783193326Sed  const char *Exec =
6784210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("as"));
6785212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6786193326Sed}
6787193326Sed
6788193326Sedvoid dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
6789212904Sdim                                   const InputInfo &Output,
6790212904Sdim                                   const InputInfoList &Inputs,
6791212904Sdim                                   const ArgList &Args,
6792212904Sdim                                   const char *LinkingOutput) const {
6793251662Sdim  bool UseGCC47 = false;
6794201361Srdivacky  const Driver &D = getToolChain().getDriver();
6795193326Sed  ArgStringList CmdArgs;
6796193326Sed
6797251662Sdim  if (llvm::sys::fs::exists("/usr/lib/gcc47", UseGCC47))
6798251662Sdim    UseGCC47 = false;
6799251662Sdim
6800221345Sdim  if (!D.SysRoot.empty())
6801221345Sdim    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
6802221345Sdim
6803251662Sdim  CmdArgs.push_back("--eh-frame-hdr");
6804193326Sed  if (Args.hasArg(options::OPT_static)) {
6805193326Sed    CmdArgs.push_back("-Bstatic");
6806193326Sed  } else {
6807251662Sdim    if (Args.hasArg(options::OPT_rdynamic))
6808251662Sdim      CmdArgs.push_back("-export-dynamic");
6809193326Sed    if (Args.hasArg(options::OPT_shared))
6810193326Sed      CmdArgs.push_back("-Bshareable");
6811193326Sed    else {
6812193326Sed      CmdArgs.push_back("-dynamic-linker");
6813193326Sed      CmdArgs.push_back("/usr/libexec/ld-elf.so.2");
6814193326Sed    }
6815251662Sdim    CmdArgs.push_back("--hash-style=both");
6816193326Sed  }
6817193326Sed
6818193326Sed  // When building 32-bit code on DragonFly/pc64, we have to explicitly
6819193326Sed  // instruct ld in the base system to link 32-bit code.
6820243830Sdim  if (getToolChain().getArch() == llvm::Triple::x86) {
6821193326Sed    CmdArgs.push_back("-m");
6822193326Sed    CmdArgs.push_back("elf_i386");
6823193326Sed  }
6824193326Sed
6825212904Sdim  if (Output.isFilename()) {
6826193326Sed    CmdArgs.push_back("-o");
6827193326Sed    CmdArgs.push_back(Output.getFilename());
6828193326Sed  } else {
6829193326Sed    assert(Output.isNothing() && "Invalid output.");
6830193326Sed  }
6831193326Sed
6832193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6833193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
6834193326Sed    if (!Args.hasArg(options::OPT_shared)) {
6835251662Sdim      if (Args.hasArg(options::OPT_pg))
6836251662Sdim        CmdArgs.push_back(Args.MakeArgString(
6837251662Sdim                                getToolChain().GetFilePath("gcrt1.o")));
6838251662Sdim      else {
6839251662Sdim        if (Args.hasArg(options::OPT_pie))
6840251662Sdim          CmdArgs.push_back(Args.MakeArgString(
6841251662Sdim                                  getToolChain().GetFilePath("Scrt1.o")));
6842251662Sdim        else
6843251662Sdim          CmdArgs.push_back(Args.MakeArgString(
6844251662Sdim                                  getToolChain().GetFilePath("crt1.o")));
6845251662Sdim      }
6846193326Sed    }
6847251662Sdim    CmdArgs.push_back(Args.MakeArgString(
6848251662Sdim                            getToolChain().GetFilePath("crti.o")));
6849251662Sdim    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
6850251662Sdim      CmdArgs.push_back(Args.MakeArgString(
6851251662Sdim                              getToolChain().GetFilePath("crtbeginS.o")));
6852251662Sdim    else
6853251662Sdim      CmdArgs.push_back(Args.MakeArgString(
6854251662Sdim                              getToolChain().GetFilePath("crtbegin.o")));
6855193326Sed  }
6856193326Sed
6857193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_L);
6858193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
6859193326Sed  Args.AddAllArgs(CmdArgs, options::OPT_e);
6860193326Sed
6861218893Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
6862193326Sed
6863193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6864193326Sed      !Args.hasArg(options::OPT_nodefaultlibs)) {
6865193326Sed    // FIXME: GCC passes on -lgcc, -lgcc_pic and a whole lot of
6866193326Sed    //         rpaths
6867251662Sdim    if (UseGCC47)
6868251662Sdim      CmdArgs.push_back("-L/usr/lib/gcc47");
6869251662Sdim    else
6870251662Sdim      CmdArgs.push_back("-L/usr/lib/gcc44");
6871193326Sed
6872193326Sed    if (!Args.hasArg(options::OPT_static)) {
6873251662Sdim      if (UseGCC47) {
6874251662Sdim        CmdArgs.push_back("-rpath");
6875251662Sdim        CmdArgs.push_back("/usr/lib/gcc47");
6876251662Sdim      } else {
6877251662Sdim        CmdArgs.push_back("-rpath");
6878251662Sdim        CmdArgs.push_back("/usr/lib/gcc44");
6879251662Sdim      }
6880193326Sed    }
6881193326Sed
6882263508Sdim    if (D.CCCIsCXX()) {
6883218893Sdim      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
6884212904Sdim      CmdArgs.push_back("-lm");
6885212904Sdim    }
6886212904Sdim
6887193326Sed    if (Args.hasArg(options::OPT_pthread))
6888198893Srdivacky      CmdArgs.push_back("-lpthread");
6889193326Sed
6890193326Sed    if (!Args.hasArg(options::OPT_nolibc)) {
6891193326Sed      CmdArgs.push_back("-lc");
6892193326Sed    }
6893193326Sed
6894251662Sdim    if (UseGCC47) {
6895251662Sdim      if (Args.hasArg(options::OPT_static) ||
6896251662Sdim          Args.hasArg(options::OPT_static_libgcc)) {
6897251662Sdim        CmdArgs.push_back("-lgcc");
6898251662Sdim        CmdArgs.push_back("-lgcc_eh");
6899251662Sdim      } else {
6900251662Sdim        if (Args.hasArg(options::OPT_shared_libgcc)) {
6901251662Sdim          CmdArgs.push_back("-lgcc_pic");
6902251662Sdim          if (!Args.hasArg(options::OPT_shared))
6903251662Sdim            CmdArgs.push_back("-lgcc");
6904251662Sdim        } else {
6905251662Sdim          CmdArgs.push_back("-lgcc");
6906251662Sdim          CmdArgs.push_back("--as-needed");
6907251662Sdim          CmdArgs.push_back("-lgcc_pic");
6908251662Sdim          CmdArgs.push_back("--no-as-needed");
6909251662Sdim        }
6910251662Sdim      }
6911193326Sed    } else {
6912251662Sdim      if (Args.hasArg(options::OPT_shared)) {
6913251662Sdim        CmdArgs.push_back("-lgcc_pic");
6914251662Sdim      } else {
6915251662Sdim        CmdArgs.push_back("-lgcc");
6916251662Sdim      }
6917193326Sed    }
6918193326Sed  }
6919193326Sed
6920193326Sed  if (!Args.hasArg(options::OPT_nostdlib) &&
6921193326Sed      !Args.hasArg(options::OPT_nostartfiles)) {
6922251662Sdim    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
6923210299Sed      CmdArgs.push_back(Args.MakeArgString(
6924251662Sdim                              getToolChain().GetFilePath("crtendS.o")));
6925193326Sed    else
6926210299Sed      CmdArgs.push_back(Args.MakeArgString(
6927251662Sdim                              getToolChain().GetFilePath("crtend.o")));
6928210299Sed    CmdArgs.push_back(Args.MakeArgString(
6929251662Sdim                            getToolChain().GetFilePath("crtn.o")));
6930193326Sed  }
6931193326Sed
6932224145Sdim  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
6933223017Sdim
6934193326Sed  const char *Exec =
6935210299Sed    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
6936212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
6937193326Sed}
6938212904Sdim
6939212904Sdimvoid visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
6940212904Sdim                                      const InputInfo &Output,
6941212904Sdim                                      const InputInfoList &Inputs,
6942212904Sdim                                      const ArgList &Args,
6943212904Sdim                                      const char *LinkingOutput) const {
6944212904Sdim  ArgStringList CmdArgs;
6945212904Sdim
6946212904Sdim  if (Output.isFilename()) {
6947218893Sdim    CmdArgs.push_back(Args.MakeArgString(std::string("-out:") +
6948218893Sdim                                         Output.getFilename()));
6949212904Sdim  } else {
6950212904Sdim    assert(Output.isNothing() && "Invalid output.");
6951212904Sdim  }
6952212904Sdim
6953212904Sdim  if (!Args.hasArg(options::OPT_nostdlib) &&
6954263508Sdim      !Args.hasArg(options::OPT_nostartfiles) &&
6955263508Sdim      !C.getDriver().IsCLMode()) {
6956212904Sdim    CmdArgs.push_back("-defaultlib:libcmt");
6957212904Sdim  }
6958212904Sdim
6959212904Sdim  CmdArgs.push_back("-nologo");
6960212904Sdim
6961263508Sdim  bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd);
6962263508Sdim
6963263508Sdim  if (DLL) {
6964263508Sdim    CmdArgs.push_back(Args.MakeArgString("-dll"));
6965263508Sdim
6966263508Sdim    SmallString<128> ImplibName(Output.getFilename());
6967263508Sdim    llvm::sys::path::replace_extension(ImplibName, "lib");
6968263508Sdim    CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") +
6969263508Sdim                                         ImplibName.str()));
6970263508Sdim  }
6971263508Sdim
6972263508Sdim  if (getToolChain().getSanitizerArgs().needsAsanRt()) {
6973263508Sdim    CmdArgs.push_back(Args.MakeArgString("-debug"));
6974263508Sdim    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
6975263508Sdim    SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir);
6976263508Sdim    llvm::sys::path::append(LibSanitizer, "lib", "windows");
6977263508Sdim    if (DLL) {
6978263508Sdim      llvm::sys::path::append(LibSanitizer, "clang_rt.asan_dll_thunk-i386.lib");
6979263508Sdim    } else {
6980263508Sdim      llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386.lib");
6981263508Sdim    }
6982263508Sdim    // FIXME: Handle 64-bit.
6983263508Sdim    CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
6984263508Sdim  }
6985263508Sdim
6986239462Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_l);
6987263508Sdim  Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
6988212904Sdim
6989239462Sdim  // Add filenames immediately.
6990239462Sdim  for (InputInfoList::const_iterator
6991239462Sdim       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
6992239462Sdim    if (it->isFilename())
6993239462Sdim      CmdArgs.push_back(it->getFilename());
6994263508Sdim    else
6995263508Sdim      it->getInputArg().renderAsInput(Args, CmdArgs);
6996239462Sdim  }
6997239462Sdim
6998212904Sdim  const char *Exec =
6999218893Sdim    Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
7000212904Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
7001212904Sdim}
7002263508Sdim
7003263508Sdimvoid visualstudio::Compile::ConstructJob(Compilation &C, const JobAction &JA,
7004263508Sdim                                         const InputInfo &Output,
7005263508Sdim                                         const InputInfoList &Inputs,
7006263508Sdim                                         const ArgList &Args,
7007263508Sdim                                         const char *LinkingOutput) const {
7008263508Sdim  C.addCommand(GetCommand(C, JA, Output, Inputs, Args, LinkingOutput));
7009263508Sdim}
7010263508Sdim
7011263508Sdim// Try to find FallbackName on PATH that is not identical to ClangProgramPath.
7012263508Sdim// If one cannot be found, return FallbackName.
7013263508Sdim// We do this special search to prevent clang-cl from falling back onto itself
7014263508Sdim// if it's available as cl.exe on the path.
7015263508Sdimstatic std::string FindFallback(const char *FallbackName,
7016263508Sdim                                const char *ClangProgramPath) {
7017263508Sdim  llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
7018263508Sdim  if (!OptPath.hasValue())
7019263508Sdim    return FallbackName;
7020263508Sdim
7021263508Sdim#ifdef LLVM_ON_WIN32
7022263508Sdim  const StringRef PathSeparators = ";";
7023263508Sdim#else
7024263508Sdim  const StringRef PathSeparators = ":";
7025263508Sdim#endif
7026263508Sdim
7027263508Sdim  SmallVector<StringRef, 8> PathSegments;
7028263508Sdim  llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators);
7029263508Sdim
7030263508Sdim  for (size_t i = 0, e = PathSegments.size(); i != e; ++i) {
7031263508Sdim    const StringRef &PathSegment = PathSegments[i];
7032263508Sdim    if (PathSegment.empty())
7033263508Sdim      continue;
7034263508Sdim
7035263508Sdim    SmallString<128> FilePath(PathSegment);
7036263508Sdim    llvm::sys::path::append(FilePath, FallbackName);
7037263508Sdim    if (llvm::sys::fs::can_execute(Twine(FilePath)) &&
7038263508Sdim        !llvm::sys::fs::equivalent(Twine(FilePath), ClangProgramPath))
7039263508Sdim      return FilePath.str();
7040263508Sdim  }
7041263508Sdim
7042263508Sdim  return FallbackName;
7043263508Sdim}
7044263508Sdim
7045263508SdimCommand *visualstudio::Compile::GetCommand(Compilation &C, const JobAction &JA,
7046263508Sdim                                           const InputInfo &Output,
7047263508Sdim                                           const InputInfoList &Inputs,
7048263508Sdim                                           const ArgList &Args,
7049263508Sdim                                           const char *LinkingOutput) const {
7050263508Sdim  ArgStringList CmdArgs;
7051263508Sdim  CmdArgs.push_back("/nologo");
7052263508Sdim  CmdArgs.push_back("/c"); // Compile only.
7053263508Sdim  CmdArgs.push_back("/W0"); // No warnings.
7054263508Sdim
7055263508Sdim  // The goal is to be able to invoke this tool correctly based on
7056263508Sdim  // any flag accepted by clang-cl.
7057263508Sdim
7058263508Sdim  // These are spelled the same way in clang and cl.exe,.
7059263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
7060263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT_I);
7061263508Sdim
7062263508Sdim  // Optimization level.
7063263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_O, options::OPT_O0)) {
7064263508Sdim    if (A->getOption().getID() == options::OPT_O0) {
7065263508Sdim      CmdArgs.push_back("/Od");
7066263508Sdim    } else {
7067263508Sdim      StringRef OptLevel = A->getValue();
7068263508Sdim      if (OptLevel == "1" || OptLevel == "2" || OptLevel == "s")
7069263508Sdim        A->render(Args, CmdArgs);
7070263508Sdim      else if (OptLevel == "3")
7071263508Sdim        CmdArgs.push_back("/Ox");
7072263508Sdim    }
7073263508Sdim  }
7074263508Sdim
7075263508Sdim  // Flags for which clang-cl have an alias.
7076263508Sdim  // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
7077263508Sdim
7078263508Sdim  if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti))
7079263508Sdim    CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR"
7080263508Sdim                                                                   : "/GR-");
7081263508Sdim  if (Args.hasArg(options::OPT_fsyntax_only))
7082263508Sdim    CmdArgs.push_back("/Zs");
7083263508Sdim
7084263508Sdim  std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include);
7085263508Sdim  for (size_t I = 0, E = Includes.size(); I != E; ++I)
7086263508Sdim    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I]));
7087263508Sdim
7088263508Sdim  // Flags that can simply be passed through.
7089263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
7090263508Sdim  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
7091263508Sdim
7092263508Sdim  // The order of these flags is relevant, so pick the last one.
7093263508Sdim  if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
7094263508Sdim                               options::OPT__SLASH_MT, options::OPT__SLASH_MTd))
7095263508Sdim    A->render(Args, CmdArgs);
7096263508Sdim
7097263508Sdim
7098263508Sdim  // Input filename.
7099263508Sdim  assert(Inputs.size() == 1);
7100263508Sdim  const InputInfo &II = Inputs[0];
7101263508Sdim  assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX);
7102263508Sdim  CmdArgs.push_back(II.getType() == types::TY_C ? "/Tc" : "/Tp");
7103263508Sdim  if (II.isFilename())
7104263508Sdim    CmdArgs.push_back(II.getFilename());
7105263508Sdim  else
7106263508Sdim    II.getInputArg().renderAsInput(Args, CmdArgs);
7107263508Sdim
7108263508Sdim  // Output filename.
7109263508Sdim  assert(Output.getType() == types::TY_Object);
7110263508Sdim  const char *Fo = Args.MakeArgString(std::string("/Fo") +
7111263508Sdim                                      Output.getFilename());
7112263508Sdim  CmdArgs.push_back(Fo);
7113263508Sdim
7114263508Sdim  const Driver &D = getToolChain().getDriver();
7115263508Sdim  std::string Exec = FindFallback("cl.exe", D.getClangProgramPath());
7116263508Sdim
7117263508Sdim  return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs);
7118263508Sdim}
7119263508Sdim
7120263508Sdim
7121263508Sdim/// XCore Tools
7122263508Sdim// We pass assemble and link construction to the xcc tool.
7123263508Sdim
7124263508Sdimvoid XCore::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
7125263508Sdim                                       const InputInfo &Output,
7126263508Sdim                                       const InputInfoList &Inputs,
7127263508Sdim                                       const ArgList &Args,
7128263508Sdim                                       const char *LinkingOutput) const {
7129263508Sdim  ArgStringList CmdArgs;
7130263508Sdim
7131263508Sdim  CmdArgs.push_back("-o");
7132263508Sdim  CmdArgs.push_back(Output.getFilename());
7133263508Sdim
7134263508Sdim  CmdArgs.push_back("-c");
7135263508Sdim
7136263508Sdim  if (Args.hasArg(options::OPT_g_Group)) {
7137263508Sdim    CmdArgs.push_back("-g");
7138263508Sdim  }
7139263508Sdim
7140263508Sdim  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
7141263508Sdim                       options::OPT_Xassembler);
7142263508Sdim
7143263508Sdim  for (InputInfoList::const_iterator
7144263508Sdim       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
7145263508Sdim    const InputInfo &II = *it;
7146263508Sdim    CmdArgs.push_back(II.getFilename());
7147263508Sdim  }
7148263508Sdim
7149263508Sdim  const char *Exec =
7150263508Sdim    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
7151263508Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
7152263508Sdim}
7153263508Sdim
7154263508Sdimvoid XCore::Link::ConstructJob(Compilation &C, const JobAction &JA,
7155263508Sdim                                   const InputInfo &Output,
7156263508Sdim                                   const InputInfoList &Inputs,
7157263508Sdim                                   const ArgList &Args,
7158263508Sdim                                   const char *LinkingOutput) const {
7159263508Sdim  ArgStringList CmdArgs;
7160263508Sdim
7161263508Sdim  if (Output.isFilename()) {
7162263508Sdim    CmdArgs.push_back("-o");
7163263508Sdim    CmdArgs.push_back(Output.getFilename());
7164263508Sdim  } else {
7165263508Sdim    assert(Output.isNothing() && "Invalid output.");
7166263508Sdim  }
7167263508Sdim
7168263508Sdim  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
7169263508Sdim
7170263508Sdim  const char *Exec =
7171263508Sdim    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
7172263508Sdim  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
7173263508Sdim}
7174